diff --git a/404.html b/404.html index e91402131d..2153676084 100644 --- a/404.html +++ b/404.html @@ -5,8 +5,8 @@ Page Not Found | OSISM – Sovereign Cloud Infrastructure - - + +
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.

diff --git a/about-us/index.html b/about-us/index.html index 9878adf1fe..c5980abd99 100644 --- a/about-us/index.html +++ b/about-us/index.html @@ -5,8 +5,8 @@ About Us | OSISM – Sovereign Cloud Infrastructure - - + +
Skip to main content

About Us

diff --git a/assets/js/0058b4c6.31f85ed2.js b/assets/js/0058b4c6.31f85ed2.js deleted file mode 100644 index fb22626b82..0000000000 --- a/assets/js/0058b4c6.31f85ed2.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkosism=self.webpackChunkosism||[]).push([[4088],{6462:e=>{e.exports=JSON.parse('{"version":{"pluginId":"default","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"tutorialSidebar":[{"type":"link","label":"Getting started","href":"/docs/","docId":"index","unlisted":false},{"type":"category","label":"Guides","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Concept Guide","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Components","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Ceph","href":"/docs/guides/concept-guide/components/ceph","docId":"guides/concept-guide/components/ceph","unlisted":false},{"type":"link","label":"Cluster API","href":"/docs/guides/concept-guide/components/clusterapi","docId":"guides/concept-guide/components/clusterapi","unlisted":false},{"type":"link","label":"Gardener","href":"/docs/guides/concept-guide/components/gardener","docId":"guides/concept-guide/components/gardener","unlisted":false},{"type":"link","label":"Ironic","href":"/docs/guides/concept-guide/components/ironic","docId":"guides/concept-guide/components/ironic","unlisted":false},{"type":"link","label":"K3S","href":"/docs/guides/concept-guide/components/k3s","docId":"guides/concept-guide/components/k3s","unlisted":false},{"type":"link","label":"Keycloak","href":"/docs/guides/concept-guide/components/keycloak","docId":"guides/concept-guide/components/keycloak","unlisted":false},{"type":"link","label":"Netdata","href":"/docs/guides/concept-guide/components/netdata","docId":"guides/concept-guide/components/netdata","unlisted":false},{"type":"link","label":"OpenStack","href":"/docs/guides/concept-guide/components/openstack","docId":"guides/concept-guide/components/openstack","unlisted":false},{"type":"link","label":"Prometheus & Grafana","href":"/docs/guides/concept-guide/components/prometheus","docId":"guides/concept-guide/components/prometheus","unlisted":false},{"type":"link","label":"Proxmox VE","href":"/docs/guides/concept-guide/components/proxmox","docId":"guides/concept-guide/components/proxmox","unlisted":false},{"type":"link","label":"SONiC & OVN","href":"/docs/guides/concept-guide/components/sonic","docId":"guides/concept-guide/components/sonic","unlisted":false},{"type":"link","label":"Teleport","href":"/docs/guides/concept-guide/components/teleport","docId":"guides/concept-guide/components/teleport","unlisted":false}],"href":"/docs/guides/concept-guide/components/"},{"type":"link","label":"Layers in a cluster","href":"/docs/guides/concept-guide/layers","docId":"guides/concept-guide/layers","unlisted":false},{"type":"link","label":"Nodes in a cluster","href":"/docs/guides/concept-guide/nodes","docId":"guides/concept-guide/nodes","unlisted":false},{"type":"link","label":"Cluster design","href":"/docs/guides/concept-guide/design","docId":"guides/concept-guide/design","unlisted":false},{"type":"link","label":"Use cases","href":"/docs/guides/concept-guide/use-cases","docId":"guides/concept-guide/use-cases","unlisted":false},{"type":"link","label":"Hardware Bill of Materials","href":"/docs/guides/concept-guide/hardware-bom","docId":"guides/concept-guide/hardware-bom","unlisted":false}],"href":"/docs/guides/concept-guide/"},{"type":"category","label":"Deploy Guide","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Seed","href":"/docs/guides/deploy-guide/seed","docId":"guides/deploy-guide/seed","unlisted":false},{"type":"link","label":"Manager","href":"/docs/guides/deploy-guide/manager","docId":"guides/deploy-guide/manager","unlisted":false},{"type":"link","label":"Provisioning","href":"/docs/guides/deploy-guide/provisioning","docId":"guides/deploy-guide/provisioning","unlisted":false},{"type":"link","label":"Bootstrap","href":"/docs/guides/deploy-guide/bootstrap","docId":"guides/deploy-guide/bootstrap","unlisted":false},{"type":"category","label":"Services","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Infrastructure","href":"/docs/guides/deploy-guide/services/infrastructure","docId":"guides/deploy-guide/services/infrastructure","unlisted":false},{"type":"link","label":"Kubernetes","href":"/docs/guides/deploy-guide/services/kubernetes","docId":"guides/deploy-guide/services/kubernetes","unlisted":false},{"type":"link","label":"Network","href":"/docs/guides/deploy-guide/services/network","docId":"guides/deploy-guide/services/network","unlisted":false},{"type":"link","label":"Logging & Monitoring","href":"/docs/guides/deploy-guide/services/logging-monitoring","docId":"guides/deploy-guide/services/logging-monitoring","unlisted":false},{"type":"link","label":"Ceph","href":"/docs/guides/deploy-guide/services/ceph","docId":"guides/deploy-guide/services/ceph","unlisted":false},{"type":"link","label":"OpenStack","href":"/docs/guides/deploy-guide/services/openstack","docId":"guides/deploy-guide/services/openstack","unlisted":false}],"href":"/docs/guides/deploy-guide/services/"},{"type":"category","label":"Examples","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Cloud in a Box","href":"/docs/guides/deploy-guide/examples/cloud-in-a-box","docId":"guides/deploy-guide/examples/cloud-in-a-box","unlisted":false},{"type":"link","label":"Testbed","href":"/docs/guides/deploy-guide/examples/testbed","docId":"guides/deploy-guide/examples/testbed","unlisted":false}],"href":"/docs/guides/deploy-guide/examples/"}],"href":"/docs/guides/deploy-guide/"},{"type":"category","label":"Upgrade Guide","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Manager","href":"/docs/guides/upgrade-guide/manager","docId":"guides/upgrade-guide/manager","unlisted":false},{"type":"link","label":"Network","href":"/docs/guides/upgrade-guide/network","docId":"guides/upgrade-guide/network","unlisted":false},{"type":"link","label":"Ceph","href":"/docs/guides/upgrade-guide/ceph","docId":"guides/upgrade-guide/ceph","unlisted":false},{"type":"link","label":"Docker","href":"/docs/guides/upgrade-guide/docker","docId":"guides/upgrade-guide/docker","unlisted":false},{"type":"link","label":"Infrastructure","href":"/docs/guides/upgrade-guide/infrastructure","docId":"guides/upgrade-guide/infrastructure","unlisted":false},{"type":"link","label":"Logging & Monitoring","href":"/docs/guides/upgrade-guide/logging-monitoring","docId":"guides/upgrade-guide/logging-monitoring","unlisted":false},{"type":"link","label":"OpenStack","href":"/docs/guides/upgrade-guide/openstack","docId":"guides/upgrade-guide/openstack","unlisted":false}],"href":"/docs/guides/upgrade-guide/"},{"type":"category","label":"Configuration Guide","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Configuration repository","href":"/docs/guides/configuration-guide/configuration-repository","docId":"guides/configuration-guide/configuration-repository","unlisted":false},{"type":"link","label":"Inventory","href":"/docs/guides/configuration-guide/inventory","docId":"guides/configuration-guide/inventory","unlisted":false},{"type":"link","label":"Manager","href":"/docs/guides/configuration-guide/manager","docId":"guides/configuration-guide/manager","unlisted":false},{"type":"link","label":"Network","href":"/docs/guides/configuration-guide/network","docId":"guides/configuration-guide/network","unlisted":false},{"type":"link","label":"Proxy","href":"/docs/guides/configuration-guide/proxy","docId":"guides/configuration-guide/proxy","unlisted":false},{"type":"link","label":"Loadbalancer","href":"/docs/guides/configuration-guide/loadbalancer","docId":"guides/configuration-guide/loadbalancer","unlisted":false},{"type":"link","label":"Ceph","href":"/docs/guides/configuration-guide/ceph","docId":"guides/configuration-guide/ceph","unlisted":false},{"type":"category","label":"OpenStack","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Aodh","href":"/docs/guides/configuration-guide/openstack/aodh","docId":"guides/configuration-guide/openstack/aodh","unlisted":false},{"type":"link","label":"Barbican","href":"/docs/guides/configuration-guide/openstack/barbican","docId":"guides/configuration-guide/openstack/barbican","unlisted":false},{"type":"link","label":"Ceilometer","href":"/docs/guides/configuration-guide/openstack/ceilometer","docId":"guides/configuration-guide/openstack/ceilometer","unlisted":false},{"type":"link","label":"Cinder","href":"/docs/guides/configuration-guide/openstack/cinder","docId":"guides/configuration-guide/openstack/cinder","unlisted":false},{"type":"link","label":"Designate","href":"/docs/guides/configuration-guide/openstack/designate","docId":"guides/configuration-guide/openstack/designate","unlisted":false},{"type":"link","label":"Glance","href":"/docs/guides/configuration-guide/openstack/glance","docId":"guides/configuration-guide/openstack/glance","unlisted":false},{"type":"link","label":"Heat","href":"/docs/guides/configuration-guide/openstack/heat","docId":"guides/configuration-guide/openstack/heat","unlisted":false},{"type":"link","label":"Horizon","href":"/docs/guides/configuration-guide/openstack/horizon","docId":"guides/configuration-guide/openstack/horizon","unlisted":false},{"type":"link","label":"Ironic","href":"/docs/guides/configuration-guide/openstack/ironic","docId":"guides/configuration-guide/openstack/ironic","unlisted":false},{"type":"link","label":"Keystone","href":"/docs/guides/configuration-guide/openstack/keystone","docId":"guides/configuration-guide/openstack/keystone","unlisted":false},{"type":"link","label":"Magnum","href":"/docs/guides/configuration-guide/openstack/magnum","docId":"guides/configuration-guide/openstack/magnum","unlisted":false},{"type":"link","label":"Manila","href":"/docs/guides/configuration-guide/openstack/manila","docId":"guides/configuration-guide/openstack/manila","unlisted":false},{"type":"link","label":"Neutron","href":"/docs/guides/configuration-guide/openstack/neutron","docId":"guides/configuration-guide/openstack/neutron","unlisted":false},{"type":"link","label":"Nova","href":"/docs/guides/configuration-guide/openstack/nova","docId":"guides/configuration-guide/openstack/nova","unlisted":false},{"type":"link","label":"Octavia","href":"/docs/guides/configuration-guide/openstack/octavia","docId":"guides/configuration-guide/openstack/octavia","unlisted":false},{"type":"link","label":"Placement","href":"/docs/guides/configuration-guide/openstack/placement","docId":"guides/configuration-guide/openstack/placement","unlisted":false},{"type":"link","label":"Skyline","href":"/docs/guides/configuration-guide/openstack/skyline","docId":"guides/configuration-guide/openstack/skyline","unlisted":false}],"href":"/docs/guides/configuration-guide/openstack/"},{"type":"category","label":"Commons","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Certificates","href":"/docs/guides/configuration-guide/commons/certificates","docId":"guides/configuration-guide/commons/certificates","unlisted":false},{"type":"link","label":"Packages","href":"/docs/guides/configuration-guide/commons/packages","docId":"guides/configuration-guide/commons/packages","unlisted":false},{"type":"link","label":"Resolvconf","href":"/docs/guides/configuration-guide/commons/resolvconf","docId":"guides/configuration-guide/commons/resolvconf","unlisted":false},{"type":"link","label":"Services","href":"/docs/guides/configuration-guide/commons/services","docId":"guides/configuration-guide/commons/services","unlisted":false},{"type":"link","label":"SSH Config","href":"/docs/guides/configuration-guide/commons/sshconfig","docId":"guides/configuration-guide/commons/sshconfig","unlisted":false},{"type":"link","label":"Sysctl","href":"/docs/guides/configuration-guide/commons/sysctl","docId":"guides/configuration-guide/commons/sysctl","unlisted":false},{"type":"link","label":"Timezone","href":"/docs/guides/configuration-guide/commons/timezone","docId":"guides/configuration-guide/commons/timezone","unlisted":false},{"type":"link","label":"User","href":"/docs/guides/configuration-guide/commons/user","docId":"guides/configuration-guide/commons/user","unlisted":false}],"href":"/docs/guides/configuration-guide/commons/"},{"type":"category","label":"Services","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Chrony","href":"/docs/guides/configuration-guide/services/chrony","docId":"guides/configuration-guide/services/chrony","unlisted":false},{"type":"link","label":"Docker","href":"/docs/guides/configuration-guide/services/docker","docId":"guides/configuration-guide/services/docker","unlisted":false},{"type":"link","label":"Tuned","href":"/docs/guides/configuration-guide/services/tuned","docId":"guides/configuration-guide/services/tuned","unlisted":false}],"href":"/docs/guides/configuration-guide/services/"},{"type":"link","label":"Validations","href":"/docs/guides/configuration-guide/validations/","docId":"guides/configuration-guide/validations/index","unlisted":false}],"href":"/docs/guides/configuration-guide/"},{"type":"category","label":"Operations Guide","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Manager","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Apply","href":"/docs/guides/operations-guide/manager/apply","docId":"guides/operations-guide/manager/apply","unlisted":false},{"type":"link","label":"Console","href":"/docs/guides/operations-guide/manager/console","docId":"guides/operations-guide/manager/console","unlisted":false},{"type":"link","label":"Get","href":"/docs/guides/operations-guide/manager/get","docId":"guides/operations-guide/manager/get","unlisted":false},{"type":"link","label":"Logging","href":"/docs/guides/operations-guide/manager/log","docId":"guides/operations-guide/manager/log","unlisted":false},{"type":"link","label":"Task","href":"/docs/guides/operations-guide/manager/task","docId":"guides/operations-guide/manager/task","unlisted":false}],"href":"/docs/guides/operations-guide/manager/"},{"type":"link","label":"Ceph","href":"/docs/guides/operations-guide/ceph","docId":"guides/operations-guide/ceph","unlisted":false},{"type":"link","label":"Infrastructure","href":"/docs/guides/operations-guide/infrastructure","docId":"guides/operations-guide/infrastructure","unlisted":false},{"type":"link","label":"Network","href":"/docs/guides/operations-guide/network","docId":"guides/operations-guide/network","unlisted":false},{"type":"category","label":"OpenStack","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Tools","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Image Manager","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Automated updates","href":"/docs/guides/operations-guide/openstack/tools/image-manager/update","docId":"guides/operations-guide/openstack/tools/image-manager/update","unlisted":false}],"href":"/docs/guides/operations-guide/openstack/tools/image-manager/"},{"type":"link","label":"Flavor Manager","href":"/docs/guides/operations-guide/openstack/tools/flavor-manager","docId":"guides/operations-guide/openstack/tools/flavor-manager","unlisted":false},{"type":"link","label":"Resource Manager","href":"/docs/guides/operations-guide/openstack/tools/resource-manager","docId":"guides/operations-guide/openstack/tools/resource-manager","unlisted":false},{"type":"link","label":"Project Manager","href":"/docs/guides/operations-guide/openstack/tools/project-manager","docId":"guides/operations-guide/openstack/tools/project-manager","unlisted":false},{"type":"link","label":"Sandbox Manager","href":"/docs/guides/operations-guide/openstack/tools/sandbox-manager","docId":"guides/operations-guide/openstack/tools/sandbox-manager","unlisted":false},{"type":"link","label":"Simple Stress","href":"/docs/guides/operations-guide/openstack/tools/simple-stress","docId":"guides/operations-guide/openstack/tools/simple-stress","unlisted":false},{"type":"link","label":"OpenStack Health Monitor","href":"/docs/guides/operations-guide/openstack/tools/openstack-health-monitor","docId":"guides/operations-guide/openstack/tools/openstack-health-monitor","unlisted":false}],"href":"/docs/guides/operations-guide/openstack/tools/"},{"type":"link","label":"Cinder","href":"/docs/guides/operations-guide/openstack/cinder","docId":"guides/operations-guide/openstack/cinder","unlisted":false},{"type":"link","label":"Keystone","href":"/docs/guides/operations-guide/openstack/keystone","docId":"guides/operations-guide/openstack/keystone","unlisted":false},{"type":"link","label":"Neutron","href":"/docs/guides/operations-guide/openstack/neutron","docId":"guides/operations-guide/openstack/neutron","unlisted":false},{"type":"link","label":"Nova","href":"/docs/guides/operations-guide/openstack/nova","docId":"guides/operations-guide/openstack/nova","unlisted":false},{"type":"link","label":"Octavia","href":"/docs/guides/operations-guide/openstack/octavia","docId":"guides/operations-guide/openstack/octavia","unlisted":false}],"href":"/docs/guides/operations-guide/openstack/"}],"href":"/docs/guides/operations-guide/"},{"type":"category","label":"Troubleshooting Guide","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Manager","href":"/docs/guides/troubleshooting-guide/manager","docId":"guides/troubleshooting-guide/manager","unlisted":false},{"type":"link","label":"OpenStack","href":"/docs/guides/troubleshooting-guide/openstack","docId":"guides/troubleshooting-guide/openstack","unlisted":false},{"type":"link","label":"Ceph","href":"/docs/guides/troubleshooting-guide/ceph","docId":"guides/troubleshooting-guide/ceph","unlisted":false}],"href":"/docs/guides/troubleshooting-guide/"},{"type":"category","label":"User Guide","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Migrate from VMware ESXi to OpenStack","href":"/docs/guides/user-guide/migration-vmware-esix","docId":"guides/user-guide/migration-vmware-esix","unlisted":false},{"type":"category","label":"OpenStack","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Client","href":"/docs/guides/user-guide/openstack/openstackclient","docId":"guides/user-guide/openstack/openstackclient","unlisted":false},{"type":"link","label":"Security groups","href":"/docs/guides/user-guide/openstack/security-groups","docId":"guides/user-guide/openstack/security-groups","unlisted":false},{"type":"link","label":"User Data Backups","href":"/docs/guides/user-guide/openstack/user-data-backups","docId":"guides/user-guide/openstack/user-data-backups","unlisted":false}],"href":"/docs/guides/user-guide/openstack/"}],"href":"/docs/guides/user-guide/"},{"type":"category","label":"Other Guides","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Cloud in a Box Guide","href":"/docs/guides/other-guides/cloud-in-a-box","docId":"guides/other-guides/cloud-in-a-box","unlisted":false},{"type":"link","label":"Contributor Guide","href":"/docs/guides/other-guides/contributor-guide","docId":"guides/other-guides/contributor-guide","unlisted":false},{"type":"category","label":"Developer Guide","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Releases","href":"/docs/guides/other-guides/developer-guide/releases","docId":"guides/other-guides/developer-guide/releases","unlisted":false},{"type":"link","label":"Scripts","href":"/docs/guides/other-guides/developer-guide/scripts","docId":"guides/other-guides/developer-guide/scripts","unlisted":false},{"type":"link","label":"Zuul CI","href":"/docs/guides/other-guides/developer-guide/zuul","docId":"guides/other-guides/developer-guide/zuul","unlisted":false}],"href":"/docs/guides/other-guides/developer-guide/"},{"type":"link","label":"Style Guide","href":"/docs/guides/other-guides/style-guide","docId":"guides/other-guides/style-guide","unlisted":false},{"type":"link","label":"Testbed Guide","href":"/docs/guides/other-guides/testbed","docId":"guides/other-guides/testbed","unlisted":false}],"href":"/docs/guides/other-guides/"}],"href":"/docs/guides/"},{"type":"category","label":"References","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Command line interface reference","href":"/docs/references/cli","docId":"references/cli","unlisted":false},{"type":"link","label":"Configuration reference","href":"/docs/references/configuration","docId":"references/configuration","unlisted":false},{"type":"link","label":"Parameters reference","href":"/docs/references/parameters","docId":"references/parameters","unlisted":false}],"href":"/docs/references/"},{"type":"category","label":"Release Notes","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"OSISM 7","href":"/docs/release-notes/osism-7","docId":"release-notes/osism-7","unlisted":false}],"href":"/docs/release-notes/"},{"type":"category","label":"Appendix","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Comparisons","href":"/docs/appendix/comparisons","docId":"appendix/comparisons","unlisted":false},{"type":"link","label":"Glossary","href":"/docs/appendix/glossary","docId":"appendix/glossary","unlisted":false},{"type":"link","label":"Networks","href":"/docs/appendix/networks","docId":"appendix/networks","unlisted":false},{"type":"link","label":"Standards","href":"/docs/appendix/standards","docId":"appendix/standards","unlisted":false}],"href":"/docs/appendix/"}]},"docs":{"appendix/comparisons":{"id":"appendix/comparisons","title":"Comparisons","description":"OSISM vs. FishOS","sidebar":"tutorialSidebar"},"appendix/glossary":{"id":"appendix/glossary","title":"Glossary","description":"\ud83d\udca1 This section serves as the central glossary within OSISM. It is intended to clearly define","sidebar":"tutorialSidebar"},"appendix/index":{"id":"appendix/index","title":"Appendix","description":"","sidebar":"tutorialSidebar"},"appendix/networks":{"id":"appendix/networks","title":"Networks","description":"| Parameter | CIDR |","sidebar":"tutorialSidebar"},"appendix/standards":{"id":"appendix/standards","title":"Standards","description":"| Name | OSISM Documentation | SCS Standard Track | SCS Standard | SCS Documentation |","sidebar":"tutorialSidebar"},"guides/concept-guide/components/ceph":{"id":"guides/concept-guide/components/ceph","title":"Ceph","description":"Ceph is an Open Source software defined storage platform designed to provide highly scalable","sidebar":"tutorialSidebar"},"guides/concept-guide/components/clusterapi":{"id":"guides/concept-guide/components/clusterapi","title":"Cluster API","description":"Kubernetes as a Service (KaaS) is a cloud service model that simplifies the deployment,","sidebar":"tutorialSidebar"},"guides/concept-guide/components/gardener":{"id":"guides/concept-guide/components/gardener","title":"Gardener","description":"Kubernetes as a Service (KaaS) simplifies the deployment, management, and scaling of","sidebar":"tutorialSidebar"},"guides/concept-guide/components/index":{"id":"guides/concept-guide/components/index","title":"Components","description":"* Infrastructure as a Service (IaaS) with OpenStack","sidebar":"tutorialSidebar"},"guides/concept-guide/components/ironic":{"id":"guides/concept-guide/components/ironic","title":"Ironic","description":"OpenStack Ironic is a project that provides Baremetal as a Service (BMaaS), enabling the","sidebar":"tutorialSidebar"},"guides/concept-guide/components/k3s":{"id":"guides/concept-guide/components/k3s","title":"K3S","description":"Lifecycle Management of K3S in OSISM","sidebar":"tutorialSidebar"},"guides/concept-guide/components/keycloak":{"id":"guides/concept-guide/components/keycloak","title":"Keycloak","description":"Lifecycle Management of Keycloak in OSISM","sidebar":"tutorialSidebar"},"guides/concept-guide/components/netdata":{"id":"guides/concept-guide/components/netdata","title":"Netdata","description":"Lifecycle Management of Netdata in OSISM","sidebar":"tutorialSidebar"},"guides/concept-guide/components/openstack":{"id":"guides/concept-guide/components/openstack","title":"OpenStack","description":"Lifecycle Management of OpenStack in OSISM","sidebar":"tutorialSidebar"},"guides/concept-guide/components/prometheus":{"id":"guides/concept-guide/components/prometheus","title":"Prometheus & Grafana","description":"Lifecycle Management of Prometheus in OSISM","sidebar":"tutorialSidebar"},"guides/concept-guide/components/proxmox":{"id":"guides/concept-guide/components/proxmox","title":"Proxmox VE","description":"Proxmox Virtual Environment (Proxmox VE) is an open-source server virtualization management","sidebar":"tutorialSidebar"},"guides/concept-guide/components/sonic":{"id":"guides/concept-guide/components/sonic","title":"SONiC & OVN","description":"Lifecycle Management of SONiC in OSISM","sidebar":"tutorialSidebar"},"guides/concept-guide/components/teleport":{"id":"guides/concept-guide/components/teleport","title":"Teleport","description":"Lifecycle Management of Teleport in OSISM","sidebar":"tutorialSidebar"},"guides/concept-guide/design":{"id":"guides/concept-guide/design","title":"Cluster design","description":"Parts of this chapter are based on the OpenStack Architecture Design Guide.","sidebar":"tutorialSidebar"},"guides/concept-guide/hardware-bom":{"id":"guides/concept-guide/hardware-bom","title":"Hardware Bill of Materials","description":"The brands, models and configurations listed are examples. There is no","sidebar":"tutorialSidebar"},"guides/concept-guide/index":{"id":"guides/concept-guide/index","title":"Concept Guide","description":"Highlevel Overview","sidebar":"tutorialSidebar"},"guides/concept-guide/layers":{"id":"guides/concept-guide/layers","title":"Layers in a cluster","description":"Compute Plane","sidebar":"tutorialSidebar"},"guides/concept-guide/nodes":{"id":"guides/concept-guide/nodes","title":"Nodes in a cluster","description":"Compute Node","sidebar":"tutorialSidebar"},"guides/concept-guide/use-cases":{"id":"guides/concept-guide/use-cases","title":"Use cases","description":"Hyper-converged infrastructure (HCI)","sidebar":"tutorialSidebar"},"guides/configuration-guide/ceph":{"id":"guides/configuration-guide/ceph","title":"Ceph","description":"The official Ceph documentation is located on https://docs.ceph.com/en/latest/rados/configuration/","sidebar":"tutorialSidebar"},"guides/configuration-guide/commons/certificates":{"id":"guides/configuration-guide/commons/certificates","title":"Certificates","description":"With the osism.commons.certificates role, it is possible to add custom CA certificates","sidebar":"tutorialSidebar"},"guides/configuration-guide/commons/index":{"id":"guides/configuration-guide/commons/index","title":"Commons","description":"This section contains the documentation of the Ansible collection osism.commons.","sidebar":"tutorialSidebar"},"guides/configuration-guide/commons/packages":{"id":"guides/configuration-guide/commons/packages","title":"Packages","description":"With the osism.commons.packages role, it is possible to add packages on a node","sidebar":"tutorialSidebar"},"guides/configuration-guide/commons/resolvconf":{"id":"guides/configuration-guide/commons/resolvconf","title":"Resolvconf","description":"With the osism.commons.resolvconf role, it is possible to manage the used DNS servers on a node.","sidebar":"tutorialSidebar"},"guides/configuration-guide/commons/services":{"id":"guides/configuration-guide/commons/services","title":"Services","description":"With the osism.commons.services role, it is possible to manage services on a node","sidebar":"tutorialSidebar"},"guides/configuration-guide/commons/sshconfig":{"id":"guides/configuration-guide/commons/sshconfig","title":"SSH Config","description":"With the osism.commons.sshconfig role, it is possible to manage a SSH config","sidebar":"tutorialSidebar"},"guides/configuration-guide/commons/sysctl":{"id":"guides/configuration-guide/commons/sysctl","title":"Sysctl","description":"With the osism.commons.sysctl role, it is possible to manage the attributes of the kernel","sidebar":"tutorialSidebar"},"guides/configuration-guide/commons/timezone":{"id":"guides/configuration-guide/commons/timezone","title":"Timezone","description":"With the osism.commons.timezone role, it is possible to manage the used timezone on a node.","sidebar":"tutorialSidebar"},"guides/configuration-guide/commons/user":{"id":"guides/configuration-guide/commons/user","title":"User","description":"With the osism.commons.user role, it is possible to manage additional","sidebar":"tutorialSidebar"},"guides/configuration-guide/configuration-repository":{"id":"guides/configuration-guide/configuration-repository","title":"Configuration Repository","description":"The configuration required for an OSISM managed cluster is stored in a single Git","sidebar":"tutorialSidebar"},"guides/configuration-guide/index":{"id":"guides/configuration-guide/index","title":"Configuration Guide","description":"","sidebar":"tutorialSidebar"},"guides/configuration-guide/inventory":{"id":"guides/configuration-guide/inventory","title":"Inventory","description":"The inventory used for the environment is located in the inventory directory.","sidebar":"tutorialSidebar"},"guides/configuration-guide/loadbalancer":{"id":"guides/configuration-guide/loadbalancer","title":"Loadbalancer","description":"IP addresses & FQDNs","sidebar":"tutorialSidebar"},"guides/configuration-guide/manager":{"id":"guides/configuration-guide/manager","title":"Manager","description":"Stable release","sidebar":"tutorialSidebar"},"guides/configuration-guide/network":{"id":"guides/configuration-guide/network","title":"Network","description":"Netplan","sidebar":"tutorialSidebar"},"guides/configuration-guide/openstack/aodh":{"id":"guides/configuration-guide/openstack/aodh","title":"Aodh","description":"* Aodh admin guide","sidebar":"tutorialSidebar"},"guides/configuration-guide/openstack/barbican":{"id":"guides/configuration-guide/openstack/barbican","title":"Barbican","description":"* Barbican admin guide","sidebar":"tutorialSidebar"},"guides/configuration-guide/openstack/ceilometer":{"id":"guides/configuration-guide/openstack/ceilometer","title":"Ceilometer","description":"* Ceilometer admin guide","sidebar":"tutorialSidebar"},"guides/configuration-guide/openstack/cinder":{"id":"guides/configuration-guide/openstack/cinder","title":"Cinder","description":"* Cinder admin guide","sidebar":"tutorialSidebar"},"guides/configuration-guide/openstack/designate":{"id":"guides/configuration-guide/openstack/designate","title":"Designate","description":"* Designate admin guide","sidebar":"tutorialSidebar"},"guides/configuration-guide/openstack/glance":{"id":"guides/configuration-guide/openstack/glance","title":"Glance","description":"* Glance admin guide","sidebar":"tutorialSidebar"},"guides/configuration-guide/openstack/heat":{"id":"guides/configuration-guide/openstack/heat","title":"Heat","description":"* Heat admin guide","sidebar":"tutorialSidebar"},"guides/configuration-guide/openstack/horizon":{"id":"guides/configuration-guide/openstack/horizon","title":"Horizon","description":"* Horizon admin guide","sidebar":"tutorialSidebar"},"guides/configuration-guide/openstack/index":{"id":"guides/configuration-guide/openstack/index","title":"OpenStack","description":"Image tags","sidebar":"tutorialSidebar"},"guides/configuration-guide/openstack/ironic":{"id":"guides/configuration-guide/openstack/ironic","title":"Ironic","description":"* Ironic admin guide","sidebar":"tutorialSidebar"},"guides/configuration-guide/openstack/keystone":{"id":"guides/configuration-guide/openstack/keystone","title":"Keystone","description":"* Keystone admin guide","sidebar":"tutorialSidebar"},"guides/configuration-guide/openstack/magnum":{"id":"guides/configuration-guide/openstack/magnum","title":"Magnum","description":"* Magnum admin guide","sidebar":"tutorialSidebar"},"guides/configuration-guide/openstack/manila":{"id":"guides/configuration-guide/openstack/manila","title":"Manila","description":"* Manila admin guide","sidebar":"tutorialSidebar"},"guides/configuration-guide/openstack/neutron":{"id":"guides/configuration-guide/openstack/neutron","title":"Neutron","description":"* Neutron admin guide","sidebar":"tutorialSidebar"},"guides/configuration-guide/openstack/nova":{"id":"guides/configuration-guide/openstack/nova","title":"Nova","description":"* Nova admin guide","sidebar":"tutorialSidebar"},"guides/configuration-guide/openstack/octavia":{"id":"guides/configuration-guide/openstack/octavia","title":"Octavia","description":"* Octavia admin guide","sidebar":"tutorialSidebar"},"guides/configuration-guide/openstack/placement":{"id":"guides/configuration-guide/openstack/placement","title":"Placement","description":"* Placement admin guide","sidebar":"tutorialSidebar"},"guides/configuration-guide/openstack/skyline":{"id":"guides/configuration-guide/openstack/skyline","title":"Skyline","description":"Skyline APIServer","sidebar":"tutorialSidebar"},"guides/configuration-guide/proxy":{"id":"guides/configuration-guide/proxy","title":"Proxy","description":"In the following examples, it is assumed that the Squid proxy integrated by OSISM","sidebar":"tutorialSidebar"},"guides/configuration-guide/services/chrony":{"id":"guides/configuration-guide/services/chrony","title":"Chrony","description":"With the osism.services.chrony role, it is possible to manage the used NTP servers on a node.","sidebar":"tutorialSidebar"},"guides/configuration-guide/services/docker":{"id":"guides/configuration-guide/services/docker","title":"Docker","description":"With the osism.services.docker role, it is possible to manage Docker.","sidebar":"tutorialSidebar"},"guides/configuration-guide/services/index":{"id":"guides/configuration-guide/services/index","title":"Services","description":"This section contains the documentation of the Ansible collection","sidebar":"tutorialSidebar"},"guides/configuration-guide/services/tuned":{"id":"guides/configuration-guide/services/tuned","title":"Tuned","description":"The roller can be applied with osism apply tuned. The role is applied to all","sidebar":"tutorialSidebar"},"guides/configuration-guide/validations/index":{"id":"guides/configuration-guide/validations/index","title":"Validations","description":"This section contains the documentation of the Ansible collection","sidebar":"tutorialSidebar"},"guides/deploy-guide/bootstrap":{"id":"guides/deploy-guide/bootstrap","title":"Bootstrap","description":"The prerequisite for bootstraping the nodes of a cluster the Manager node has to be","sidebar":"tutorialSidebar"},"guides/deploy-guide/examples/cloud-in-a-box":{"id":"guides/deploy-guide/examples/cloud-in-a-box","title":"Cloud in a Box","description":"This section has moved. You can now find the content in the","sidebar":"tutorialSidebar"},"guides/deploy-guide/examples/index":{"id":"guides/deploy-guide/examples/index","title":"Examples","description":"","sidebar":"tutorialSidebar"},"guides/deploy-guide/examples/testbed":{"id":"guides/deploy-guide/examples/testbed","title":"Testbed","description":"This section has moved. You can now find the content in the","sidebar":"tutorialSidebar"},"guides/deploy-guide/index":{"id":"guides/deploy-guide/index","title":"Deploy Guide","description":"OSISM is deployed in a series of successive steps. The steps are documented in the Deploy Guide.","sidebar":"tutorialSidebar"},"guides/deploy-guide/manager":{"id":"guides/deploy-guide/manager","title":"Manager","description":"The prerequisite for deploying the Manager node is a Seed node. What a Seed node is","sidebar":"tutorialSidebar"},"guides/deploy-guide/provisioning":{"id":"guides/deploy-guide/provisioning","title":"Provisioning of bare-metal nodes","description":"For the initial deployment of the management plane and the control plane of OSISM,","sidebar":"tutorialSidebar"},"guides/deploy-guide/seed":{"id":"guides/deploy-guide/seed","title":"Seed","description":"The prerequisite for the deployment of a cluster is a configuration repository.","sidebar":"tutorialSidebar"},"guides/deploy-guide/services/ceph":{"id":"guides/deploy-guide/services/ceph","title":"Ceph","description":"In OSISM it is also possible to integrate and use existing Ceph clusters. It","sidebar":"tutorialSidebar"},"guides/deploy-guide/services/index":{"id":"guides/deploy-guide/services/index","title":"Services","description":"The prerequisite for depoying the services of a cluster is the bootstrap of","sidebar":"tutorialSidebar"},"guides/deploy-guide/services/infrastructure":{"id":"guides/deploy-guide/services/infrastructure","title":"Infrastructure","description":"Common issues with deploying infrastructure services required by OpenStack","sidebar":"tutorialSidebar"},"guides/deploy-guide/services/kubernetes":{"id":"guides/deploy-guide/services/kubernetes","title":"Kubernetes","description":"As of OSISM 7, it is possible to create a Kubernetes cluster on all nodes.","sidebar":"tutorialSidebar"},"guides/deploy-guide/services/logging-monitoring":{"id":"guides/deploy-guide/services/logging-monitoring","title":"Logging & Monitoring","description":"Common issues with deploying logging & monitoring services provided by Kolla","sidebar":"tutorialSidebar"},"guides/deploy-guide/services/network":{"id":"guides/deploy-guide/services/network","title":"Network","description":"1. Open vSwitch (OVS)","sidebar":"tutorialSidebar"},"guides/deploy-guide/services/openstack":{"id":"guides/deploy-guide/services/openstack","title":"OpenStack","description":"Common issues with deploying OpenStack services are documented in the","sidebar":"tutorialSidebar"},"guides/index":{"id":"guides/index","title":"Guides","description":"* The Concept Guide explains which components and modules make up OSISM. It also","sidebar":"tutorialSidebar"},"guides/operations-guide/ceph":{"id":"guides/operations-guide/ceph","title":"Ceph","description":"Where to find docs","sidebar":"tutorialSidebar"},"guides/operations-guide/index":{"id":"guides/operations-guide/index","title":"Operations Guide","description":"Change Node states","sidebar":"tutorialSidebar"},"guides/operations-guide/infrastructure":{"id":"guides/operations-guide/infrastructure","title":"Infrastructure","description":"Loadbalancer","sidebar":"tutorialSidebar"},"guides/operations-guide/manager/apply":{"id":"guides/operations-guide/manager/apply","title":"Apply","description":"List all available plays","sidebar":"tutorialSidebar"},"guides/operations-guide/manager/console":{"id":"guides/operations-guide/manager/console","title":"Console","description":"A console command is available in the OSISM CLI. This allows specific parts of the","sidebar":"tutorialSidebar"},"guides/operations-guide/manager/get":{"id":"guides/operations-guide/manager/get","title":"Get","description":"A get command is available in the OSISM CLI. This allows to gather specific information.","sidebar":"tutorialSidebar"},"guides/operations-guide/manager/index":{"id":"guides/operations-guide/manager/index","title":"Manager","description":"OSISM orchestrator","sidebar":"tutorialSidebar"},"guides/operations-guide/manager/log":{"id":"guides/operations-guide/manager/log","title":"Logging","description":"Ansible","sidebar":"tutorialSidebar"},"guides/operations-guide/manager/task":{"id":"guides/operations-guide/manager/task","title":"Task","description":"List","sidebar":"tutorialSidebar"},"guides/operations-guide/network":{"id":"guides/operations-guide/network","title":"Network","description":"OpenStack, OVN, and Open vSwitch all really like UUIDs.","sidebar":"tutorialSidebar"},"guides/operations-guide/openstack/cinder":{"id":"guides/operations-guide/openstack/cinder","title":"Cinder","description":"Remove service","sidebar":"tutorialSidebar"},"guides/operations-guide/openstack/index":{"id":"guides/operations-guide/openstack/index","title":"OpenStack","description":"Create an external network","sidebar":"tutorialSidebar"},"guides/operations-guide/openstack/keystone":{"id":"guides/operations-guide/openstack/keystone","title":"Keystone","description":"* List all users of a project who have been assigned the member role","sidebar":"tutorialSidebar"},"guides/operations-guide/openstack/neutron":{"id":"guides/operations-guide/openstack/neutron","title":"Neutron","description":"Quality of Service (QoS)","sidebar":"tutorialSidebar"},"guides/operations-guide/openstack/nova":{"id":"guides/operations-guide/openstack/nova","title":"Nova","description":"Get all servers on a node","sidebar":"tutorialSidebar"},"guides/operations-guide/openstack/octavia":{"id":"guides/operations-guide/openstack/octavia","title":"Octavia","description":"Cleanup of amphorae missing from the DB","sidebar":"tutorialSidebar"},"guides/operations-guide/openstack/tools/flavor-manager":{"id":"guides/operations-guide/openstack/tools/flavor-manager","title":"Flavor Manager","description":"Overview","sidebar":"tutorialSidebar"},"guides/operations-guide/openstack/tools/image-manager/index":{"id":"guides/operations-guide/openstack/tools/image-manager/index","title":"Image Manager","description":"The OpenStack Image Manager is a tool for managing all","sidebar":"tutorialSidebar"},"guides/operations-guide/openstack/tools/image-manager/update":{"id":"guides/operations-guide/openstack/tools/image-manager/update","title":"Image Manager update.py","description":"Overview","sidebar":"tutorialSidebar"},"guides/operations-guide/openstack/tools/index":{"id":"guides/operations-guide/openstack/tools/index","title":"Tools","description":"","sidebar":"tutorialSidebar"},"guides/operations-guide/openstack/tools/openstack-health-monitor":{"id":"guides/operations-guide/openstack/tools/openstack-health-monitor","title":"Setting up OpenStack health monitor on Debian","description":"Kurt Garloff, 2024-02-20","sidebar":"tutorialSidebar"},"guides/operations-guide/openstack/tools/project-manager":{"id":"guides/operations-guide/openstack/tools/project-manager","title":"Project Manager","description":"Overview","sidebar":"tutorialSidebar"},"guides/operations-guide/openstack/tools/resource-manager":{"id":"guides/operations-guide/openstack/tools/resource-manager","title":"Resource Manager","description":"Preparations","sidebar":"tutorialSidebar"},"guides/operations-guide/openstack/tools/sandbox-manager":{"id":"guides/operations-guide/openstack/tools/sandbox-manager","title":"Sandbox Manager","description":"","sidebar":"tutorialSidebar"},"guides/operations-guide/openstack/tools/simple-stress":{"id":"guides/operations-guide/openstack/tools/simple-stress","title":"Simple Stress","description":"Overview","sidebar":"tutorialSidebar"},"guides/other-guides/cloud-in-a-box":{"id":"guides/other-guides/cloud-in-a-box","title":"Cloud in a Box - CiaB","description":"\ud83d\udca1 Cloud in a Box (CiaB) is a minimalistic installation of the latest stable OSISM release with only services which are needed to","sidebar":"tutorialSidebar"},"guides/other-guides/contributor-guide":{"id":"guides/other-guides/contributor-guide","title":"Contributor Guide","description":"We welcome any issues, change requests or general feedback. Do not hestiate to open an issue.","sidebar":"tutorialSidebar"},"guides/other-guides/developer-guide/index":{"id":"guides/other-guides/developer-guide/index","title":"Developer Guide","description":"How to add a new service","sidebar":"tutorialSidebar"},"guides/other-guides/developer-guide/releases":{"id":"guides/other-guides/developer-guide/releases","title":"Releases","description":"How we handle releases","sidebar":"tutorialSidebar"},"guides/other-guides/developer-guide/scripts":{"id":"guides/other-guides/developer-guide/scripts","title":"Scripts","description":"Scripts are included in container images to simplify development work and to enable","sidebar":"tutorialSidebar"},"guides/other-guides/developer-guide/zuul":{"id":"guides/other-guides/developer-guide/zuul","title":"Zuul CI","description":"We use Zuul CI as a CI service for OSISM. The service is not required for","sidebar":"tutorialSidebar"},"guides/other-guides/index":{"id":"guides/other-guides/index","title":"Other Guides","description":"","sidebar":"tutorialSidebar"},"guides/other-guides/style-guide":{"id":"guides/other-guides/style-guide","title":"Style Guide","description":"Ansible","sidebar":"tutorialSidebar"},"guides/other-guides/testbed":{"id":"guides/other-guides/testbed","title":"Testbed","description":"With the OSISM Testbed, it is possible to run a full Sovereign Cloud Stack","sidebar":"tutorialSidebar"},"guides/troubleshooting-guide/ceph":{"id":"guides/troubleshooting-guide/ceph","title":"Ceph","description":"Where to find docs","sidebar":"tutorialSidebar"},"guides/troubleshooting-guide/index":{"id":"guides/troubleshooting-guide/index","title":"Troubleshooting Guide","description":"\ud83d\udca1 The Troubleshooting Guide describe how to solve issues.","sidebar":"tutorialSidebar"},"guides/troubleshooting-guide/manager":{"id":"guides/troubleshooting-guide/manager","title":"Manager","description":"Reset","sidebar":"tutorialSidebar"},"guides/troubleshooting-guide/openstack":{"id":"guides/troubleshooting-guide/openstack","title":"OpenStack","description":"Database creation fails","sidebar":"tutorialSidebar"},"guides/upgrade-guide/ceph":{"id":"guides/upgrade-guide/ceph","title":"Ceph","description":"","sidebar":"tutorialSidebar"},"guides/upgrade-guide/docker":{"id":"guides/upgrade-guide/docker","title":"Docker","description":"The Docker version used is defined via the parameter docker_version in the file","sidebar":"tutorialSidebar"},"guides/upgrade-guide/index":{"id":"guides/upgrade-guide/index","title":"Upgrade Guide","description":"In the examples, the pull of images (if supported by a role) is always run first. While","sidebar":"tutorialSidebar"},"guides/upgrade-guide/infrastructure":{"id":"guides/upgrade-guide/infrastructure","title":"Infrastructure","description":"1. Kubernetes","sidebar":"tutorialSidebar"},"guides/upgrade-guide/logging-monitoring":{"id":"guides/upgrade-guide/logging-monitoring","title":"Logging & Monitoring","description":"1. OpenSearch","sidebar":"tutorialSidebar"},"guides/upgrade-guide/manager":{"id":"guides/upgrade-guide/manager","title":"Manager","description":"Always read the release notes first to learn what has changed and what","sidebar":"tutorialSidebar"},"guides/upgrade-guide/network":{"id":"guides/upgrade-guide/network","title":"Network","description":"1. Open vSwitch (OVS)","sidebar":"tutorialSidebar"},"guides/upgrade-guide/openstack":{"id":"guides/upgrade-guide/openstack","title":"OpenStack","description":"When upgrade the different OpenStack services, all containers must be","sidebar":"tutorialSidebar"},"guides/user-guide/index":{"id":"guides/user-guide/index","title":"User Guide","description":"","sidebar":"tutorialSidebar"},"guides/user-guide/migration-vmware-esix":{"id":"guides/user-guide/migration-vmware-esix","title":"Migrate from VMware ESXi to OpenStack","description":"This guide is an example of how to perform a manual migration from a VMware ESXi host to OpenStack.","sidebar":"tutorialSidebar"},"guides/user-guide/openstack/index":{"id":"guides/user-guide/openstack/index","title":"OpenStack","description":"","sidebar":"tutorialSidebar"},"guides/user-guide/openstack/openstackclient":{"id":"guides/user-guide/openstack/openstackclient","title":"Client","description":"OpenStackClient looks for a clouds.yaml configuration file in the following locations:","sidebar":"tutorialSidebar"},"guides/user-guide/openstack/security-groups":{"id":"guides/user-guide/openstack/security-groups","title":"How to configure and use security groups","description":"Security groups in OpenStack are part of the network security mechanisms provided for the users.","sidebar":"tutorialSidebar"},"guides/user-guide/openstack/user-data-backups":{"id":"guides/user-guide/openstack/user-data-backups","title":"User Data Backups","description":"This guide will explain common procedures for creating and restoring backups of user data accumulated in cloud resources such as volumes, images or ephemeral server disks.","sidebar":"tutorialSidebar"},"index":{"id":"index","title":"Getting started","description":"OSISM is a solution for the holistic management of sustainable, sovereign","sidebar":"tutorialSidebar"},"references/cli":{"id":"references/cli","title":"Command line interface reference","description":"","sidebar":"tutorialSidebar"},"references/configuration":{"id":"references/configuration","title":"Configuration reference","description":"","sidebar":"tutorialSidebar"},"references/index":{"id":"references/index","title":"References","description":"","sidebar":"tutorialSidebar"},"references/parameters":{"id":"references/parameters","title":"Parameters reference","description":"","sidebar":"tutorialSidebar"},"release-notes/index":{"id":"release-notes/index","title":"Release Notes","description":"The old release notes (before OSISM 7) can be found on the archived page","sidebar":"tutorialSidebar"},"release-notes/osism-7":{"id":"release-notes/osism-7","title":"OSISM 7","description":"Instructions for the upgrade can be found in the Upgrade Guide.","sidebar":"tutorialSidebar"}}}}')}}]); \ No newline at end of file diff --git a/assets/js/0058b4c6.607ef452.js b/assets/js/0058b4c6.607ef452.js new file mode 100644 index 0000000000..e2f4f4a97a --- /dev/null +++ b/assets/js/0058b4c6.607ef452.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkosism=self.webpackChunkosism||[]).push([[4088],{6462:e=>{e.exports=JSON.parse('{"version":{"pluginId":"default","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"tutorialSidebar":[{"type":"link","label":"Getting started","href":"/docs/","docId":"index","unlisted":false},{"type":"category","label":"Guides","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Concept Guide","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Components","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Ceph","href":"/docs/guides/concept-guide/components/ceph","docId":"guides/concept-guide/components/ceph","unlisted":false},{"type":"link","label":"Cluster API","href":"/docs/guides/concept-guide/components/clusterapi","docId":"guides/concept-guide/components/clusterapi","unlisted":false},{"type":"link","label":"Gardener","href":"/docs/guides/concept-guide/components/gardener","docId":"guides/concept-guide/components/gardener","unlisted":false},{"type":"link","label":"Ironic","href":"/docs/guides/concept-guide/components/ironic","docId":"guides/concept-guide/components/ironic","unlisted":false},{"type":"link","label":"K3S","href":"/docs/guides/concept-guide/components/k3s","docId":"guides/concept-guide/components/k3s","unlisted":false},{"type":"link","label":"Keycloak","href":"/docs/guides/concept-guide/components/keycloak","docId":"guides/concept-guide/components/keycloak","unlisted":false},{"type":"link","label":"Netdata","href":"/docs/guides/concept-guide/components/netdata","docId":"guides/concept-guide/components/netdata","unlisted":false},{"type":"link","label":"OpenStack","href":"/docs/guides/concept-guide/components/openstack","docId":"guides/concept-guide/components/openstack","unlisted":false},{"type":"link","label":"Prometheus & Grafana","href":"/docs/guides/concept-guide/components/prometheus","docId":"guides/concept-guide/components/prometheus","unlisted":false},{"type":"link","label":"Proxmox VE","href":"/docs/guides/concept-guide/components/proxmox","docId":"guides/concept-guide/components/proxmox","unlisted":false},{"type":"link","label":"SONiC & OVN","href":"/docs/guides/concept-guide/components/sonic","docId":"guides/concept-guide/components/sonic","unlisted":false},{"type":"link","label":"Teleport","href":"/docs/guides/concept-guide/components/teleport","docId":"guides/concept-guide/components/teleport","unlisted":false}],"href":"/docs/guides/concept-guide/components/"},{"type":"link","label":"Layers in a cluster","href":"/docs/guides/concept-guide/layers","docId":"guides/concept-guide/layers","unlisted":false},{"type":"link","label":"Nodes in a cluster","href":"/docs/guides/concept-guide/nodes","docId":"guides/concept-guide/nodes","unlisted":false},{"type":"link","label":"Cluster design","href":"/docs/guides/concept-guide/design","docId":"guides/concept-guide/design","unlisted":false},{"type":"link","label":"Use cases","href":"/docs/guides/concept-guide/use-cases","docId":"guides/concept-guide/use-cases","unlisted":false},{"type":"link","label":"Hardware Bill of Materials","href":"/docs/guides/concept-guide/hardware-bom","docId":"guides/concept-guide/hardware-bom","unlisted":false}],"href":"/docs/guides/concept-guide/"},{"type":"category","label":"Deploy Guide","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Seed","href":"/docs/guides/deploy-guide/seed","docId":"guides/deploy-guide/seed","unlisted":false},{"type":"link","label":"Manager","href":"/docs/guides/deploy-guide/manager","docId":"guides/deploy-guide/manager","unlisted":false},{"type":"link","label":"Provisioning","href":"/docs/guides/deploy-guide/provisioning","docId":"guides/deploy-guide/provisioning","unlisted":false},{"type":"link","label":"Bootstrap","href":"/docs/guides/deploy-guide/bootstrap","docId":"guides/deploy-guide/bootstrap","unlisted":false},{"type":"category","label":"Services","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Infrastructure","href":"/docs/guides/deploy-guide/services/infrastructure","docId":"guides/deploy-guide/services/infrastructure","unlisted":false},{"type":"link","label":"Kubernetes","href":"/docs/guides/deploy-guide/services/kubernetes","docId":"guides/deploy-guide/services/kubernetes","unlisted":false},{"type":"link","label":"Network","href":"/docs/guides/deploy-guide/services/network","docId":"guides/deploy-guide/services/network","unlisted":false},{"type":"link","label":"Logging & Monitoring","href":"/docs/guides/deploy-guide/services/logging-monitoring","docId":"guides/deploy-guide/services/logging-monitoring","unlisted":false},{"type":"link","label":"Ceph","href":"/docs/guides/deploy-guide/services/ceph","docId":"guides/deploy-guide/services/ceph","unlisted":false},{"type":"link","label":"Ceph via Rook (technical preview)","href":"/docs/guides/deploy-guide/services/rook","docId":"guides/deploy-guide/services/rook","unlisted":false},{"type":"link","label":"OpenStack","href":"/docs/guides/deploy-guide/services/openstack","docId":"guides/deploy-guide/services/openstack","unlisted":false}],"href":"/docs/guides/deploy-guide/services/"},{"type":"category","label":"Examples","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Cloud in a Box","href":"/docs/guides/deploy-guide/examples/cloud-in-a-box","docId":"guides/deploy-guide/examples/cloud-in-a-box","unlisted":false},{"type":"link","label":"Testbed","href":"/docs/guides/deploy-guide/examples/testbed","docId":"guides/deploy-guide/examples/testbed","unlisted":false}],"href":"/docs/guides/deploy-guide/examples/"}],"href":"/docs/guides/deploy-guide/"},{"type":"category","label":"Upgrade Guide","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Manager","href":"/docs/guides/upgrade-guide/manager","docId":"guides/upgrade-guide/manager","unlisted":false},{"type":"link","label":"Network","href":"/docs/guides/upgrade-guide/network","docId":"guides/upgrade-guide/network","unlisted":false},{"type":"link","label":"Ceph","href":"/docs/guides/upgrade-guide/ceph","docId":"guides/upgrade-guide/ceph","unlisted":false},{"type":"link","label":"Docker","href":"/docs/guides/upgrade-guide/docker","docId":"guides/upgrade-guide/docker","unlisted":false},{"type":"link","label":"Infrastructure","href":"/docs/guides/upgrade-guide/infrastructure","docId":"guides/upgrade-guide/infrastructure","unlisted":false},{"type":"link","label":"Logging & Monitoring","href":"/docs/guides/upgrade-guide/logging-monitoring","docId":"guides/upgrade-guide/logging-monitoring","unlisted":false},{"type":"link","label":"OpenStack","href":"/docs/guides/upgrade-guide/openstack","docId":"guides/upgrade-guide/openstack","unlisted":false}],"href":"/docs/guides/upgrade-guide/"},{"type":"category","label":"Configuration Guide","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Configuration repository","href":"/docs/guides/configuration-guide/configuration-repository","docId":"guides/configuration-guide/configuration-repository","unlisted":false},{"type":"link","label":"Inventory","href":"/docs/guides/configuration-guide/inventory","docId":"guides/configuration-guide/inventory","unlisted":false},{"type":"link","label":"Manager","href":"/docs/guides/configuration-guide/manager","docId":"guides/configuration-guide/manager","unlisted":false},{"type":"link","label":"Network","href":"/docs/guides/configuration-guide/network","docId":"guides/configuration-guide/network","unlisted":false},{"type":"link","label":"Proxy","href":"/docs/guides/configuration-guide/proxy","docId":"guides/configuration-guide/proxy","unlisted":false},{"type":"link","label":"Loadbalancer","href":"/docs/guides/configuration-guide/loadbalancer","docId":"guides/configuration-guide/loadbalancer","unlisted":false},{"type":"link","label":"Ceph","href":"/docs/guides/configuration-guide/ceph","docId":"guides/configuration-guide/ceph","unlisted":false},{"type":"category","label":"OpenStack","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Aodh","href":"/docs/guides/configuration-guide/openstack/aodh","docId":"guides/configuration-guide/openstack/aodh","unlisted":false},{"type":"link","label":"Barbican","href":"/docs/guides/configuration-guide/openstack/barbican","docId":"guides/configuration-guide/openstack/barbican","unlisted":false},{"type":"link","label":"Ceilometer","href":"/docs/guides/configuration-guide/openstack/ceilometer","docId":"guides/configuration-guide/openstack/ceilometer","unlisted":false},{"type":"link","label":"Cinder","href":"/docs/guides/configuration-guide/openstack/cinder","docId":"guides/configuration-guide/openstack/cinder","unlisted":false},{"type":"link","label":"Designate","href":"/docs/guides/configuration-guide/openstack/designate","docId":"guides/configuration-guide/openstack/designate","unlisted":false},{"type":"link","label":"Glance","href":"/docs/guides/configuration-guide/openstack/glance","docId":"guides/configuration-guide/openstack/glance","unlisted":false},{"type":"link","label":"Heat","href":"/docs/guides/configuration-guide/openstack/heat","docId":"guides/configuration-guide/openstack/heat","unlisted":false},{"type":"link","label":"Horizon","href":"/docs/guides/configuration-guide/openstack/horizon","docId":"guides/configuration-guide/openstack/horizon","unlisted":false},{"type":"link","label":"Ironic","href":"/docs/guides/configuration-guide/openstack/ironic","docId":"guides/configuration-guide/openstack/ironic","unlisted":false},{"type":"link","label":"Keystone","href":"/docs/guides/configuration-guide/openstack/keystone","docId":"guides/configuration-guide/openstack/keystone","unlisted":false},{"type":"link","label":"Magnum","href":"/docs/guides/configuration-guide/openstack/magnum","docId":"guides/configuration-guide/openstack/magnum","unlisted":false},{"type":"link","label":"Manila","href":"/docs/guides/configuration-guide/openstack/manila","docId":"guides/configuration-guide/openstack/manila","unlisted":false},{"type":"link","label":"Neutron","href":"/docs/guides/configuration-guide/openstack/neutron","docId":"guides/configuration-guide/openstack/neutron","unlisted":false},{"type":"link","label":"Nova","href":"/docs/guides/configuration-guide/openstack/nova","docId":"guides/configuration-guide/openstack/nova","unlisted":false},{"type":"link","label":"Octavia","href":"/docs/guides/configuration-guide/openstack/octavia","docId":"guides/configuration-guide/openstack/octavia","unlisted":false},{"type":"link","label":"Placement","href":"/docs/guides/configuration-guide/openstack/placement","docId":"guides/configuration-guide/openstack/placement","unlisted":false},{"type":"link","label":"Skyline","href":"/docs/guides/configuration-guide/openstack/skyline","docId":"guides/configuration-guide/openstack/skyline","unlisted":false}],"href":"/docs/guides/configuration-guide/openstack/"},{"type":"link","label":"Ceph via Rook (technical preview)","href":"/docs/guides/configuration-guide/rook","docId":"guides/configuration-guide/rook","unlisted":false},{"type":"category","label":"Commons","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Certificates","href":"/docs/guides/configuration-guide/commons/certificates","docId":"guides/configuration-guide/commons/certificates","unlisted":false},{"type":"link","label":"Packages","href":"/docs/guides/configuration-guide/commons/packages","docId":"guides/configuration-guide/commons/packages","unlisted":false},{"type":"link","label":"Resolvconf","href":"/docs/guides/configuration-guide/commons/resolvconf","docId":"guides/configuration-guide/commons/resolvconf","unlisted":false},{"type":"link","label":"Services","href":"/docs/guides/configuration-guide/commons/services","docId":"guides/configuration-guide/commons/services","unlisted":false},{"type":"link","label":"SSH Config","href":"/docs/guides/configuration-guide/commons/sshconfig","docId":"guides/configuration-guide/commons/sshconfig","unlisted":false},{"type":"link","label":"Sysctl","href":"/docs/guides/configuration-guide/commons/sysctl","docId":"guides/configuration-guide/commons/sysctl","unlisted":false},{"type":"link","label":"Timezone","href":"/docs/guides/configuration-guide/commons/timezone","docId":"guides/configuration-guide/commons/timezone","unlisted":false},{"type":"link","label":"User","href":"/docs/guides/configuration-guide/commons/user","docId":"guides/configuration-guide/commons/user","unlisted":false}],"href":"/docs/guides/configuration-guide/commons/"},{"type":"category","label":"Services","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Chrony","href":"/docs/guides/configuration-guide/services/chrony","docId":"guides/configuration-guide/services/chrony","unlisted":false},{"type":"link","label":"Docker","href":"/docs/guides/configuration-guide/services/docker","docId":"guides/configuration-guide/services/docker","unlisted":false},{"type":"link","label":"Tuned","href":"/docs/guides/configuration-guide/services/tuned","docId":"guides/configuration-guide/services/tuned","unlisted":false}],"href":"/docs/guides/configuration-guide/services/"},{"type":"link","label":"Validations","href":"/docs/guides/configuration-guide/validations/","docId":"guides/configuration-guide/validations/index","unlisted":false}],"href":"/docs/guides/configuration-guide/"},{"type":"category","label":"Operations Guide","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Manager","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Apply","href":"/docs/guides/operations-guide/manager/apply","docId":"guides/operations-guide/manager/apply","unlisted":false},{"type":"link","label":"Console","href":"/docs/guides/operations-guide/manager/console","docId":"guides/operations-guide/manager/console","unlisted":false},{"type":"link","label":"Get","href":"/docs/guides/operations-guide/manager/get","docId":"guides/operations-guide/manager/get","unlisted":false},{"type":"link","label":"Logging","href":"/docs/guides/operations-guide/manager/log","docId":"guides/operations-guide/manager/log","unlisted":false},{"type":"link","label":"Task","href":"/docs/guides/operations-guide/manager/task","docId":"guides/operations-guide/manager/task","unlisted":false}],"href":"/docs/guides/operations-guide/manager/"},{"type":"link","label":"Ceph","href":"/docs/guides/operations-guide/ceph","docId":"guides/operations-guide/ceph","unlisted":false},{"type":"link","label":"Infrastructure","href":"/docs/guides/operations-guide/infrastructure","docId":"guides/operations-guide/infrastructure","unlisted":false},{"type":"link","label":"Network","href":"/docs/guides/operations-guide/network","docId":"guides/operations-guide/network","unlisted":false},{"type":"category","label":"OpenStack","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Tools","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Image Manager","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Automated updates","href":"/docs/guides/operations-guide/openstack/tools/image-manager/update","docId":"guides/operations-guide/openstack/tools/image-manager/update","unlisted":false}],"href":"/docs/guides/operations-guide/openstack/tools/image-manager/"},{"type":"link","label":"Flavor Manager","href":"/docs/guides/operations-guide/openstack/tools/flavor-manager","docId":"guides/operations-guide/openstack/tools/flavor-manager","unlisted":false},{"type":"link","label":"Resource Manager","href":"/docs/guides/operations-guide/openstack/tools/resource-manager","docId":"guides/operations-guide/openstack/tools/resource-manager","unlisted":false},{"type":"link","label":"Project Manager","href":"/docs/guides/operations-guide/openstack/tools/project-manager","docId":"guides/operations-guide/openstack/tools/project-manager","unlisted":false},{"type":"link","label":"Sandbox Manager","href":"/docs/guides/operations-guide/openstack/tools/sandbox-manager","docId":"guides/operations-guide/openstack/tools/sandbox-manager","unlisted":false},{"type":"link","label":"Simple Stress","href":"/docs/guides/operations-guide/openstack/tools/simple-stress","docId":"guides/operations-guide/openstack/tools/simple-stress","unlisted":false},{"type":"link","label":"OpenStack Health Monitor","href":"/docs/guides/operations-guide/openstack/tools/openstack-health-monitor","docId":"guides/operations-guide/openstack/tools/openstack-health-monitor","unlisted":false}],"href":"/docs/guides/operations-guide/openstack/tools/"},{"type":"link","label":"Cinder","href":"/docs/guides/operations-guide/openstack/cinder","docId":"guides/operations-guide/openstack/cinder","unlisted":false},{"type":"link","label":"Keystone","href":"/docs/guides/operations-guide/openstack/keystone","docId":"guides/operations-guide/openstack/keystone","unlisted":false},{"type":"link","label":"Neutron","href":"/docs/guides/operations-guide/openstack/neutron","docId":"guides/operations-guide/openstack/neutron","unlisted":false},{"type":"link","label":"Nova","href":"/docs/guides/operations-guide/openstack/nova","docId":"guides/operations-guide/openstack/nova","unlisted":false},{"type":"link","label":"Octavia","href":"/docs/guides/operations-guide/openstack/octavia","docId":"guides/operations-guide/openstack/octavia","unlisted":false}],"href":"/docs/guides/operations-guide/openstack/"},{"type":"link","label":"Ceph via Rook (technical preview)","href":"/docs/guides/operations-guide/rook","docId":"guides/operations-guide/rook","unlisted":false}],"href":"/docs/guides/operations-guide/"},{"type":"category","label":"Troubleshooting Guide","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Manager","href":"/docs/guides/troubleshooting-guide/manager","docId":"guides/troubleshooting-guide/manager","unlisted":false},{"type":"link","label":"OpenStack","href":"/docs/guides/troubleshooting-guide/openstack","docId":"guides/troubleshooting-guide/openstack","unlisted":false},{"type":"link","label":"Ceph","href":"/docs/guides/troubleshooting-guide/ceph","docId":"guides/troubleshooting-guide/ceph","unlisted":false}],"href":"/docs/guides/troubleshooting-guide/"},{"type":"category","label":"User Guide","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Migrate from VMware ESXi to OpenStack","href":"/docs/guides/user-guide/migration-vmware-esix","docId":"guides/user-guide/migration-vmware-esix","unlisted":false},{"type":"category","label":"OpenStack","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Client","href":"/docs/guides/user-guide/openstack/openstackclient","docId":"guides/user-guide/openstack/openstackclient","unlisted":false},{"type":"link","label":"Security groups","href":"/docs/guides/user-guide/openstack/security-groups","docId":"guides/user-guide/openstack/security-groups","unlisted":false},{"type":"link","label":"User Data Backups","href":"/docs/guides/user-guide/openstack/user-data-backups","docId":"guides/user-guide/openstack/user-data-backups","unlisted":false}],"href":"/docs/guides/user-guide/openstack/"}],"href":"/docs/guides/user-guide/"},{"type":"category","label":"Other Guides","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Cloud in a Box Guide","href":"/docs/guides/other-guides/cloud-in-a-box","docId":"guides/other-guides/cloud-in-a-box","unlisted":false},{"type":"link","label":"Contributor Guide","href":"/docs/guides/other-guides/contributor-guide","docId":"guides/other-guides/contributor-guide","unlisted":false},{"type":"category","label":"Developer Guide","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Releases","href":"/docs/guides/other-guides/developer-guide/releases","docId":"guides/other-guides/developer-guide/releases","unlisted":false},{"type":"link","label":"Scripts","href":"/docs/guides/other-guides/developer-guide/scripts","docId":"guides/other-guides/developer-guide/scripts","unlisted":false},{"type":"link","label":"Zuul CI","href":"/docs/guides/other-guides/developer-guide/zuul","docId":"guides/other-guides/developer-guide/zuul","unlisted":false}],"href":"/docs/guides/other-guides/developer-guide/"},{"type":"link","label":"Style Guide","href":"/docs/guides/other-guides/style-guide","docId":"guides/other-guides/style-guide","unlisted":false},{"type":"link","label":"Testbed Guide","href":"/docs/guides/other-guides/testbed","docId":"guides/other-guides/testbed","unlisted":false}],"href":"/docs/guides/other-guides/"}],"href":"/docs/guides/"},{"type":"category","label":"References","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Command line interface reference","href":"/docs/references/cli","docId":"references/cli","unlisted":false},{"type":"link","label":"Configuration reference","href":"/docs/references/configuration","docId":"references/configuration","unlisted":false},{"type":"link","label":"Parameters reference","href":"/docs/references/parameters","docId":"references/parameters","unlisted":false}],"href":"/docs/references/"},{"type":"category","label":"Release Notes","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"OSISM 7","href":"/docs/release-notes/osism-7","docId":"release-notes/osism-7","unlisted":false}],"href":"/docs/release-notes/"},{"type":"category","label":"Appendix","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Comparisons","href":"/docs/appendix/comparisons","docId":"appendix/comparisons","unlisted":false},{"type":"link","label":"Glossary","href":"/docs/appendix/glossary","docId":"appendix/glossary","unlisted":false},{"type":"link","label":"Networks","href":"/docs/appendix/networks","docId":"appendix/networks","unlisted":false},{"type":"link","label":"Standards","href":"/docs/appendix/standards","docId":"appendix/standards","unlisted":false}],"href":"/docs/appendix/"}]},"docs":{"appendix/comparisons":{"id":"appendix/comparisons","title":"Comparisons","description":"OSISM vs. FishOS","sidebar":"tutorialSidebar"},"appendix/glossary":{"id":"appendix/glossary","title":"Glossary","description":"\ud83d\udca1 This section serves as the central glossary within OSISM. It is intended to clearly define","sidebar":"tutorialSidebar"},"appendix/index":{"id":"appendix/index","title":"Appendix","description":"","sidebar":"tutorialSidebar"},"appendix/networks":{"id":"appendix/networks","title":"Networks","description":"| Parameter | CIDR |","sidebar":"tutorialSidebar"},"appendix/standards":{"id":"appendix/standards","title":"Standards","description":"| Name | OSISM Documentation | SCS Standard Track | SCS Standard | SCS Documentation |","sidebar":"tutorialSidebar"},"guides/concept-guide/components/ceph":{"id":"guides/concept-guide/components/ceph","title":"Ceph","description":"Ceph is an Open Source software defined storage platform designed to provide highly scalable","sidebar":"tutorialSidebar"},"guides/concept-guide/components/clusterapi":{"id":"guides/concept-guide/components/clusterapi","title":"Cluster API","description":"Kubernetes as a Service (KaaS) is a cloud service model that simplifies the deployment,","sidebar":"tutorialSidebar"},"guides/concept-guide/components/gardener":{"id":"guides/concept-guide/components/gardener","title":"Gardener","description":"Kubernetes as a Service (KaaS) simplifies the deployment, management, and scaling of","sidebar":"tutorialSidebar"},"guides/concept-guide/components/index":{"id":"guides/concept-guide/components/index","title":"Components","description":"* Infrastructure as a Service (IaaS) with OpenStack","sidebar":"tutorialSidebar"},"guides/concept-guide/components/ironic":{"id":"guides/concept-guide/components/ironic","title":"Ironic","description":"OpenStack Ironic is a project that provides Baremetal as a Service (BMaaS), enabling the","sidebar":"tutorialSidebar"},"guides/concept-guide/components/k3s":{"id":"guides/concept-guide/components/k3s","title":"K3S","description":"Lifecycle Management of K3S in OSISM","sidebar":"tutorialSidebar"},"guides/concept-guide/components/keycloak":{"id":"guides/concept-guide/components/keycloak","title":"Keycloak","description":"Lifecycle Management of Keycloak in OSISM","sidebar":"tutorialSidebar"},"guides/concept-guide/components/netdata":{"id":"guides/concept-guide/components/netdata","title":"Netdata","description":"Lifecycle Management of Netdata in OSISM","sidebar":"tutorialSidebar"},"guides/concept-guide/components/openstack":{"id":"guides/concept-guide/components/openstack","title":"OpenStack","description":"Lifecycle Management of OpenStack in OSISM","sidebar":"tutorialSidebar"},"guides/concept-guide/components/prometheus":{"id":"guides/concept-guide/components/prometheus","title":"Prometheus & Grafana","description":"Lifecycle Management of Prometheus in OSISM","sidebar":"tutorialSidebar"},"guides/concept-guide/components/proxmox":{"id":"guides/concept-guide/components/proxmox","title":"Proxmox VE","description":"Proxmox Virtual Environment (Proxmox VE) is an open-source server virtualization management","sidebar":"tutorialSidebar"},"guides/concept-guide/components/sonic":{"id":"guides/concept-guide/components/sonic","title":"SONiC & OVN","description":"Lifecycle Management of SONiC in OSISM","sidebar":"tutorialSidebar"},"guides/concept-guide/components/teleport":{"id":"guides/concept-guide/components/teleport","title":"Teleport","description":"Lifecycle Management of Teleport in OSISM","sidebar":"tutorialSidebar"},"guides/concept-guide/design":{"id":"guides/concept-guide/design","title":"Cluster design","description":"Parts of this chapter are based on the OpenStack Architecture Design Guide.","sidebar":"tutorialSidebar"},"guides/concept-guide/hardware-bom":{"id":"guides/concept-guide/hardware-bom","title":"Hardware Bill of Materials","description":"The brands, models and configurations listed are examples. There is no","sidebar":"tutorialSidebar"},"guides/concept-guide/index":{"id":"guides/concept-guide/index","title":"Concept Guide","description":"Highlevel Overview","sidebar":"tutorialSidebar"},"guides/concept-guide/layers":{"id":"guides/concept-guide/layers","title":"Layers in a cluster","description":"Compute Plane","sidebar":"tutorialSidebar"},"guides/concept-guide/nodes":{"id":"guides/concept-guide/nodes","title":"Nodes in a cluster","description":"Compute Node","sidebar":"tutorialSidebar"},"guides/concept-guide/use-cases":{"id":"guides/concept-guide/use-cases","title":"Use cases","description":"Hyper-converged infrastructure (HCI)","sidebar":"tutorialSidebar"},"guides/configuration-guide/ceph":{"id":"guides/configuration-guide/ceph","title":"Ceph","description":"The official Ceph documentation is located on https://docs.ceph.com/en/latest/rados/configuration/","sidebar":"tutorialSidebar"},"guides/configuration-guide/commons/certificates":{"id":"guides/configuration-guide/commons/certificates","title":"Certificates","description":"With the osism.commons.certificates role, it is possible to add custom CA certificates","sidebar":"tutorialSidebar"},"guides/configuration-guide/commons/index":{"id":"guides/configuration-guide/commons/index","title":"Commons","description":"This section contains the documentation of the Ansible collection osism.commons.","sidebar":"tutorialSidebar"},"guides/configuration-guide/commons/packages":{"id":"guides/configuration-guide/commons/packages","title":"Packages","description":"With the osism.commons.packages role, it is possible to add packages on a node","sidebar":"tutorialSidebar"},"guides/configuration-guide/commons/resolvconf":{"id":"guides/configuration-guide/commons/resolvconf","title":"Resolvconf","description":"With the osism.commons.resolvconf role, it is possible to manage the used DNS servers on a node.","sidebar":"tutorialSidebar"},"guides/configuration-guide/commons/services":{"id":"guides/configuration-guide/commons/services","title":"Services","description":"With the osism.commons.services role, it is possible to manage services on a node","sidebar":"tutorialSidebar"},"guides/configuration-guide/commons/sshconfig":{"id":"guides/configuration-guide/commons/sshconfig","title":"SSH Config","description":"With the osism.commons.sshconfig role, it is possible to manage a SSH config","sidebar":"tutorialSidebar"},"guides/configuration-guide/commons/sysctl":{"id":"guides/configuration-guide/commons/sysctl","title":"Sysctl","description":"With the osism.commons.sysctl role, it is possible to manage the attributes of the kernel","sidebar":"tutorialSidebar"},"guides/configuration-guide/commons/timezone":{"id":"guides/configuration-guide/commons/timezone","title":"Timezone","description":"With the osism.commons.timezone role, it is possible to manage the used timezone on a node.","sidebar":"tutorialSidebar"},"guides/configuration-guide/commons/user":{"id":"guides/configuration-guide/commons/user","title":"User","description":"With the osism.commons.user role, it is possible to manage additional","sidebar":"tutorialSidebar"},"guides/configuration-guide/configuration-repository":{"id":"guides/configuration-guide/configuration-repository","title":"Configuration Repository","description":"The configuration required for an OSISM managed cluster is stored in a single Git","sidebar":"tutorialSidebar"},"guides/configuration-guide/index":{"id":"guides/configuration-guide/index","title":"Configuration Guide","description":"","sidebar":"tutorialSidebar"},"guides/configuration-guide/inventory":{"id":"guides/configuration-guide/inventory","title":"Inventory","description":"The inventory used for the environment is located in the inventory directory.","sidebar":"tutorialSidebar"},"guides/configuration-guide/loadbalancer":{"id":"guides/configuration-guide/loadbalancer","title":"Loadbalancer","description":"IP addresses & FQDNs","sidebar":"tutorialSidebar"},"guides/configuration-guide/manager":{"id":"guides/configuration-guide/manager","title":"Manager","description":"Stable release","sidebar":"tutorialSidebar"},"guides/configuration-guide/network":{"id":"guides/configuration-guide/network","title":"Network","description":"Netplan","sidebar":"tutorialSidebar"},"guides/configuration-guide/openstack/aodh":{"id":"guides/configuration-guide/openstack/aodh","title":"Aodh","description":"* Aodh admin guide","sidebar":"tutorialSidebar"},"guides/configuration-guide/openstack/barbican":{"id":"guides/configuration-guide/openstack/barbican","title":"Barbican","description":"* Barbican admin guide","sidebar":"tutorialSidebar"},"guides/configuration-guide/openstack/ceilometer":{"id":"guides/configuration-guide/openstack/ceilometer","title":"Ceilometer","description":"* Ceilometer admin guide","sidebar":"tutorialSidebar"},"guides/configuration-guide/openstack/cinder":{"id":"guides/configuration-guide/openstack/cinder","title":"Cinder","description":"* Cinder admin guide","sidebar":"tutorialSidebar"},"guides/configuration-guide/openstack/designate":{"id":"guides/configuration-guide/openstack/designate","title":"Designate","description":"* Designate admin guide","sidebar":"tutorialSidebar"},"guides/configuration-guide/openstack/glance":{"id":"guides/configuration-guide/openstack/glance","title":"Glance","description":"* Glance admin guide","sidebar":"tutorialSidebar"},"guides/configuration-guide/openstack/heat":{"id":"guides/configuration-guide/openstack/heat","title":"Heat","description":"* Heat admin guide","sidebar":"tutorialSidebar"},"guides/configuration-guide/openstack/horizon":{"id":"guides/configuration-guide/openstack/horizon","title":"Horizon","description":"* Horizon admin guide","sidebar":"tutorialSidebar"},"guides/configuration-guide/openstack/index":{"id":"guides/configuration-guide/openstack/index","title":"OpenStack","description":"Image tags","sidebar":"tutorialSidebar"},"guides/configuration-guide/openstack/ironic":{"id":"guides/configuration-guide/openstack/ironic","title":"Ironic","description":"* Ironic admin guide","sidebar":"tutorialSidebar"},"guides/configuration-guide/openstack/keystone":{"id":"guides/configuration-guide/openstack/keystone","title":"Keystone","description":"* Keystone admin guide","sidebar":"tutorialSidebar"},"guides/configuration-guide/openstack/magnum":{"id":"guides/configuration-guide/openstack/magnum","title":"Magnum","description":"* Magnum admin guide","sidebar":"tutorialSidebar"},"guides/configuration-guide/openstack/manila":{"id":"guides/configuration-guide/openstack/manila","title":"Manila","description":"* Manila admin guide","sidebar":"tutorialSidebar"},"guides/configuration-guide/openstack/neutron":{"id":"guides/configuration-guide/openstack/neutron","title":"Neutron","description":"* Neutron admin guide","sidebar":"tutorialSidebar"},"guides/configuration-guide/openstack/nova":{"id":"guides/configuration-guide/openstack/nova","title":"Nova","description":"* Nova admin guide","sidebar":"tutorialSidebar"},"guides/configuration-guide/openstack/octavia":{"id":"guides/configuration-guide/openstack/octavia","title":"Octavia","description":"* Octavia admin guide","sidebar":"tutorialSidebar"},"guides/configuration-guide/openstack/placement":{"id":"guides/configuration-guide/openstack/placement","title":"Placement","description":"* Placement admin guide","sidebar":"tutorialSidebar"},"guides/configuration-guide/openstack/skyline":{"id":"guides/configuration-guide/openstack/skyline","title":"Skyline","description":"Skyline APIServer","sidebar":"tutorialSidebar"},"guides/configuration-guide/proxy":{"id":"guides/configuration-guide/proxy","title":"Proxy","description":"In the following examples, it is assumed that the Squid proxy integrated by OSISM","sidebar":"tutorialSidebar"},"guides/configuration-guide/rook":{"id":"guides/configuration-guide/rook","title":"Ceph via Rook (technical preview)","description":"The official Ceph documentation is located on https://docs.ceph.com/en/latest/rados/configuration/","sidebar":"tutorialSidebar"},"guides/configuration-guide/services/chrony":{"id":"guides/configuration-guide/services/chrony","title":"Chrony","description":"With the osism.services.chrony role, it is possible to manage the used NTP servers on a node.","sidebar":"tutorialSidebar"},"guides/configuration-guide/services/docker":{"id":"guides/configuration-guide/services/docker","title":"Docker","description":"With the osism.services.docker role, it is possible to manage Docker.","sidebar":"tutorialSidebar"},"guides/configuration-guide/services/index":{"id":"guides/configuration-guide/services/index","title":"Services","description":"This section contains the documentation of the Ansible collection","sidebar":"tutorialSidebar"},"guides/configuration-guide/services/tuned":{"id":"guides/configuration-guide/services/tuned","title":"Tuned","description":"The roller can be applied with osism apply tuned. The role is applied to all","sidebar":"tutorialSidebar"},"guides/configuration-guide/validations/index":{"id":"guides/configuration-guide/validations/index","title":"Validations","description":"This section contains the documentation of the Ansible collection","sidebar":"tutorialSidebar"},"guides/deploy-guide/bootstrap":{"id":"guides/deploy-guide/bootstrap","title":"Bootstrap","description":"The prerequisite for bootstraping the nodes of a cluster the Manager node has to be","sidebar":"tutorialSidebar"},"guides/deploy-guide/examples/cloud-in-a-box":{"id":"guides/deploy-guide/examples/cloud-in-a-box","title":"Cloud in a Box","description":"This section has moved. You can now find the content in the","sidebar":"tutorialSidebar"},"guides/deploy-guide/examples/index":{"id":"guides/deploy-guide/examples/index","title":"Examples","description":"","sidebar":"tutorialSidebar"},"guides/deploy-guide/examples/testbed":{"id":"guides/deploy-guide/examples/testbed","title":"Testbed","description":"This section has moved. You can now find the content in the","sidebar":"tutorialSidebar"},"guides/deploy-guide/index":{"id":"guides/deploy-guide/index","title":"Deploy Guide","description":"OSISM is deployed in a series of successive steps. The steps are documented in the Deploy Guide.","sidebar":"tutorialSidebar"},"guides/deploy-guide/manager":{"id":"guides/deploy-guide/manager","title":"Manager","description":"The prerequisite for deploying the Manager node is a Seed node. What a Seed node is","sidebar":"tutorialSidebar"},"guides/deploy-guide/provisioning":{"id":"guides/deploy-guide/provisioning","title":"Provisioning of bare-metal nodes","description":"For the initial deployment of the management plane and the control plane of OSISM,","sidebar":"tutorialSidebar"},"guides/deploy-guide/seed":{"id":"guides/deploy-guide/seed","title":"Seed","description":"The prerequisite for the deployment of a cluster is a configuration repository.","sidebar":"tutorialSidebar"},"guides/deploy-guide/services/ceph":{"id":"guides/deploy-guide/services/ceph","title":"Ceph","description":"In OSISM it is also possible to integrate and use existing Ceph clusters. It","sidebar":"tutorialSidebar"},"guides/deploy-guide/services/index":{"id":"guides/deploy-guide/services/index","title":"Services","description":"The prerequisite for depoying the services of a cluster is the bootstrap of","sidebar":"tutorialSidebar"},"guides/deploy-guide/services/infrastructure":{"id":"guides/deploy-guide/services/infrastructure","title":"Infrastructure","description":"Common issues with deploying infrastructure services required by OpenStack","sidebar":"tutorialSidebar"},"guides/deploy-guide/services/kubernetes":{"id":"guides/deploy-guide/services/kubernetes","title":"Kubernetes","description":"As of OSISM 7, it is possible to create a Kubernetes cluster on all nodes.","sidebar":"tutorialSidebar"},"guides/deploy-guide/services/logging-monitoring":{"id":"guides/deploy-guide/services/logging-monitoring","title":"Logging & Monitoring","description":"Common issues with deploying logging & monitoring services provided by Kolla","sidebar":"tutorialSidebar"},"guides/deploy-guide/services/network":{"id":"guides/deploy-guide/services/network","title":"Network","description":"1. Open vSwitch (OVS)","sidebar":"tutorialSidebar"},"guides/deploy-guide/services/openstack":{"id":"guides/deploy-guide/services/openstack","title":"OpenStack","description":"Common issues with deploying OpenStack services are documented in the","sidebar":"tutorialSidebar"},"guides/deploy-guide/services/rook":{"id":"guides/deploy-guide/services/rook","title":"Ceph via Rook (technical preview)","description":"This is a technical preview and not recommended for production use yet.","sidebar":"tutorialSidebar"},"guides/index":{"id":"guides/index","title":"Guides","description":"* The Concept Guide explains which components and modules make up OSISM. It also","sidebar":"tutorialSidebar"},"guides/operations-guide/ceph":{"id":"guides/operations-guide/ceph","title":"Ceph","description":"Where to find docs","sidebar":"tutorialSidebar"},"guides/operations-guide/index":{"id":"guides/operations-guide/index","title":"Operations Guide","description":"Change Node states","sidebar":"tutorialSidebar"},"guides/operations-guide/infrastructure":{"id":"guides/operations-guide/infrastructure","title":"Infrastructure","description":"Loadbalancer","sidebar":"tutorialSidebar"},"guides/operations-guide/manager/apply":{"id":"guides/operations-guide/manager/apply","title":"Apply","description":"List all available plays","sidebar":"tutorialSidebar"},"guides/operations-guide/manager/console":{"id":"guides/operations-guide/manager/console","title":"Console","description":"A console command is available in the OSISM CLI. This allows specific parts of the","sidebar":"tutorialSidebar"},"guides/operations-guide/manager/get":{"id":"guides/operations-guide/manager/get","title":"Get","description":"A get command is available in the OSISM CLI. This allows to gather specific information.","sidebar":"tutorialSidebar"},"guides/operations-guide/manager/index":{"id":"guides/operations-guide/manager/index","title":"Manager","description":"OSISM orchestrator","sidebar":"tutorialSidebar"},"guides/operations-guide/manager/log":{"id":"guides/operations-guide/manager/log","title":"Logging","description":"Ansible","sidebar":"tutorialSidebar"},"guides/operations-guide/manager/task":{"id":"guides/operations-guide/manager/task","title":"Task","description":"List","sidebar":"tutorialSidebar"},"guides/operations-guide/network":{"id":"guides/operations-guide/network","title":"Network","description":"OpenStack, OVN, and Open vSwitch all really like UUIDs.","sidebar":"tutorialSidebar"},"guides/operations-guide/openstack/cinder":{"id":"guides/operations-guide/openstack/cinder","title":"Cinder","description":"Remove service","sidebar":"tutorialSidebar"},"guides/operations-guide/openstack/index":{"id":"guides/operations-guide/openstack/index","title":"OpenStack","description":"Create an external network","sidebar":"tutorialSidebar"},"guides/operations-guide/openstack/keystone":{"id":"guides/operations-guide/openstack/keystone","title":"Keystone","description":"* List all users of a project who have been assigned the member role","sidebar":"tutorialSidebar"},"guides/operations-guide/openstack/neutron":{"id":"guides/operations-guide/openstack/neutron","title":"Neutron","description":"Quality of Service (QoS)","sidebar":"tutorialSidebar"},"guides/operations-guide/openstack/nova":{"id":"guides/operations-guide/openstack/nova","title":"Nova","description":"Get all servers on a node","sidebar":"tutorialSidebar"},"guides/operations-guide/openstack/octavia":{"id":"guides/operations-guide/openstack/octavia","title":"Octavia","description":"Cleanup of amphorae missing from the DB","sidebar":"tutorialSidebar"},"guides/operations-guide/openstack/tools/flavor-manager":{"id":"guides/operations-guide/openstack/tools/flavor-manager","title":"Flavor Manager","description":"Overview","sidebar":"tutorialSidebar"},"guides/operations-guide/openstack/tools/image-manager/index":{"id":"guides/operations-guide/openstack/tools/image-manager/index","title":"Image Manager","description":"The OpenStack Image Manager is a tool for managing all","sidebar":"tutorialSidebar"},"guides/operations-guide/openstack/tools/image-manager/update":{"id":"guides/operations-guide/openstack/tools/image-manager/update","title":"Image Manager update.py","description":"Overview","sidebar":"tutorialSidebar"},"guides/operations-guide/openstack/tools/index":{"id":"guides/operations-guide/openstack/tools/index","title":"Tools","description":"","sidebar":"tutorialSidebar"},"guides/operations-guide/openstack/tools/openstack-health-monitor":{"id":"guides/operations-guide/openstack/tools/openstack-health-monitor","title":"Setting up OpenStack health monitor on Debian","description":"Kurt Garloff, 2024-02-20","sidebar":"tutorialSidebar"},"guides/operations-guide/openstack/tools/project-manager":{"id":"guides/operations-guide/openstack/tools/project-manager","title":"Project Manager","description":"Overview","sidebar":"tutorialSidebar"},"guides/operations-guide/openstack/tools/resource-manager":{"id":"guides/operations-guide/openstack/tools/resource-manager","title":"Resource Manager","description":"Preparations","sidebar":"tutorialSidebar"},"guides/operations-guide/openstack/tools/sandbox-manager":{"id":"guides/operations-guide/openstack/tools/sandbox-manager","title":"Sandbox Manager","description":"","sidebar":"tutorialSidebar"},"guides/operations-guide/openstack/tools/simple-stress":{"id":"guides/operations-guide/openstack/tools/simple-stress","title":"Simple Stress","description":"Overview","sidebar":"tutorialSidebar"},"guides/operations-guide/rook":{"id":"guides/operations-guide/rook","title":"Ceph via Rook (technical preview)","description":"This is a technical preview and not recommended for production use yet.","sidebar":"tutorialSidebar"},"guides/other-guides/cloud-in-a-box":{"id":"guides/other-guides/cloud-in-a-box","title":"Cloud in a Box - CiaB","description":"\ud83d\udca1 Cloud in a Box (CiaB) is a minimalistic installation of the latest stable OSISM release with only services which are needed to","sidebar":"tutorialSidebar"},"guides/other-guides/contributor-guide":{"id":"guides/other-guides/contributor-guide","title":"Contributor Guide","description":"We welcome any issues, change requests or general feedback. Do not hestiate to open an issue.","sidebar":"tutorialSidebar"},"guides/other-guides/developer-guide/index":{"id":"guides/other-guides/developer-guide/index","title":"Developer Guide","description":"How to add a new service","sidebar":"tutorialSidebar"},"guides/other-guides/developer-guide/releases":{"id":"guides/other-guides/developer-guide/releases","title":"Releases","description":"How we handle releases","sidebar":"tutorialSidebar"},"guides/other-guides/developer-guide/scripts":{"id":"guides/other-guides/developer-guide/scripts","title":"Scripts","description":"Scripts are included in container images to simplify development work and to enable","sidebar":"tutorialSidebar"},"guides/other-guides/developer-guide/zuul":{"id":"guides/other-guides/developer-guide/zuul","title":"Zuul CI","description":"We use Zuul CI as a CI service for OSISM. The service is not required for","sidebar":"tutorialSidebar"},"guides/other-guides/index":{"id":"guides/other-guides/index","title":"Other Guides","description":"","sidebar":"tutorialSidebar"},"guides/other-guides/style-guide":{"id":"guides/other-guides/style-guide","title":"Style Guide","description":"Ansible","sidebar":"tutorialSidebar"},"guides/other-guides/testbed":{"id":"guides/other-guides/testbed","title":"Testbed","description":"With the OSISM Testbed, it is possible to run a full Sovereign Cloud Stack","sidebar":"tutorialSidebar"},"guides/troubleshooting-guide/ceph":{"id":"guides/troubleshooting-guide/ceph","title":"Ceph","description":"Where to find docs","sidebar":"tutorialSidebar"},"guides/troubleshooting-guide/index":{"id":"guides/troubleshooting-guide/index","title":"Troubleshooting Guide","description":"\ud83d\udca1 The Troubleshooting Guide describe how to solve issues.","sidebar":"tutorialSidebar"},"guides/troubleshooting-guide/manager":{"id":"guides/troubleshooting-guide/manager","title":"Manager","description":"Reset","sidebar":"tutorialSidebar"},"guides/troubleshooting-guide/openstack":{"id":"guides/troubleshooting-guide/openstack","title":"OpenStack","description":"Database creation fails","sidebar":"tutorialSidebar"},"guides/upgrade-guide/ceph":{"id":"guides/upgrade-guide/ceph","title":"Ceph","description":"See Rook Operations.","sidebar":"tutorialSidebar"},"guides/upgrade-guide/docker":{"id":"guides/upgrade-guide/docker","title":"Docker","description":"The Docker version used is defined via the parameter docker_version in the file","sidebar":"tutorialSidebar"},"guides/upgrade-guide/index":{"id":"guides/upgrade-guide/index","title":"Upgrade Guide","description":"In the examples, the pull of images (if supported by a role) is always run first. While","sidebar":"tutorialSidebar"},"guides/upgrade-guide/infrastructure":{"id":"guides/upgrade-guide/infrastructure","title":"Infrastructure","description":"1. Kubernetes","sidebar":"tutorialSidebar"},"guides/upgrade-guide/logging-monitoring":{"id":"guides/upgrade-guide/logging-monitoring","title":"Logging & Monitoring","description":"1. OpenSearch","sidebar":"tutorialSidebar"},"guides/upgrade-guide/manager":{"id":"guides/upgrade-guide/manager","title":"Manager","description":"Always read the release notes first to learn what has changed and what","sidebar":"tutorialSidebar"},"guides/upgrade-guide/network":{"id":"guides/upgrade-guide/network","title":"Network","description":"1. Open vSwitch (OVS)","sidebar":"tutorialSidebar"},"guides/upgrade-guide/openstack":{"id":"guides/upgrade-guide/openstack","title":"OpenStack","description":"When upgrade the different OpenStack services, all containers must be","sidebar":"tutorialSidebar"},"guides/user-guide/index":{"id":"guides/user-guide/index","title":"User Guide","description":"","sidebar":"tutorialSidebar"},"guides/user-guide/migration-vmware-esix":{"id":"guides/user-guide/migration-vmware-esix","title":"Migrate from VMware ESXi to OpenStack","description":"This guide is an example of how to perform a manual migration from a VMware ESXi host to OpenStack.","sidebar":"tutorialSidebar"},"guides/user-guide/openstack/index":{"id":"guides/user-guide/openstack/index","title":"OpenStack","description":"","sidebar":"tutorialSidebar"},"guides/user-guide/openstack/openstackclient":{"id":"guides/user-guide/openstack/openstackclient","title":"Client","description":"OpenStackClient looks for a clouds.yaml configuration file in the following locations:","sidebar":"tutorialSidebar"},"guides/user-guide/openstack/security-groups":{"id":"guides/user-guide/openstack/security-groups","title":"How to configure and use security groups","description":"Security groups in OpenStack are part of the network security mechanisms provided for the users.","sidebar":"tutorialSidebar"},"guides/user-guide/openstack/user-data-backups":{"id":"guides/user-guide/openstack/user-data-backups","title":"User Data Backups","description":"This guide will explain common procedures for creating and restoring backups of user data accumulated in cloud resources such as volumes, images or ephemeral server disks.","sidebar":"tutorialSidebar"},"index":{"id":"index","title":"Getting started","description":"OSISM is a solution for the holistic management of sustainable, sovereign","sidebar":"tutorialSidebar"},"references/cli":{"id":"references/cli","title":"Command line interface reference","description":"","sidebar":"tutorialSidebar"},"references/configuration":{"id":"references/configuration","title":"Configuration reference","description":"","sidebar":"tutorialSidebar"},"references/index":{"id":"references/index","title":"References","description":"","sidebar":"tutorialSidebar"},"references/parameters":{"id":"references/parameters","title":"Parameters reference","description":"","sidebar":"tutorialSidebar"},"release-notes/index":{"id":"release-notes/index","title":"Release Notes","description":"The old release notes (before OSISM 7) can be found on the archived page","sidebar":"tutorialSidebar"},"release-notes/osism-7":{"id":"release-notes/osism-7","title":"OSISM 7","description":"Instructions for the upgrade can be found in the Upgrade Guide.","sidebar":"tutorialSidebar"}}}}')}}]); \ No newline at end of file diff --git a/assets/js/06fc275a.bacd9c39.js b/assets/js/06fc275a.bacd9c39.js new file mode 100644 index 0000000000..8a207f9a38 --- /dev/null +++ b/assets/js/06fc275a.bacd9c39.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkosism=self.webpackChunkosism||[]).push([[6759],{6428:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>u,frontMatter:()=>o,metadata:()=>l,toc:()=>a});var s=i(5893),t=i(1151);const o={sidebar_label:"Skyline"},r="Skyline",l={id:"guides/configuration-guide/openstack/skyline",title:"Skyline",description:"Skyline APIServer",source:"@site/docs/guides/configuration-guide/openstack/skyline.md",sourceDirName:"guides/configuration-guide/openstack",slug:"/guides/configuration-guide/openstack/skyline",permalink:"/docs/guides/configuration-guide/openstack/skyline",draft:!1,unlisted:!1,editUrl:"https://github.com/osism/osism.github.io/tree/main/docs/guides/configuration-guide/openstack/skyline.md",tags:[],version:"current",frontMatter:{sidebar_label:"Skyline"},sidebar:"tutorialSidebar",previous:{title:"Placement",permalink:"/docs/guides/configuration-guide/openstack/placement"},next:{title:"Ceph via Rook (technical preview)",permalink:"/docs/guides/configuration-guide/rook"}},c={},a=[{value:"Skyline APIServer",id:"skyline-apiserver",level:2},{value:"Skyline Console",id:"skyline-console",level:2}];function d(e){const n={a:"a",h1:"h1",h2:"h2",li:"li",ul:"ul",...(0,t.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"skyline",children:"Skyline"}),"\n",(0,s.jsx)(n.h2,{id:"skyline-apiserver",children:"Skyline APIServer"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://docs.openstack.org/skyline-apiserver/latest/configuration/settings.html",children:"Skyline APIServer configuration reference"})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"skyline-console",children:"Skyline Console"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://docs.openstack.org/skyline-console/latest/admin/index.html",children:"Skyline Console admin guide"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://docs.openstack.org/skyline-console/latest/configuration/skyline-console-settings.html",children:"Skyline Console configuration reference"})}),"\n"]})]})}function u(e={}){const{wrapper:n}={...(0,t.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},1151:(e,n,i)=>{i.d(n,{Z:()=>l,a:()=>r});var s=i(7294);const t={},o=s.createContext(t);function r(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:r(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/06fc275a.ea18936d.js b/assets/js/06fc275a.ea18936d.js deleted file mode 100644 index 4c0c4de512..0000000000 --- a/assets/js/06fc275a.ea18936d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkosism=self.webpackChunkosism||[]).push([[6759],{6428:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>c,contentTitle:()=>l,default:()=>u,frontMatter:()=>o,metadata:()=>r,toc:()=>a});var s=i(5893),t=i(1151);const o={sidebar_label:"Skyline"},l="Skyline",r={id:"guides/configuration-guide/openstack/skyline",title:"Skyline",description:"Skyline APIServer",source:"@site/docs/guides/configuration-guide/openstack/skyline.md",sourceDirName:"guides/configuration-guide/openstack",slug:"/guides/configuration-guide/openstack/skyline",permalink:"/docs/guides/configuration-guide/openstack/skyline",draft:!1,unlisted:!1,editUrl:"https://github.com/osism/osism.github.io/tree/main/docs/guides/configuration-guide/openstack/skyline.md",tags:[],version:"current",frontMatter:{sidebar_label:"Skyline"},sidebar:"tutorialSidebar",previous:{title:"Placement",permalink:"/docs/guides/configuration-guide/openstack/placement"},next:{title:"Commons",permalink:"/docs/guides/configuration-guide/commons/"}},c={},a=[{value:"Skyline APIServer",id:"skyline-apiserver",level:2},{value:"Skyline Console",id:"skyline-console",level:2}];function d(e){const n={a:"a",h1:"h1",h2:"h2",li:"li",ul:"ul",...(0,t.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"skyline",children:"Skyline"}),"\n",(0,s.jsx)(n.h2,{id:"skyline-apiserver",children:"Skyline APIServer"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://docs.openstack.org/skyline-apiserver/latest/configuration/settings.html",children:"Skyline APIServer configuration reference"})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"skyline-console",children:"Skyline Console"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://docs.openstack.org/skyline-console/latest/admin/index.html",children:"Skyline Console admin guide"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://docs.openstack.org/skyline-console/latest/configuration/skyline-console-settings.html",children:"Skyline Console configuration reference"})}),"\n"]})]})}function u(e={}){const{wrapper:n}={...(0,t.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},1151:(e,n,i)=>{i.d(n,{Z:()=>r,a:()=>l});var s=i(7294);const t={},o=s.createContext(t);function l(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:l(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0e3a612a.04d1cbc8.js b/assets/js/0e3a612a.04d1cbc8.js new file mode 100644 index 0000000000..9cece25f4a --- /dev/null +++ b/assets/js/0e3a612a.04d1cbc8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkosism=self.webpackChunkosism||[]).push([[888],{4963:(e,o,n)=>{n.r(o),n.d(o,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>t,metadata:()=>i,toc:()=>c});var s=n(5893),r=n(1151);const t={sidebar_label:"Ceph via Rook (technical preview)",sidebar_position:31},a="Ceph via Rook (technical preview)",i={id:"guides/configuration-guide/rook",title:"Ceph via Rook (technical preview)",description:"The official Ceph documentation is located on https://docs.ceph.com/en/latest/rados/configuration/",source:"@site/docs/guides/configuration-guide/rook.md",sourceDirName:"guides/configuration-guide",slug:"/guides/configuration-guide/rook",permalink:"/docs/guides/configuration-guide/rook",draft:!1,unlisted:!1,editUrl:"https://github.com/osism/osism.github.io/tree/main/docs/guides/configuration-guide/rook.md",tags:[],version:"current",sidebarPosition:31,frontMatter:{sidebar_label:"Ceph via Rook (technical preview)",sidebar_position:31},sidebar:"tutorialSidebar",previous:{title:"Skyline",permalink:"/docs/guides/configuration-guide/openstack/skyline"},next:{title:"Commons",permalink:"/docs/guides/configuration-guide/commons/"}},l={},c=[{value:"Unique Identifier",id:"unique-identifier",level:2},{value:"Client",id:"client",level:2},{value:"Network configuration",id:"network-configuration",level:2},{value:"Configuring addressRanges",id:"configuring-addressranges",level:3},{value:"Configuring encryption, compression, msgr2",id:"configuring-encryption-compression-msgr2",level:3},{value:"Flexible approach using rook_network",id:"flexible-approach-using-rook_network",level:3},{value:"RGW service - CephObjectStore CRD",id:"rgw-service---cephobjectstore-crd",level:2},{value:"Cephfs - CephFilesystem CRD",id:"cephfs---cephfilesystem-crd",level:2},{value:"Extra pools - CephBlockPool CRD",id:"extra-pools---cephblockpool-crd",level:2},{value:"Storage configuration",id:"storage-configuration",level:2},{value:"Deploy OSDs on all nodes and found devices",id:"deploy-osds-on-all-nodes-and-found-devices",level:3},{value:"Deploy OSDs on specific nodes and devices based on a device filter",id:"deploy-osds-on-specific-nodes-and-devices-based-on-a-device-filter",level:3},{value:"Deploy OSDs on specific nodes and devices based on device names",id:"deploy-osds-on-specific-nodes-and-devices-based-on-device-names",level:3},{value:"Flexible approach using rook_storage",id:"flexible-approach-using-rook_storage",level:3},{value:"Encrypted OSDs",id:"encrypted-osds",level:3},{value:"Dashboard",id:"dashboard",level:2},{value:"Enable dashboard and configure ssl and ports",id:"enable-dashboard-and-configure-ssl-and-ports",level:3},{value:"Rook Cluster Name",id:"rook-cluster-name",level:2},{value:"Kubernetes Namespaces",id:"kubernetes-namespaces",level:2},{value:"Number and Placement of Ceph Daemons",id:"number-and-placement-of-ceph-daemons",level:2},{value:"Crash Collector",id:"crash-collector",level:2},{value:"Crash Collector",id:"crash-collector-1",level:2},{value:"Ceph Config",id:"ceph-config",level:2},{value:"Second Ceph cluster",id:"second-ceph-cluster",level:2},{value:"Helm Value File",id:"helm-value-file",level:2}];function d(e){const o={a:"a",admonition:"admonition",code:"code",del:"del",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(o.h1,{id:"ceph-via-rook-technical-preview",children:"Ceph via Rook (technical preview)"}),"\n",(0,s.jsxs)(o.p,{children:["The official Ceph documentation is located on ",(0,s.jsx)(o.a,{href:"https://docs.ceph.com/en/latest/rados/configuration/",children:"https://docs.ceph.com/en/latest/rados/configuration/"})]}),"\n",(0,s.jsxs)(o.p,{children:["It is ",(0,s.jsx)(o.strong,{children:"strongly advised"})," to use the documentation for the version being used."]}),"\n",(0,s.jsxs)(o.ul,{children:["\n",(0,s.jsxs)(o.li,{children:["Quincy - ",(0,s.jsx)(o.a,{href:"https://docs.ceph.com/en/quincy/rados/configuration/",children:"https://docs.ceph.com/en/quincy/rados/configuration/"})]}),"\n",(0,s.jsxs)(o.li,{children:["Reef - ",(0,s.jsx)(o.a,{href:"https://docs.ceph.com/en/reef/rados/configuration/",children:"https://docs.ceph.com/en/reef/rados/configuration/"})]}),"\n"]}),"\n",(0,s.jsx)(o.h2,{id:"unique-identifier",children:"Unique Identifier"}),"\n",(0,s.jsx)(o.p,{children:"The File System ID is a unique identifier for the cluster."}),"\n",(0,s.jsxs)(o.p,{children:[(0,s.jsxs)(o.del,{children:["The identifier is set via the parameter ",(0,s.jsx)(o.code,{children:"fsid"})," in ",(0,s.jsx)(o.code,{children:"environments/rook/configuration.yml"})]}),"\n",(0,s.jsxs)(o.del,{children:["and must be unique. It can be generated with ",(0,s.jsx)(o.code,{children:"uuidgen"}),"."]})]}),"\n",(0,s.jsxs)(o.p,{children:["It is generated automatically by the ",(0,s.jsx)(o.a,{href:"/docs/guides/deploy-guide/services/rook",children:"Rook Deployment"}),"."]}),"\n",(0,s.jsxs)(o.p,{children:["TODO: To evaluate if we want and can pass a ",(0,s.jsx)(o.code,{children:"fsid"}),". This is no out-of-the-box Rook feature, though."]}),"\n",(0,s.jsx)(o.h2,{id:"client",children:"Client"}),"\n",(0,s.jsx)(o.p,{children:(0,s.jsxs)(o.del,{children:["The ",(0,s.jsx)(o.code,{children:"client.admin"})," keyring is placed in the file ",(0,s.jsx)(o.code,{children:"environments/infrastructure/files/ceph/ceph.client.admin.keyring"}),"."]})}),"\n",(0,s.jsx)(o.p,{children:"There is no real Ceph client installed on the manager node, but a wrapper to enter the Rook Toolbox can be installed."}),"\n",(0,s.jsx)(o.p,{children:"If the namespace of the rook cluster was changed this needs to be reflected as well as the install type of the client."}),"\n",(0,s.jsx)(o.pre,{children:(0,s.jsx)(o.code,{className:"language-yaml",metastring:'title="environments/infrastructure/configuration.yml"',children:"cephclient_install_type: rook\n\ncephclient_rook_namespace: rook-ceph\n"})}),"\n",(0,s.jsx)(o.p,{children:"After successfully configuring the environment for the client, run the installation:"}),"\n",(0,s.jsx)(o.pre,{children:(0,s.jsx)(o.code,{className:"language-bash",children:"osism apply cephclient\n"})}),"\n",(0,s.jsxs)(o.p,{children:["TODO: This will try to detect a prior installation of a Ceph client with the install type ",(0,s.jsx)(o.code,{children:"container"})," or ",(0,s.jsx)(o.code,{children:"package"})," and cleanup that."]}),"\n",(0,s.jsx)(o.h2,{id:"network-configuration",children:"Network configuration"}),"\n",(0,s.jsxs)(o.p,{children:["Some useful ansible variables for the options from the ",(0,s.jsx)(o.a,{href:"https://rook.io/docs/rook/latest-release/CRDs/Cluster/ceph-cluster-crd/?h=#network-configuration-settings",children:"Rook Network Configuration Settings"})," are available.\nIf you want complete flexibility, you can also use the ",(0,s.jsx)(o.code,{children:"rook_network"})," variable which abstracts all settings from ",(0,s.jsx)(o.a,{href:"https://rook.io/docs/rook/latest/CRDs/Cluster/ceph-cluster-crd/#network-configuration-settings",children:"Rook Network Configuration Settings"}),"."]}),"\n",(0,s.jsxs)(o.h3,{id:"configuring-addressranges",children:["Configuring ",(0,s.jsx)(o.code,{children:"addressRanges"})]}),"\n",(0,s.jsx)(o.pre,{children:(0,s.jsx)(o.code,{className:"language-yaml",metastring:'title="environments/rook/configuration.yml"',children:'rook_network_public: "192.168.16.0/24"\nrook_network_cluster: "192.168.17.0/24"\n'})}),"\n",(0,s.jsx)(o.h3,{id:"configuring-encryption-compression-msgr2",children:"Configuring encryption, compression, msgr2"}),"\n",(0,s.jsx)(o.pre,{children:(0,s.jsx)(o.code,{className:"language-yaml",metastring:'title="environments/rook/configuration.yml"',children:"rook_network_encryption: true\nrook_network_compression: true\nrook_network_require_msgr2: false\n"})}),"\n",(0,s.jsxs)(o.h3,{id:"flexible-approach-using-rook_network",children:["Flexible approach using ",(0,s.jsx)(o.code,{children:"rook_network"})]}),"\n",(0,s.jsx)(o.pre,{children:(0,s.jsx)(o.code,{className:"language-yaml",metastring:'title="environments/rook/configuration.yml"',children:'rook_network_encryption: true\nrook_network_compression: true\nrook_network_require_msgr2: false\nrook_network_public: "192.168.16.0/20"\nrook_network_cluster: "{{ rook_network_public }}"\nrook_network:\n connections:\n # Whether to encrypt the data in transit across the wire to prevent eavesdropping the data on the network.\n # The default is false. When encryption is enabled, all communication between clients and Ceph daemons, or between Ceph daemons will be encrypted.\n # When encryption is not enabled, clients still establish a strong initial authentication and data integrity is still validated with a crc check.\n # IMPORTANT: Encryption requires the 5.11 kernel for the latest nbd and cephfs drivers. Alternatively for testing only,\n # you can set the "mounter: rbd-nbd" in the rbd storage class, or "mounter: fuse" in the cephfs storage class.\n # The nbd and fuse drivers are *not* recommended in production since restarting the csi driver pod will disconnect the volumes.\n encryption:\n enabled: "{{ rook_network_encryption }}"\n # Whether to compress the data in transit across the wire. The default is false.\n # Requires Ceph Quincy (v17) or newer. Also see the kernel requirements above for encryption.\n compression:\n enabled: "{{ rook_network_compression }}"\n # Whether to require communication over msgr2. If true, the msgr v1 port (6789) will be disabled\n # and clients will be required to connect to the Ceph cluster with the v2 port (3300).\n # Requires a kernel that supports msgr v2 (kernel 5.11 or CentOS 8.4 or newer).\n requireMsgr2: "{{ rook_network_require_msgr2 }}"\n # enable host networking\n provider: host\n addressRanges:\n public:\n - "{{ rook_network_public }}"\n cluster:\n - "{{ rook_network_cluster }}"\n'})}),"\n",(0,s.jsx)(o.h2,{id:"rgw-service---cephobjectstore-crd",children:"RGW service - CephObjectStore CRD"}),"\n",(0,s.jsx)(o.admonition,{type:"info",children:(0,s.jsxs)(o.p,{children:["OpenStack integration between Keystone/Swift and Rook is currently missing upstream in Rook. Please have a look at ",(0,s.jsx)(o.a,{href:"https://github.com/orgs/SovereignCloudStack/projects/18/views/1?layout=board&pane=issue&itemId=63889060",children:"#1027"})," to get the current status of the integration in OSISM."]})}),"\n",(0,s.jsxs)(o.p,{children:["Have a look at ",(0,s.jsx)(o.a,{href:"https://rook.io/docs/rook/latest/CRDs/Object-Storage/ceph-object-store-crd/",children:"CephObjectStore CRD Spec"})," for details on how to configure the RGW service."]}),"\n",(0,s.jsx)(o.pre,{children:(0,s.jsx)(o.code,{className:"language-yaml",metastring:'title="environments/rook/configuration.yml"',children:'rook_cephobjectstore_default_name: rgw\nrook_cephobjectstore_replicated_default_size: 3\nrook_cephobjectstore_erasurecoded_default_datachunks: 2\nrook_cephobjectstore_erasurecoded_default_codingchunks: 1\nrook_cephobjectstore_failuredomain: host\nrook_cephobjectstore_default_port: 8081\nrook_cephobjectstore_preservepoolsondelete: true\nrook_cephobjectstores:\n - name: "{{ rook_cephobjectstore_default_name }}"\n spec:\n metadataPool:\n failureDomain: "{{ rook_cephobjectstore_failuredomain }}"\n replicated:\n size: "{{ rook_cephobjectstore_replicated_default_size }}"\n # erasureCoded:\n # dataChunks: "{{ rook_cephobjectstore_erasurecoded_default_datachunks }}"\n # codingChunks: "{{ rook_cephobjectstore_erasurecoded_default_codingchunks }}"\n dataPool:\n failureDomain: "{{ rook_cephobjectstore_failuredomain }}"\n replicated:\n size: "{{ rook_cephobjectstore_replicated_default_size }}"\n # erasureCoded:\n # dataChunks: "{{ rook_cephobjectstore_erasurecoded_default_datachunks }}"\n # codingChunks: "{{ rook_cephobjectstore_erasurecoded_default_codingchunks }}"\n preservePoolsOnDelete: "{{ rook_cephobjectstore_preservepoolsondelete }}"\n gateway:\n port: "{{ rook_cephobjectstore_default_port }}"\n resources: "{{ rook_resources_cephobjecstore }}"\n # securePort: 443\n # sslCertificateRef:\n instances: 1\n priorityClassName: system-cluster-critical\n placement: "{{ rook_placement_cephobjectstore }}"\n annotations: "{{ rook_annotations_cephobjecstore }}"\n storageClass:\n enabled: false\n'})}),"\n",(0,s.jsx)(o.h2,{id:"cephfs---cephfilesystem-crd",children:"Cephfs - CephFilesystem CRD"}),"\n",(0,s.jsxs)(o.p,{children:["Have a look at ",(0,s.jsx)(o.a,{href:"https://rook.io/docs/rook/latest/CRDs/Shared-Filesystem/ceph-filesystem-crd/",children:"CephFilesystem CRD Spec"})," for details on how to configure Cephfs."]}),"\n",(0,s.jsx)(o.pre,{children:(0,s.jsx)(o.code,{className:"language-yaml",metastring:'title="environments/rook/configuration.yml"',children:'rook_cephfilesystem_default_name: cephfs\nrook_cephfilesystem_replicated_default_size: 3\nrook_cephfilesystem_erasurecoded_default_datachunks: 2\nrook_cephfilesystem_erasurecoded_default_codingchunks: 1\nrook_cephfilesystem_default_metadatapool_parameters_compression_mode: none\nrook_cephfilesystem_default_datapool_parameters_compression_mode: none\nrook_cephfilesystems:\n - name: "{{ rook_cephfilesystem_default_name }}"\n spec:\n metadataPool:\n failureDomain: host\n # The metadata pool spec must use replication.\n replicated:\n size: "{{ rook_cephfilesystem_replicated_default_size }}"\n requireSafeReplicaSize: true\n parameters:\n compression_mode: "{{ rook_cephfilesystem_default_datapool_parameters_compression_mode }}"\n # target_size_ratio: ".5"\n dataPools:\n - failureDomain: host\n # The data pool spec can use replication or erasure coding.\n replicated:\n size: "{{ rook_cephfilesystem_replicated_default_size }}"\n requireSafeReplicaSize: true\n # erasureCoded:\n # dataChunks: "{{ rook_cephfilesystem_erasurecoded_default_datachunks }}"\n # codingChunks: "{{ rook_cephfilesystem_erasurecoded_default_codingchunks }}"\n name: data0\n parameters:\n compression_mode: "{{ rook_cephfilesystem_default_datapool_parameters_compression_mode }}"\n # target_size_ratio: ".5"\n metadataServer:\n activeCount: "{{ rook_mds_count }}"\n activeStandby: true\n resources: "{{ rook_resources_cephfilesystem }}"\n priorityClassName: system-cluster-critical"\n placement: "{{ rook_placement_cephfilesystem }}"\n annotations: "{{ rook_annotations_cephfilesystem }}"\n storageClass:\n enabled: false\n'})}),"\n",(0,s.jsx)(o.h2,{id:"extra-pools---cephblockpool-crd",children:"Extra pools - CephBlockPool CRD"}),"\n",(0,s.jsxs)(o.p,{children:["Extra pools can be defined via the ",(0,s.jsx)(o.code,{children:"rook_cephblockpools"})," parameter. Be sure to also include the default pools.\nThey will use the default values from the ",(0,s.jsx)(o.code,{children:"rook_cephblockpool_*"})," variables."]}),"\n",(0,s.jsxs)(o.p,{children:["Have a look at ",(0,s.jsx)(o.a,{href:"https://rook.io/docs/rook/latest-release/CRDs/Block-Storage/ceph-block-pool-crd/#spec",children:"CephBlockPool CRD Spec"})," for details."]}),"\n",(0,s.jsx)(o.pre,{children:(0,s.jsx)(o.code,{className:"language-yaml",metastring:'title="environments/rook/configuration.yml"',children:'rook_cephblockpool_replicated_default_size: 3\nrook_cephblockpool_erasurecoded_default_datachunks: 2\nrook_cephblockpool_erasurecoded_default_codingchunks: 1\nrook_cephblockpool_default_min_size: "0"\nrook_cephblockpool_default_pg_num: "128"\nrook_cephblockpools:\n # default pools\n - name: backups\n spec:\n failureDomain: host\n replicated:\n size: "{{ rook_cephblockpool_replicated_default_size }}"\n parameters:\n min_size: "{{ rook_cephblockpool_default_min_size }}"\n pg_num: "{{ rook_cephblockpool_default_pg_num }}"\n pgp_num: "{{ rook_cephblockpool_default_pg_num }}"\n storageClass:\n enabled: false\n - name: volumes\n spec:\n failureDomain: host\n replicated:\n size: "{{ rook_cephblockpool_replicated_default_size }}"\n parameters:\n min_size: "{{ rook_cephblockpool_default_min_size }}"\n pg_num: "{{ rook_cephblockpool_default_pg_num }}"\n pgp_num: "{{ rook_cephblockpool_default_pg_num }}"\n storageClass:\n enabled: false\n - name: images\n spec:\n failureDomain: host\n replicated:\n size: "{{ rook_cephblockpool_replicated_default_size }}"\n parameters:\n min_size: "{{ rook_cephblockpool_default_min_size }}"\n pg_num: "{{ rook_cephblockpool_default_pg_num }}"\n pgp_num: "{{ rook_cephblockpool_default_pg_num }}"\n storageClass:\n enabled: false\n - name: metrics\n spec:\n failureDomain: host\n replicated:\n size: "{{ rook_cephblockpool_replicated_default_size }}"\n parameters:\n min_size: "{{ rook_cephblockpool_default_min_size }}"\n pg_num: "{{ rook_cephblockpool_default_pg_num }}"\n pgp_num: "{{ rook_cephblockpool_default_pg_num }}"\n storageClass:\n enabled: false\n - name: vms\n spec:\n failureDomain: host\n replicated:\n size: "{{ rook_cephblockpool_replicated_default_size }}"\n parameters:\n min_size: "{{ rook_cephblockpool_default_min_size }}"\n pg_num: "{{ rook_cephblockpool_default_pg_num }}"\n pgp_num: "{{ rook_cephblockpool_default_pg_num }}"\n storageClass:\n enabled: false\n # extra pools\n - name: extra1\n spec:\n failureDomain: host\n replicated:\n size: "{{ rook_cephblockpool_replicated_default_size }}"\n parameters:\n min_size: "{{ rook_cephblockpool_default_min_size }}"\n pg_num: "{{ rook_cephblockpool_default_pg_num }}"\n pgp_num: "{{ rook_cephblockpool_default_pg_num }}"\n storageClass:\n enabled: false\n - name: extra2\n spec:\n failureDomain: host\n erasureCoded:\n dataChunks: "{{ rook_cephblockpool_erasurecoded_default_datachunks }}"\n codingChunks: "{{ rook_cephblockpool_erasurecoded_default_codingchunks }}" \n parameters:\n min_size: "{{ rook_cephblockpool_default_min_size }}"\n pg_num: "{{ rook_cephblockpool_default_pg_num }}"\n pgp_num: "{{ rook_cephblockpool_default_pg_num }}"\n storageClass:\n enabled: false\n'})}),"\n",(0,s.jsx)(o.h2,{id:"storage-configuration",children:"Storage configuration"}),"\n",(0,s.jsx)(o.admonition,{type:"info",children:(0,s.jsx)(o.p,{children:"In the default setup, no OSD will be deployed (better safe than sorry approach)."})}),"\n",(0,s.jsxs)(o.p,{children:["You have to pass a storage configuration via ",(0,s.jsx)(o.code,{children:"environments/rook/configuration.yml"}),"."]}),"\n",(0,s.jsxs)(o.p,{children:["Some useful ansible variables for the options from the ",(0,s.jsx)(o.a,{href:"https://rook.io/docs/rook/latest-release/CRDs/Cluster/ceph-cluster-crd/#storage-selection-settings",children:"Rook Storage Selection Settings"})," are available.\nIf you want complete flexibility, you can also use the ",(0,s.jsx)(o.code,{children:"rook_storage"})," variable which abstracts all settings from ",(0,s.jsx)(o.a,{href:"https://rook.io/docs/rook/latest-release/CRDs/Cluster/ceph-cluster-crd/#storage-selection-settings",children:"Rook Storage Selection Settings"}),"."]}),"\n",(0,s.jsx)(o.h3,{id:"deploy-osds-on-all-nodes-and-found-devices",children:"Deploy OSDs on all nodes and found devices"}),"\n",(0,s.jsx)(o.pre,{children:(0,s.jsx)(o.code,{className:"language-yaml",metastring:'title="environments/rook/configuration.yml"',children:"rook_storage_useallnodes: true\nrook_storage_usealldevices: true\n"})}),"\n",(0,s.jsx)(o.h3,{id:"deploy-osds-on-specific-nodes-and-devices-based-on-a-device-filter",children:"Deploy OSDs on specific nodes and devices based on a device filter"}),"\n",(0,s.jsx)(o.pre,{children:(0,s.jsx)(o.code,{className:"language-yaml",metastring:'title="environments/rook/configuration.yml"',children:'rook_storage_useallnodes: false\nrook_storage_usealldevices: false\nrook_storage_devicefilter: "^sd[b-c]"\nrook_storage_nodes:\n - name: "testbed-node-0"\n - name: "testbed-node-1"\n - name: "testbed-node-2"\n'})}),"\n",(0,s.jsx)(o.h3,{id:"deploy-osds-on-specific-nodes-and-devices-based-on-device-names",children:"Deploy OSDs on specific nodes and devices based on device names"}),"\n",(0,s.jsx)(o.pre,{children:(0,s.jsx)(o.code,{className:"language-yaml",metastring:'title="environments/rook/configuration.yml"',children:'rook_storage_useallnodes: false\nrook_storage_usealldevices: false\nrook_storage_nodes:\n - name: "testbed-node-0"\n devices:\n - name: "/dev/sdb"\n - name: "/dev/sdc"\n - name: "/dev/sde"\n - name: "testbed-node-1"\n devices:\n - name: "/dev/sdf"\n - name: "/dev/sdg"\n - name: "/dev/sdh"\n - name: "testbed-node-2"\n devices:\n - name: "/dev/sdi"\n - name: "/dev/sdj"\n - name: "/dev/sdk"\n'})}),"\n",(0,s.jsxs)(o.h3,{id:"flexible-approach-using-rook_storage",children:["Flexible approach using ",(0,s.jsx)(o.code,{children:"rook_storage"})]}),"\n",(0,s.jsx)(o.pre,{children:(0,s.jsx)(o.code,{className:"language-yaml",metastring:'title="environments/rook/configuration.yml"',children:'# do not use all nodes\nrook_storage_useallnodes: false\n# do not use all found devices\nrook_storage_usealldevices: false\nrook_storage_config_osdsperdevice: "1"\n# enable device encryption\nrook_storage_config_encrypteddevice: "true"\n# define a device filter where to create OSDs\nrook_storage_devicefilter: ""\n# name nodes where to create OSDs\nrook_storage_nodes: []\n# - name: "testbed-node-0"\n# - name: "testbed-node-1"\n# - name: "testbed-node-2"\nrook_storage:\n useAllNodes: "{{ rook_storage_useallnodes }}"\n useAllDevices: "{{ rook_storage_usealldevices }}"\n config:\n crushRoot: "custom-root" # specify a non-default root label for the CRUSH map\n metadataDevice: "md0" # specify a non-rotational storage so ceph-volume will use it as block db device of bluestore.\n databaseSizeMB: "1024" # uncomment if the disks are smaller than 100 GB\n osdsPerDevice: "{{ rook_storage_config_osdsperdevice }}" # this value can be overridden at the node or device level\n encryptedDevice: "{{ rook_storage_config_encrypteddevice }}" # the default value for this option is "false"\n # # Individual nodes and their config can be specified as well, but \'useAllNodes\' above must be set to false. Then, only the named\n # # nodes below will be used as storage resources. Each node\'s \'name\' field should match their \'kubernetes.io/hostname\' label.\n nodes:\n - name: "172.17.4.201"\n devices: # specific devices to use for storage can be specified for each node\n - name: "sdb"\n - name: "nvme01" # multiple osds can be created on high performance devices\n config:\n osdsPerDevice: "5"\n - name: "/dev/disk/by-id/ata-ST4000DM004-XXXX" # devices can be specified using full udev paths\n config: # configuration can be specified at the node level which overrides the cluster level config\n - name: "172.17.4.301"\n deviceFilter: "^sd."\n'})}),"\n",(0,s.jsx)(o.h3,{id:"encrypted-osds",children:"Encrypted OSDs"}),"\n",(0,s.jsx)(o.p,{children:"OSDs are encrypted by default. Rook creates a LUKS on LVM setup for this. Encryption keys are managed by Ceph, as usual."}),"\n",(0,s.jsx)(o.admonition,{type:"info",children:(0,s.jsx)(o.p,{children:"Provisioning LUKS on already existing logical volumes is not supported currently by Rook."})}),"\n",(0,s.jsxs)(o.p,{children:["Have a look at the ",(0,s.jsx)(o.a,{href:"https://docs.ceph.com/en/latest/ceph-volume/lvm/encryption/",children:"Ceph documentation on LVM encryption"})," and the ",(0,s.jsx)(o.a,{href:"https://rook.io/docs/rook/latest-release/CRDs/Cluster/ceph-cluster-crd/?h=#osd-configuration-settings",children:"Rook OSD Configuration Settings"})," for details."]}),"\n",(0,s.jsxs)(o.p,{children:["If you want complete flexibility, look into the details of the ",(0,s.jsx)(o.a,{href:"#helm-value-file",children:"Helm Value File"}),"."]}),"\n",(0,s.jsx)(o.h2,{id:"dashboard",children:"Dashboard"}),"\n",(0,s.jsx)(o.p,{children:"Password for the admin user of the Ceph dashboard is automatically generated by rook and can be retrieved like this:"}),"\n",(0,s.jsx)(o.pre,{children:(0,s.jsx)(o.code,{children:"kubectl -n rook-ceph get secret rook-ceph-dashboard-password -o jsonpath=\"{['data']['password']}\" | base64 --decode && echo\n"})}),"\n",(0,s.jsxs)(o.p,{children:["Have a look at the ",(0,s.jsx)(o.a,{href:"https://rook.io/docs/rook/latest-release/Storage-Configuration/Monitoring/ceph-dashboard/",children:"Rook Ceph Dashboard Documentation"})," for details."]}),"\n",(0,s.jsxs)(o.p,{children:["Some useful ansible variables for the options from the ",(0,s.jsx)(o.a,{href:"https://rook.io/docs/rook/latest-release/Storage-Configuration/Monitoring/ceph-dashboard/",children:"Rook Ceph Dashboard Documentation"})," are available."]}),"\n",(0,s.jsx)(o.h3,{id:"enable-dashboard-and-configure-ssl-and-ports",children:"Enable dashboard and configure ssl and ports"}),"\n",(0,s.jsx)(o.p,{children:"The Ceph dashboard is deployed by default and also an LoadBalancer Service is created in Kubernetes."}),"\n",(0,s.jsx)(o.pre,{children:(0,s.jsx)(o.code,{className:"language-yaml",metastring:'title="environments/rook/configuration.yml"',children:"rook_dashboard_enabled: true\nrook_dashboard_ssl: true\nrook_dashboard_port: 7000\nrook_dashboard_port_external: 443\n"})}),"\n",(0,s.jsx)(o.h2,{id:"rook-cluster-name",children:"Rook Cluster Name"}),"\n",(0,s.jsx)(o.p,{children:"The name that will be used internally for the Ceph cluster can be changed. Most commonly the name is the same as the namespace since multiple clusters are not supported in the same namespace."}),"\n",(0,s.jsx)(o.pre,{children:(0,s.jsx)(o.code,{className:"language-yaml",metastring:'title="environments/rook/configuration.yml"',children:"rook_cluster_name: rook-ceph\n"})}),"\n",(0,s.jsx)(o.h2,{id:"kubernetes-namespaces",children:"Kubernetes Namespaces"}),"\n",(0,s.jsx)(o.p,{children:"The Kubernetes namespace that will be created for the Rook cluster can be changed. The services, pods, and other resources created by the operator will be added to this namespace. The common scenario is to create a single Rook cluster. If multiple clusters are created, they must not have conflicting devices or host paths."}),"\n",(0,s.jsxs)(o.p,{children:["By default, both for the operator and the rook cluster, the namespace ",(0,s.jsx)(o.code,{children:"rook-ceph"})," is used."]}),"\n",(0,s.jsx)(o.pre,{children:(0,s.jsx)(o.code,{className:"language-yaml",metastring:'title="environments/rook/configuration.yml"',children:"rook_operator_namespace: rook-ceph\nrook_namespace: rook-ceph\n"})}),"\n",(0,s.jsx)(o.h2,{id:"number-and-placement-of-ceph-daemons",children:"Number and Placement of Ceph Daemons"}),"\n",(0,s.jsx)(o.p,{children:"The number and placement of Ceph daemons can be changed."}),"\n",(0,s.jsx)(o.pre,{children:(0,s.jsx)(o.code,{className:"language-yaml",metastring:'title="environments/rook/configuration.yml"',children:"rook_mon_count: 3\nrook_mds_count: 3\nrook_mgr_count: 3\n"})}),"\n",(0,s.jsxs)(o.p,{children:["Please read ",(0,s.jsx)(o.a,{href:"https://rook.io/docs/rook/latest-release/CRDs/Cluster/ceph-cluster-crd/#mon-settings",children:"Rook MON Settings"}),", ",(0,s.jsx)(o.a,{href:"https://rook.io/docs/rook/latest-release/CRDs/Cluster/ceph-cluster-crd/#mgr-settings",children:"Rook MGR Settings"})," and ",(0,s.jsx)(o.a,{href:"https://rook.io/docs/rook/latest-release/CRDs/Shared-Filesystem/ceph-filesystem-crd/#metadata-server-settings",children:"Rook MDS Settings"})," to understand which configurations make sense."]}),"\n",(0,s.jsx)(o.p,{children:"The following inventory groups are defined with defaults and can be used to control the node affinity regarding the indicated Ceph components:"}),"\n",(0,s.jsxs)(o.ul,{children:["\n",(0,s.jsx)(o.li,{children:(0,s.jsx)(o.code,{children:"rook-mds"})}),"\n",(0,s.jsx)(o.li,{children:(0,s.jsx)(o.code,{children:"rook-mgr"})}),"\n",(0,s.jsx)(o.li,{children:(0,s.jsx)(o.code,{children:"rook-mon"})}),"\n",(0,s.jsx)(o.li,{children:(0,s.jsx)(o.code,{children:"rook-osd"})}),"\n",(0,s.jsx)(o.li,{children:(0,s.jsx)(o.code,{children:"rook-rgw"})}),"\n"]}),"\n",(0,s.jsx)(o.p,{children:"To customise those inventory groups it is possible to do so in the following format:"}),"\n",(0,s.jsx)(o.pre,{children:(0,s.jsx)(o.code,{className:"language-ini",metastring:'title="inventory/20-roles"',children:"[rook-mds:children]\nceph-control\n\n[rook-mgr:children]\nceph-control\n\n[rook-mon:children]\nceph-control\n\n[rook-osd:children]\nceph-resource\n\n[rook-rgw:children]\nceph-control\n"})}),"\n",(0,s.jsx)(o.p,{children:"Nodes assigned to those groups will be labeled and then be utilised during the scheduling of the pods with a configuration like the following for each component:"}),"\n",(0,s.jsx)(o.pre,{children:(0,s.jsx)(o.code,{className:"language-yaml",metastring:'title="environments/rook/configuration.yml"',children:'nodeAffinity:\n requiredDuringSchedulingIgnoredDuringExecution:\n nodeSelectorTerms:\n - matchExpressions:\n - key: "node-role.osism.tech/{{ rook_placement_label_mon }}"\n operator: In\n values:\n - "true"\n'})}),"\n",(0,s.jsx)(o.p,{children:"TODO: Implement a way to cleanly relabel nodes.\nTODO: Implement reschedule after changing labels"}),"\n",(0,s.jsx)(o.h2,{id:"crash-collector",children:"Crash Collector"}),"\n",(0,s.jsxs)(o.p,{children:["The ",(0,s.jsx)(o.a,{href:"https://docs.ceph.com/en/quincy/mgr/crash/",children:"Ceph Crash Module"})," is enabled by default. You can also configure how long to retain the crash reports."]}),"\n",(0,s.jsx)(o.pre,{children:(0,s.jsx)(o.code,{className:"language-yaml",metastring:'title="environments/rook/configuration.yml"',children:"rook_crashcollector:\n disable: false\n daysToRetrain: 7\n"})}),"\n",(0,s.jsx)(o.h2,{id:"crash-collector-1",children:"Crash Collector"}),"\n",(0,s.jsxs)(o.p,{children:["The ",(0,s.jsx)(o.a,{href:"https://docs.ceph.com/en/quincy/mgr/crash/",children:"Ceph Crash Module"})," is enabled by default. You can also configure how long to retain the crash reports."]}),"\n",(0,s.jsx)(o.pre,{children:(0,s.jsx)(o.code,{className:"language-yaml",metastring:'title="environments/rook/configuration.yml"',children:"rook_crashcollector:\n disable: false\n daysToRetrain: 7\n"})}),"\n",(0,s.jsx)(o.h2,{id:"ceph-config",children:"Ceph Config"}),"\n",(0,s.jsx)(o.admonition,{type:"info",children:(0,s.jsx)(o.p,{children:"The Ceph Config feature is currently in an experimental state in the Rook project."})}),"\n",(0,s.jsxs)(o.p,{children:["Please read ",(0,s.jsx)(o.a,{href:"https://rook.github.io/docs/rook/latest-release/CRDs/Cluster/ceph-cluster-crd/#ceph-config",children:"Ceph Config"})," for details on how to use and what to expect from this feature."]}),"\n",(0,s.jsx)(o.pre,{children:(0,s.jsx)(o.code,{className:"language-yaml",metastring:'title="environments/rook/configuration.yml"',children:'rook_cephconfig:\n global:\n # All values must be quoted so they are considered a string in YAML\n osd_pool_default_size: "3"\n mon_warn_on_pool_no_redundancy: "false"\n osd_crush_update_on_start: "false"\n # Make sure to quote special characters\n "osd.*":\n osd_max_scrubs: "10"\n'})}),"\n",(0,s.jsx)(o.h2,{id:"second-ceph-cluster",children:"Second Ceph cluster"}),"\n",(0,s.jsx)(o.p,{children:"In theory, this is completely customizable by deploying multiple helm releases. No evaluation has been done so far, though and this is currently not implemented in OSISM."}),"\n",(0,s.jsx)(o.h2,{id:"helm-value-file",children:"Helm Value File"}),"\n",(0,s.jsxs)(o.p,{children:["The ",(0,s.jsx)(o.a,{href:"https://github.com/osism/ansible-collection-services/tree/main/roles/rook",children:"OSISM Rook role"})," is an opinionated and sane default configuration. If you reach the limits of what is customizable via ansible variables or have a very custom setup, you can pass a custom or additional [",(0,s.jsx)(o.code,{children:"values.yml"}),"](",(0,s.jsx)(o.a,{href:"https://github.com/osism/ansible-collection-services/blob/main/roles/rook/templates/01-helm-values-all.yml.j2",children:"https://github.com/osism/ansible-collection-services/blob/main/roles/rook/templates/01-helm-values-all.yml.j2"})," files or even any ",(0,s.jsx)(o.a,{href:"https://rook.io/docs/rook/latest-release/CRDs/specification/",children:"Rook CRD"})," to the role and it will be jinja2 templated and roled out to the kubernetes cluster."]}),"\n",(0,s.jsxs)(o.p,{children:["Just overwrite ",(0,s.jsx)(o.code,{children:"rook_configuration_directory"})," and place any ",(0,s.jsx)(o.code,{children:"*.yml.j2"})," files that you want to apply there."]}),"\n",(0,s.jsx)(o.pre,{children:(0,s.jsx)(o.code,{className:"language-yaml",metastring:'title="environments/rook/configuration.yml"',children:'rook_template_directory: "{{ configuration_directory }}/environments/rook/files"\n'})}),"\n",(0,s.jsxs)(o.ul,{children:["\n",(0,s.jsxs)(o.li,{children:["Helm ",(0,s.jsx)(o.code,{children:"values.yml"})," files need to be named ",(0,s.jsx)(o.code,{children:"*-helm-values-*.yml.j2"})]}),"\n",(0,s.jsxs)(o.li,{children:["custom CRDs need to be named ",(0,s.jsx)(o.code,{children:"*-CRD-*.yml.j2"})]}),"\n"]}),"\n",(0,s.jsx)(o.p,{children:"It makes sense to also include the default templates and change them (to e.g. use already existing ansible variables) add your custom settings on top or change them to fit your use cases."}),"\n",(0,s.jsxs)(o.p,{children:["Get the default templates from the ",(0,s.jsx)(o.code,{children:"osism-ansible"})," container or download them from github."]}),"\n",(0,s.jsx)(o.pre,{children:(0,s.jsx)(o.code,{children:'mkdir /opt/configuration/environments/rook/files\ncd /opt/configuration/environments/rook/files\nfor file in 01-helm-values-all.yml.j2 02-CRD-CephClient.yml.j2 ; do\n curl -O "https://raw.githubusercontent.com/osism/ansible-collection-services/main/roles/rook/templates/${file}"\ndone\n'})})]})}function h(e={}){const{wrapper:o}={...(0,r.a)(),...e.components};return o?(0,s.jsx)(o,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},1151:(e,o,n)=>{n.d(o,{Z:()=>i,a:()=>a});var s=n(7294);const r={},t=s.createContext(r);function a(e){const o=s.useContext(t);return s.useMemo((function(){return"function"==typeof e?e(o):{...o,...e}}),[o,e])}function i(e){let o;return o=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),s.createElement(t.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0f52743c.0bbcf24e.js b/assets/js/0f52743c.0bbcf24e.js deleted file mode 100644 index 77d42071b1..0000000000 --- a/assets/js/0f52743c.0bbcf24e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkosism=self.webpackChunkosism||[]).push([[6891],{8064:(e,o,t)=>{t.r(o),t.d(o,{assets:()=>d,contentTitle:()=>r,default:()=>l,frontMatter:()=>n,metadata:()=>u,toc:()=>a});var i=t(5893),s=t(1151);const n={sidebar_label:"Troubleshooting Guide",sidebar_position:40},r="Troubleshooting Guide",u={id:"guides/troubleshooting-guide/index",title:"Troubleshooting Guide",description:"\ud83d\udca1 The Troubleshooting Guide describe how to solve issues.",source:"@site/docs/guides/troubleshooting-guide/index.md",sourceDirName:"guides/troubleshooting-guide",slug:"/guides/troubleshooting-guide/",permalink:"/docs/guides/troubleshooting-guide/",draft:!1,unlisted:!1,editUrl:"https://github.com/osism/osism.github.io/tree/main/docs/guides/troubleshooting-guide/index.md",tags:[],version:"current",sidebarPosition:40,frontMatter:{sidebar_label:"Troubleshooting Guide",sidebar_position:40},sidebar:"tutorialSidebar",previous:{title:"Octavia",permalink:"/docs/guides/operations-guide/openstack/octavia"},next:{title:"Manager",permalink:"/docs/guides/troubleshooting-guide/manager"}},d={},a=[];function c(e){const o={h1:"h1",p:"p",...(0,s.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(o.h1,{id:"troubleshooting-guide",children:"Troubleshooting Guide"}),"\n",(0,i.jsx)(o.p,{children:"\ud83d\udca1 The Troubleshooting Guide describe how to solve issues."})]})}function l(e={}){const{wrapper:o}={...(0,s.a)(),...e.components};return o?(0,i.jsx)(o,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},1151:(e,o,t)=>{t.d(o,{Z:()=>u,a:()=>r});var i=t(7294);const s={},n=i.createContext(s);function r(e){const o=i.useContext(n);return i.useMemo((function(){return"function"==typeof e?e(o):{...o,...e}}),[o,e])}function u(e){let o;return o=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),i.createElement(n.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0f52743c.60ffc92e.js b/assets/js/0f52743c.60ffc92e.js new file mode 100644 index 0000000000..c5fec0e437 --- /dev/null +++ b/assets/js/0f52743c.60ffc92e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkosism=self.webpackChunkosism||[]).push([[6891],{8064:(e,o,i)=>{i.r(o),i.d(o,{assets:()=>d,contentTitle:()=>r,default:()=>c,frontMatter:()=>n,metadata:()=>u,toc:()=>a});var t=i(5893),s=i(1151);const n={sidebar_label:"Troubleshooting Guide",sidebar_position:40},r="Troubleshooting Guide",u={id:"guides/troubleshooting-guide/index",title:"Troubleshooting Guide",description:"\ud83d\udca1 The Troubleshooting Guide describe how to solve issues.",source:"@site/docs/guides/troubleshooting-guide/index.md",sourceDirName:"guides/troubleshooting-guide",slug:"/guides/troubleshooting-guide/",permalink:"/docs/guides/troubleshooting-guide/",draft:!1,unlisted:!1,editUrl:"https://github.com/osism/osism.github.io/tree/main/docs/guides/troubleshooting-guide/index.md",tags:[],version:"current",sidebarPosition:40,frontMatter:{sidebar_label:"Troubleshooting Guide",sidebar_position:40},sidebar:"tutorialSidebar",previous:{title:"Ceph via Rook (technical preview)",permalink:"/docs/guides/operations-guide/rook"},next:{title:"Manager",permalink:"/docs/guides/troubleshooting-guide/manager"}},d={},a=[];function l(e){const o={h1:"h1",p:"p",...(0,s.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(o.h1,{id:"troubleshooting-guide",children:"Troubleshooting Guide"}),"\n",(0,t.jsx)(o.p,{children:"\ud83d\udca1 The Troubleshooting Guide describe how to solve issues."})]})}function c(e={}){const{wrapper:o}={...(0,s.a)(),...e.components};return o?(0,t.jsx)(o,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},1151:(e,o,i)=>{i.d(o,{Z:()=>u,a:()=>r});var t=i(7294);const s={},n=t.createContext(s);function r(e){const o=t.useContext(n);return t.useMemo((function(){return"function"==typeof e?e(o):{...o,...e}}),[o,e])}function u(e){let o;return o=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),t.createElement(n.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/15cba8f7.8977d6f4.js b/assets/js/15cba8f7.8977d6f4.js new file mode 100644 index 0000000000..980f92b3ff --- /dev/null +++ b/assets/js/15cba8f7.8977d6f4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkosism=self.webpackChunkosism||[]).push([[8019],{1082:(e,i,t)=>{t.r(i),t.d(i,{assets:()=>c,contentTitle:()=>r,default:()=>u,frontMatter:()=>s,metadata:()=>d,toc:()=>a});var n=t(5893),o=t(1151);const s={sidebar_label:"Ceph",sidebar_position:20},r="Ceph",d={id:"guides/upgrade-guide/ceph",title:"Ceph",description:"See Rook Operations.",source:"@site/docs/guides/upgrade-guide/ceph.md",sourceDirName:"guides/upgrade-guide",slug:"/guides/upgrade-guide/ceph",permalink:"/docs/guides/upgrade-guide/ceph",draft:!1,unlisted:!1,editUrl:"https://github.com/osism/osism.github.io/tree/main/docs/guides/upgrade-guide/ceph.md",tags:[],version:"current",sidebarPosition:20,frontMatter:{sidebar_label:"Ceph",sidebar_position:20},sidebar:"tutorialSidebar",previous:{title:"Network",permalink:"/docs/guides/upgrade-guide/network"},next:{title:"Docker",permalink:"/docs/guides/upgrade-guide/docker"}},c={},a=[];function p(e){const i={a:"a",code:"code",h1:"h1",p:"p",pre:"pre",...(0,o.a)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(i.h1,{id:"ceph",children:"Ceph"}),"\n",(0,n.jsx)(i.pre,{children:(0,n.jsx)(i.code,{children:"osism apply ceph-rolling_update -e ireallymeanit=yes\nosism apply cephclient\n"})}),"\n",(0,n.jsx)(i.h1,{id:"ceph-via-rook-technical-preview",children:"Ceph via Rook (technical preview)"}),"\n",(0,n.jsxs)(i.p,{children:["See ",(0,n.jsx)(i.a,{href:"/docs/guides/operations-guide/rook",children:"Rook Operations"}),"."]})]})}function u(e={}){const{wrapper:i}={...(0,o.a)(),...e.components};return i?(0,n.jsx)(i,{...e,children:(0,n.jsx)(p,{...e})}):p(e)}},1151:(e,i,t)=>{t.d(i,{Z:()=>d,a:()=>r});var n=t(7294);const o={},s=n.createContext(o);function r(e){const i=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function d(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),n.createElement(s.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/15cba8f7.eb46ba30.js b/assets/js/15cba8f7.eb46ba30.js deleted file mode 100644 index ebfac42ab9..0000000000 --- a/assets/js/15cba8f7.eb46ba30.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkosism=self.webpackChunkosism||[]).push([[8019],{1082:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>p,frontMatter:()=>r,metadata:()=>d,toc:()=>u});var s=i(5893),n=i(1151);const r={sidebar_label:"Ceph",sidebar_position:20},o="Ceph",d={id:"guides/upgrade-guide/ceph",title:"Ceph",description:"",source:"@site/docs/guides/upgrade-guide/ceph.md",sourceDirName:"guides/upgrade-guide",slug:"/guides/upgrade-guide/ceph",permalink:"/docs/guides/upgrade-guide/ceph",draft:!1,unlisted:!1,editUrl:"https://github.com/osism/osism.github.io/tree/main/docs/guides/upgrade-guide/ceph.md",tags:[],version:"current",sidebarPosition:20,frontMatter:{sidebar_label:"Ceph",sidebar_position:20},sidebar:"tutorialSidebar",previous:{title:"Network",permalink:"/docs/guides/upgrade-guide/network"},next:{title:"Docker",permalink:"/docs/guides/upgrade-guide/docker"}},c={},u=[];function a(e){const t={code:"code",h1:"h1",pre:"pre",...(0,n.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h1,{id:"ceph",children:"Ceph"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{children:"osism apply ceph-rolling_update -e ireallymeanit=yes\nosism apply cephclient\n"})})]})}function p(e={}){const{wrapper:t}={...(0,n.a)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(a,{...e})}):a(e)}},1151:(e,t,i)=>{i.d(t,{Z:()=>d,a:()=>o});var s=i(7294);const n={},r=s.createContext(n);function o(e){const t=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function d(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:o(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/51d1621c.c8208468.js b/assets/js/51d1621c.c8208468.js new file mode 100644 index 0000000000..dce78137ba --- /dev/null +++ b/assets/js/51d1621c.c8208468.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkosism=self.webpackChunkosism||[]).push([[3189],{6788:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>l,contentTitle:()=>s,default:()=>u,frontMatter:()=>o,metadata:()=>a,toc:()=>c});var t=r(5893),i=r(1151);r(4866),r(5162);const o={sidebar_label:"Ceph via Rook (technical preview)",sidebar_position:51},s="Ceph via Rook (technical preview)",a={id:"guides/deploy-guide/services/rook",title:"Ceph via Rook (technical preview)",description:"This is a technical preview and not recommended for production use yet.",source:"@site/docs/guides/deploy-guide/services/rook.md",sourceDirName:"guides/deploy-guide/services",slug:"/guides/deploy-guide/services/rook",permalink:"/docs/guides/deploy-guide/services/rook",draft:!1,unlisted:!1,editUrl:"https://github.com/osism/osism.github.io/tree/main/docs/guides/deploy-guide/services/rook.md",tags:[],version:"current",sidebarPosition:51,frontMatter:{sidebar_label:"Ceph via Rook (technical preview)",sidebar_position:51},sidebar:"tutorialSidebar",previous:{title:"Ceph",permalink:"/docs/guides/deploy-guide/services/ceph"},next:{title:"OpenStack",permalink:"/docs/guides/deploy-guide/services/openstack"}},l={},c=[{value:"RGW service",id:"rgw-service",level:2},{value:"Cleanup",id:"cleanup",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,i.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"ceph-via-rook-technical-preview",children:"Ceph via Rook (technical preview)"}),"\n",(0,t.jsx)(n.admonition,{type:"warning",children:(0,t.jsx)(n.p,{children:"This is a technical preview and not recommended for production use yet."})}),"\n",(0,t.jsxs)(n.p,{children:["In OSISM it is also possible to integrate and use existing Ceph clusters. It\nis not necessary to deploy Ceph with OSISM. If Ceph is deployed with OSISM, it\nshould be noted that OSISM does not claim to provide all possible features of Ceph.\nCeph provided with OSISM is intended to provide the storage for Glance, Nova, Cinder\nand Manila. In a specific way that has been implemented by OSISM for years. It\nshould be checked in advance whether the way in OSISM the Ceph deployment and the\nprovided features are sufficient. If this is not the case, it is recommended to\ndeploy Ceph in a different way directly and independently of OSISM. For possible\nopen source projects, please refer to\n",(0,t.jsx)(n.a,{href:"https://docs.ceph.com/en/latest/cephadm/index.html",children:"cephadm"})," and\n",(0,t.jsx)(n.a,{href:"https://rook.io",children:"Rook"}),"."]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"Deploy services."}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["When using rook, all services are deployed via a single helm chart and at the same time. This could be altered by passing custom CRDs. See ",(0,t.jsx)(n.a,{href:"../../configuration-guide/rook",children:"Rook Configuration Guide"}),"."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Install ",(0,t.jsx)(n.a,{href:"/docs/guides/deploy-guide/services/kubernetes",children:"Kubernetes Cluster"})]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Deploy ",(0,t.jsx)(n.a,{href:"https://rook.io/docs/rook/latest/Helm-Charts/operator-chart/",children:"Rook Operator Helm Chart"})]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply rook-operator\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Deploy complete Rook Ceph Cluster"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply rook\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Copy ceph keyrings to kolla directories (if deploying OpenStack)"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply rook-fetch-keys\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.ol,{start:"2",children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Get ceph keyrings. This places the necessary keys in ",(0,t.jsx)(n.code,{children:"/opt/configuration"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply rook-fetch-keys\n"})}),"\n",(0,t.jsx)(n.p,{children:"After run, these keys must be permanently added to the configuration repository\nvia Git."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"environments/infrastructure/files/ceph/ceph.client.admin.keyring\nenvironments/kolla/files/overlays/gnocchi/ceph.client.gnocchi.keyring\nenvironments/kolla/files/overlays/nova/ceph.client.cinder.keyring\nenvironments/kolla/files/overlays/nova/ceph.client.nova.keyring\nenvironments/kolla/files/overlays/cinder/cinder-backup/ceph.client.cinder.keyring\nenvironments/kolla/files/overlays/cinder/cinder-backup/ceph.client.cinder-backup.keyring\nenvironments/kolla/files/overlays/cinder/cinder-volume/ceph.client.cinder.keyring\nenvironments/kolla/files/overlays/manila/ceph.client.manila.keyring\nenvironments/kolla/files/overlays/glance/ceph.client.glance.keyring\n"})}),"\n",(0,t.jsxs)(n.p,{children:["You can also overwrite the ",(0,t.jsx)(n.code,{children:"rook_cephclients"})," parameter to skip\nthese keys."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/rook/configuration.yml"',children:"rook_cephclients: {}\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"A Ceph client (a wrapper on the manager for entering the rook toolbox) can be deployed."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply cephclient\n"})}),"\n",(0,t.jsxs)(n.p,{children:["You have to make sure the correct ",(0,t.jsx)(n.a,{href:"/docs/guides/configuration-guide/rook#client",children:"Configuration Options for the Rook Ceph Client Wrapper"})," are net."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["After getting the Ceph Keyrings, the ",(0,t.jsx)(n.a,{href:"/docs/guides/deploy-guide/services/openstack",children:"OpenStack Deployment"})," can optionally be done."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"rgw-service",children:"RGW service"}),"\n",(0,t.jsxs)(n.p,{children:["Deployment of the Ceph RGW Service is enabled by default in rook. This is done by creating a default ",(0,t.jsx)(n.a,{href:"https://rook.io/docs/rook/latest-release/CRDs/Object-Storage/ceph-object-store-crd/",children:"CephObjectStore CRD"}),". How the Ceph RGW service can be deployed and integrated into OpenStack is described here."]}),"\n",(0,t.jsx)(n.admonition,{type:"info",children:(0,t.jsxs)(n.p,{children:["OpenStack integration between Keystone/Swift and Rook is currently missing upstream in Rook. Please have a look at ",(0,t.jsx)(n.a,{href:"https://github.com/orgs/SovereignCloudStack/projects/18/views/1?layout=board&pane=issue&itemId=63889060",children:"#1027"})," to get the current status of the integration in OSISM."]})}),"\n",(0,t.jsx)(n.h2,{id:"cleanup",children:"Cleanup"}),"\n",(0,t.jsx)(n.admonition,{type:"warning",children:(0,t.jsx)(n.p,{children:"This will permanently delete all your data in the Ceph Cluster. Be sure you know what you are doing before proceeding."})}),"\n",(0,t.jsxs)(n.p,{children:["If you want to cleanup/delete the whole cluster, you can do that by enabling ",(0,t.jsx)(n.code,{children:"rook_cleanup"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/rook/configuration.yml"',children:"rook_cleanup: true\n"})}),"\n",(0,t.jsxs)(n.p,{children:["And running the ",(0,t.jsx)(n.code,{children:"rook-cleanup"})," role."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply rook-cleanup\n"})})]})}function u(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},5162:(e,n,r)=>{r.d(n,{Z:()=>s});r(7294);var t=r(6905);const i={tabItem:"tabItem_Ymn6"};var o=r(5893);function s(e){let{children:n,hidden:r,className:s}=e;return(0,o.jsx)("div",{role:"tabpanel",className:(0,t.Z)(i.tabItem,s),hidden:r,children:n})}},4866:(e,n,r)=>{r.d(n,{Z:()=>j});var t=r(7294),i=r(6905),o=r(2466),s=r(6550),a=r(469),l=r(1980),c=r(7392),d=r(812);function u(e){return t.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,t.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function h(e){const{values:n,children:r}=e;return(0,t.useMemo)((()=>{const e=n??function(e){return u(e).map((e=>{let{props:{value:n,label:r,attributes:t,default:i}}=e;return{value:n,label:r,attributes:t,default:i}}))}(r);return function(e){const n=(0,c.l)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[n,r])}function p(e){let{value:n,tabValues:r}=e;return r.some((e=>e.value===n))}function m(e){let{queryString:n=!1,groupId:r}=e;const i=(0,s.k6)(),o=function(e){let{queryString:n=!1,groupId:r}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!r)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return r??null}({queryString:n,groupId:r});return[(0,l._X)(o),(0,t.useCallback)((e=>{if(!o)return;const n=new URLSearchParams(i.location.search);n.set(o,e),i.replace({...i.location,search:n.toString()})}),[o,i])]}function f(e){const{defaultValue:n,queryString:r=!1,groupId:i}=e,o=h(e),[s,l]=(0,t.useState)((()=>function(e){let{defaultValue:n,tabValues:r}=e;if(0===r.length)throw new Error("Docusaurus error: the component requires at least one children component");if(n){if(!p({value:n,tabValues:r}))throw new Error(`Docusaurus error: The has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${r.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const t=r.find((e=>e.default))??r[0];if(!t)throw new Error("Unexpected error: 0 tabValues");return t.value}({defaultValue:n,tabValues:o}))),[c,u]=m({queryString:r,groupId:i}),[f,v]=function(e){let{groupId:n}=e;const r=function(e){return e?`docusaurus.tab.${e}`:null}(n),[i,o]=(0,d.Nk)(r);return[i,(0,t.useCallback)((e=>{r&&o.set(e)}),[r,o])]}({groupId:i}),g=(()=>{const e=c??f;return p({value:e,tabValues:o})?e:null})();(0,a.Z)((()=>{g&&l(g)}),[g]);return{selectedValue:s,selectValue:(0,t.useCallback)((e=>{if(!p({value:e,tabValues:o}))throw new Error(`Can't select invalid tab value=${e}`);l(e),u(e),v(e)}),[u,v,o]),tabValues:o}}var v=r(2389);const g={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var y=r(5893);function b(e){let{className:n,block:r,selectedValue:t,selectValue:s,tabValues:a}=e;const l=[],{blockElementScrollPositionUntilNextRender:c}=(0,o.o5)(),d=e=>{const n=e.currentTarget,r=l.indexOf(n),i=a[r].value;i!==t&&(c(n),s(i))},u=e=>{let n=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const r=l.indexOf(e.currentTarget)+1;n=l[r]??l[0];break}case"ArrowLeft":{const r=l.indexOf(e.currentTarget)-1;n=l[r]??l[l.length-1];break}}n?.focus()};return(0,y.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,i.Z)("tabs",{"tabs--block":r},n),children:a.map((e=>{let{value:n,label:r,attributes:o}=e;return(0,y.jsx)("li",{role:"tab",tabIndex:t===n?0:-1,"aria-selected":t===n,ref:e=>l.push(e),onKeyDown:u,onClick:d,...o,className:(0,i.Z)("tabs__item",g.tabItem,o?.className,{"tabs__item--active":t===n}),children:r??n},n)}))})}function k(e){let{lazy:n,children:r,selectedValue:i}=e;const o=(Array.isArray(r)?r:[r]).filter(Boolean);if(n){const e=o.find((e=>e.props.value===i));return e?(0,t.cloneElement)(e,{className:"margin-top--md"}):null}return(0,y.jsx)("div",{className:"margin-top--md",children:o.map(((e,n)=>(0,t.cloneElement)(e,{key:n,hidden:e.props.value!==i})))})}function x(e){const n=f(e);return(0,y.jsxs)("div",{className:(0,i.Z)("tabs-container",g.tabList),children:[(0,y.jsx)(b,{...n,...e}),(0,y.jsx)(k,{...n,...e})]})}function j(e){const n=(0,v.Z)();return(0,y.jsx)(x,{...e,children:u(e.children)},String(n))}},1151:(e,n,r)=>{r.d(n,{Z:()=>a,a:()=>s});var t=r(7294);const i={},o=t.createContext(i);function s(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6235e5b8.79ce735b.js b/assets/js/6235e5b8.79ce735b.js deleted file mode 100644 index 20ecfcb855..0000000000 --- a/assets/js/6235e5b8.79ce735b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkosism=self.webpackChunkosism||[]).push([[9705],{5675:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>a,contentTitle:()=>c,default:()=>u,frontMatter:()=>d,metadata:()=>o,toc:()=>h});var n=s(5893),l=s(1151),i=s(4866),r=s(5162);const d={sidebar_label:"Testbed Guide"},c="Testbed",o={id:"guides/other-guides/testbed",title:"Testbed",description:"With the OSISM Testbed, it is possible to run a full Sovereign Cloud Stack",source:"@site/docs/guides/other-guides/testbed.mdx",sourceDirName:"guides/other-guides",slug:"/guides/other-guides/testbed",permalink:"/docs/guides/other-guides/testbed",draft:!1,unlisted:!1,editUrl:"https://github.com/osism/osism.github.io/tree/main/docs/guides/other-guides/testbed.mdx",tags:[],version:"current",frontMatter:{sidebar_label:"Testbed Guide"},sidebar:"tutorialSidebar",previous:{title:"Style Guide",permalink:"/docs/guides/other-guides/style-guide"},next:{title:"References",permalink:"/docs/references/"}},a={},h=[{value:"Requirements",id:"requirements",level:2},{value:"Cloud access",id:"cloud-access",level:3},{value:"Cloud resources",id:"cloud-resources",level:3},{value:"Software",id:"software",level:3},{value:"Deployment",id:"deployment",level:2},{value:"Usage",id:"usage",level:2},{value:"Custom CA",id:"custom-ca",level:3},{value:"VPN access",id:"vpn-access",level:3},{value:"Wireguard",id:"wireguard",level:4},{value:"sshuttle",id:"sshuttle",level:4},{value:"Static entries in /etc/hosts",id:"static-entries-in-etchosts",level:3},{value:"Webinterfaces",id:"webinterfaces",level:3},{value:"Authentication with OIDC",id:"authentication-with-oidc",level:3},{value:"OpenStack web dashboard (Horizon) login via OIDC",id:"openstack-web-dashboard-horizon-login-via-oidc",level:4},{value:"OpenStack web dashboard (Horizon) logout",id:"openstack-web-dashboard-horizon-logout",level:4},{value:"Usage of the OpenStack CLI",id:"usage-of-the-openstack-cli",level:4},{value:"OpenStack CLI operations with OpenID Connect password",id:"openstack-cli-operations-with-openid-connect-password",level:4},{value:"OpenStack CLI token issue with OpenID Connect",id:"openstack-cli-token-issue-with-openid-connect",level:4},{value:"Advanced Usage",id:"advanced-usage",level:2},{value:"External API",id:"external-api",level:3},{value:"Change versions",id:"change-versions",level:3},{value:"Deploy services",id:"deploy-services",level:3},{value:"Upgrade services",id:"upgrade-services",level:3},{value:"Troubleshooting",id:"troubleshooting",level:2},{value:"Ansible errors",id:"ansible-errors",level:3},{value:"Unsupported locale setting",id:"unsupported-locale-setting",level:3},{value:"Appendix",id:"appendix",level:2},{value:"Configuration",id:"configuration",level:3},{value:"Variables",id:"variables",level:4},{value:"Overrides",id:"overrides",level:4},{value:"Customisations",id:"customisations",level:4},{value:"Notes",id:"notes",level:3},{value:"Supported releases",id:"supported-releases",level:3},{value:"Included services",id:"included-services",level:3},{value:"Infrastructure",id:"infrastructure",level:4},{value:"OpenStack",id:"openstack",level:4},{value:"Makefile reference",id:"makefile-reference",level:3},{value:"CI jobs",id:"ci-jobs",level:3}];function x(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,l.a)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h1,{id:"testbed",children:"Testbed"}),"\n",(0,n.jsxs)(t.p,{children:["With the OSISM Testbed, it is possible to run a full Sovereign Cloud Stack\ndeployment on an existing OpenStack environment such as Cleura or ",(0,n.jsx)(t.a,{href:"https://regio.digital",children:"REGIO.cloud"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:["OSISM is the reference implementation for the Infrastructure as a Service (IaaS) layer in the\n",(0,n.jsx)(t.a,{href:"https://scs.community",children:"Sovereign Cloud Stack"})," (SCS) project. The OSISM Testbed is therefore\nused in the SCS project to test and work on the Instrastructure as a Service layer."]}),"\n",(0,n.jsx)(t.p,{children:"The OSISM Testbed is intended as a playground. Further services and integration will\nbe added over time. A increasing number of best practices and experiences from the productive\ndeployments will be included here in the future. It will become more production-like\nover time. However, at no point does it claim to represent a production setup exactly."}),"\n",(0,n.jsx)(t.h2,{id:"requirements",children:"Requirements"}),"\n",(0,n.jsx)(t.h3,{id:"cloud-access",children:"Cloud access"}),"\n",(0,n.jsx)(t.p,{children:"The usual prerequisite is to have an account on one of the supported OpenStack cloud providers.\nAs the OSISM Testbed also virtualizes systems itself, the OpenStack cluster should provide\nthe capabilities for nested virtualization."}),"\n",(0,n.jsx)(t.p,{children:"It is not part of this guide to describe the registration with the individual cloud\nproviders. Please contact the respective cloud provider for this."}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Product"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Provider"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Profile name"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Note"})]})}),(0,n.jsxs)(t.tbody,{children:[(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Cleura"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Cleura"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"cleura"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Fuga Cloud"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"FUGA"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"fuga"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"HuaweiCloud"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"HuaweiCloud"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"huaweicloud"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"OVH"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"OVH"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"ovh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"OpenTelekomCloud"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"T-Systems"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"otc"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"pluscloud open"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"plusserver"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"pluscloudopen"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"pluscloud SCS Test"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"plusserver"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"gx-scs"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"REGIO.cloud"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"OSISM"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"regiocloud"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"REGIO.cloud"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"OSISM"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"regio-fast"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"boot from NVMe SSD backed volumes"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Wavestack"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"noris network"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"wavestack"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]})]})]}),"\n",(0,n.jsxs)(t.p,{children:["For each cloud provider listed in the table, a predefined profile is available in the\n",(0,n.jsx)(t.code,{children:"terraform/environments"})," directory. This profile contains the name of the public\nnetwork, which flavors to use, etc."]}),"\n",(0,n.jsxs)(t.p,{children:["Here is an example from the profile for ",(0,n.jsx)(t.a,{href:"https://regio.digital",children:"REGIO.cloud"}),"."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-text",children:'flavor_manager = "SCS-4V-16-50"\nflavor_node = "SCS-8V-32-50"\nvolume_type = "ssd"\nimage = "Ubuntu 22.04"\nimage_node = "Ubuntu 22.04"\npublic = "public"\navailability_zone = "nova"\nvolume_availability_zone = "nova"\nnetwork_availability_zone = "nova"\n'})}),"\n",(0,n.jsx)(t.h3,{id:"cloud-resources",children:"Cloud resources"}),"\n",(0,n.jsx)(t.p,{children:"The OSISM Testbed requires at least the following project quota when using the default flavors:"}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Quantity"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Resource"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Note"})]})}),(0,n.jsxs)(t.tbody,{children:[(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"4"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Instances"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"28 VCPUs + 112 GByte RAM (3 modes, 1 manager)"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"9"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Volumes"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"90 GByte volume storage"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"1"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Floating IP"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"1"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Keypair"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"3"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Security group"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"16"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Security group rules"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"1"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Network"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"1"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Subetwork"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"6"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Ports"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"1"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Router"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]})]})]}),"\n",(0,n.jsx)(t.h3,{id:"software",children:"Software"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.code,{children:"make"})," must be installed on the system"]}),"\n",(0,n.jsxs)(t.li,{children:["Wireguard or ",(0,n.jsx)(t.code,{children:"sshuttle"})," must be installed on your system for VPN access"]}),"\n",(0,n.jsxs)(t.li,{children:["Python must be installed, the Python version used must be at least 3.10, otherwise\nthe current Ansible release cannot be used (details in the\n",(0,n.jsx)(t.a,{href:"https://docs.ansible.com/ansible/latest/reference_appendices/release_and_maintenance.html#ansible-core-support-matrix",children:"Ansible support matrix"}),")"]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.code,{children:"python3-venv"})," must be installed for managing Python dependencies like Ansible"]}),"\n"]}),"\n",(0,n.jsx)(t.h2,{id:"deployment",children:"Deployment"}),"\n",(0,n.jsx)(t.p,{children:"This section describes step by step how to deploy the OSISM Testbed."}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"Request access from the administrator of the respective cloud or get access to an OpenStack cloud."}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:["Clone the ",(0,n.jsx)(t.a,{href:"https://github.com/osism/testbed",children:"osism/testbed"})," repository."]}),"\n",(0,n.jsx)(t.p,{children:"The repository can also be cloned to any other location."}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"mkdir -p ~/src/github.com/osism\ngit clone https://github.com/osism/testbed ~/src/github.com/osism/testbed\ncd ~/src/github.com/osism/testbed\n"})}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"Configure your cloud access profile"}),"\n",(0,n.jsxs)(t.p,{children:["The access data for the cloud provider used is stored in ",(0,n.jsx)(t.code,{children:"terraform/clouds.yaml"})," and (optionally)\nin ",(0,n.jsx)(t.code,{children:"terraform/secure.yaml"})," (same structure, if you want to store credentials on a separate place)."]}),"\n",(0,n.jsxs)(t.p,{children:["In file ",(0,n.jsx)(t.a,{href:"https://github.com/osism/testbed/blob/main/terraform/clouds.yaml.sample",children:"terraform/clouds.yaml.sample"}),"\nyou will find examples of typical setups. Settings that are identical for all users of a cloud can be defined\ncentrally via the profiles of the file\n",(0,n.jsx)(t.a,{href:"https://github.com/osism/testbed/blob/main/terraform/clouds-public.yaml",children:"terraform/clouds-public.yaml"}),".\nYou can reference these settings by using the ",(0,n.jsx)(t.code,{children:"profile"})," parameter in cloud-specific\ndefinition in ",(0,n.jsx)(t.code,{children:"terraform/clouds.yaml"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:["The user specific settings of the ",(0,n.jsx)(t.code,{children:"clouds.yaml"})," file are provided by the cloud provider. Please check the\ndocumentation of the cloud provider you are using or their support for details."]}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.a,{href:"https://regio.digital",children:"REGIO.cloud"})," is used as an example here. The cloud name in ",(0,n.jsx)(t.code,{children:"clouds.yaml"}),"\nand the environment name (value of ",(0,n.jsx)(t.code,{children:"ENVIRONMENT"}),") are ",(0,n.jsx)(t.code,{children:"regiocloud"})," in this case. It is important that\nthe name of the cloud in ",(0,n.jsx)(t.code,{children:"clouds.yaml"})," matches the name of the environment to be used. The names must\nbe identical. It is currently not possible to name the cloud ",(0,n.jsx)(t.code,{children:"regiocloud-123"})," in ",(0,n.jsx)(t.code,{children:"clouds.yaml"})," if the\nenvironment is ",(0,n.jsx)(t.code,{children:"regiocloud"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:["If another cloud is used, replace ",(0,n.jsx)(t.code,{children:"regiocloud"})," with the respective profile name ",(0,n.jsx)(t.a,{href:"#cloud-access",children:"from the table above"}),"."]}),"\n",(0,n.jsxs)(i.Z,{children:[(0,n.jsxs)(r.Z,{value:"testbed-cloud-access-with-app-credentials",label:"Application Credentials",children:[(0,n.jsxs)(t.p,{children:["The use of application credentials is preferred. This way it is not necessary to store\ndetails like username, project name or sensitive information like the password in the\n",(0,n.jsx)(t.code,{children:"clouds.yaml"})," file."]}),(0,n.jsxs)(t.p,{children:["The application credentials can be found in Horizon under ",(0,n.jsx)(t.strong,{children:"Identity"}),". Use ",(0,n.jsx)(t.code,{children:"OSISM Testbed"})," as\nname and click ",(0,n.jsx)(t.code,{children:"Create Application Credential"}),"."]}),(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-yaml",metastring:'title="terraform/clouds.yaml"',children:'clouds:\n regiocloud:\n profile: regiocloud\n auth:\n application_credential_id: ID\n application_credential_secret: SECRET\n auth_type: "v3applicationcredential"\n'})}),(0,n.jsxs)(t.p,{children:["If you want to make use of ",(0,n.jsx)(t.code,{children:"terraform/secure.yaml"})," add your application credential secret there\ninstead of ",(0,n.jsx)(t.code,{children:"terraform/clouds.yaml"}),"."]}),(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-yaml",metastring:'title="terraform/secure.yaml"',children:"clouds:\n regiocloud:\n auth:\n application_credential_secret: SECRET\n"})})]}),(0,n.jsxs)(r.Z,{value:"testbed-cloud-access-with-username-password",label:"Username/Password",children:[(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-yaml",metastring:'title="terraform/clouds.yaml"',children:"clouds:\n regiocloud:\n profile: regiocloud\n auth:\n project_name: PROJECT\n username: USERNAME\n project_domain_name: DOMAIN\n user_domain_name: DOMAIN\n"})}),(0,n.jsxs)(t.p,{children:["If you want to make use of ",(0,n.jsx)(t.code,{children:"terraform/secure.yaml"})," add your password there instead of ",(0,n.jsx)(t.code,{children:"terraform/clouds.yaml"}),"."]}),(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-yaml",metastring:'title="terraform/secure.yaml"',children:"clouds:\n regiocloud:\n auth:\n password: PASSWORD\n"})})]})]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"Prepare the deployment."}),"\n",(0,n.jsxs)(t.p,{children:["The versions of Ansible and ",(0,n.jsx)(t.a,{href:"https://opentofu.org",children:"OpenTofu"})," are managed\nautomatically and necessary dependencies are cloned."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"make prepare\n"})}),"\n",(0,n.jsxs)(t.p,{children:["If any error occurs during preparation and you want to run the preparation\nagain, it is important to run ",(0,n.jsx)(t.code,{children:"make wipe-local-install"})," first. Otherwise the\npreparation will not be redone completely and necessary parts will be missing\nlater on."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"Create the infrastructure with OpenTofu."}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"make ENVIRONMENT=regiocloud create\n"})}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"Deploy the OSISM manager and bootstrap all nodes."}),"\n",(0,n.jsxs)(i.Z,{children:[(0,n.jsx)(r.Z,{value:"testbed-deploy-latst",label:"Deploy latest manager version",children:(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"make ENVIRONMENT=regiocloud manager\n"})})}),(0,n.jsx)(r.Z,{value:"testbed-deploy-stable",label:"Deploy a stable manager version",children:(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"make ENVIRONMENT=regiocloud VERSION_MANAGER=7.0.3 manager\n"})})})]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"After the bootstrap, you can log in to the manager via SSH."}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"make ENVIRONMENT=regiocloud login\n"})}),"\n",(0,n.jsx)(t.p,{children:"Yo can log in to the nodes of the cluster via the manager."}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"osism console testbed-node-0\n"})}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"Deploy all services."}),"\n",(0,n.jsxs)(i.Z,{children:[(0,n.jsxs)(r.Z,{value:"testbed-deploy-multi-steps",label:"Deployment in single steps",children:[(0,n.jsxs)(t.p,{children:["It is also possible to deploy the services step by step on the\nmanager. To do this, first log in to the manager with ",(0,n.jsx)(t.code,{children:"make ENVIRONMENT=regiocloud login"}),"\nand then execute the deploy scripts one after the other. It is recommended to do this\nwithin a screen session."]}),(0,n.jsx)(t.p,{children:"Deploying the services takes some time and depends on how much bandwidth is available,\nhow the instances are equipped, etc. 90-120 minutes is not unusual when Ceph and OpenStack\nare fully deployed."}),(0,n.jsxs)(t.p,{children:["To speed up the Ansible playbooks, ",(0,n.jsx)(t.a,{href:"https://ara.recordsansible.org",children:"ARA"})," can be disabled. This\nis done by executing ",(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/disable-ara.sh"}),". Run this script ",(0,n.jsx)(t.strong,{children:"before"})," the deployment scripts.\nAfterwards no more logs are available in the ARA web\ninterface. To re-enable ARA use ",(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/enable-ara.sh"}),"."]}),(0,n.jsxs)(t.p,{children:["There is also the option of pre-population of images with ",(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/pull-images.sh"}),"\nso that deployments do not have to be lengthy. Run this script ",(0,n.jsx)(t.strong,{children:"before"})," the deployment scripts."]}),(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"/opt/configuration/scripts/deploy/001-helper-services.sh\n/opt/configuration/scripts/deploy/005-kubernetes.sh\n/opt/configuration/scripts/deploy/100-ceph-services-basic.sh\n/opt/configuration/scripts/deploy/200-infrastructure-services-basic.sh\n/opt/configuration/scripts/deploy/300-openstack-services-basic.sh\n/opt/configuration/scripts/deploy/400-monitoring-services.sh\n"})}),(0,n.jsxs)(t.p,{children:["Prepare OpenStack resources like public network, flavors and images by running\n",(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/bootstrap.sh"}),". Run this script ",(0,n.jsx)(t.strong,{children:"after"})," the deployment scripts."]}),(0,n.jsxs)(t.admonition,{type:"info",children:[(0,n.jsxs)(t.p,{children:["If you only want to deploy the monitoring services with ",(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/deploy/400-monitoring-services.sh"}),",\na few dependencies must be deployed first. You can then use the monitoring services without having to install a\ncomplete OpenStack & Ceph environment."]}),(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"osism apply common\nosism apply loadbalancer\nosism apply opensearch\nosism apply mariadb\n"})})]})]}),(0,n.jsxs)(r.Z,{value:"testbed-deploy-single-step",label:"Deployment of all services",children:[(0,n.jsx)(t.p,{children:"In this single step deployment, Ceph, OpenStack and all necessary\ninfrastructure services (MariaDB, RabbitMQ, ...) are deployed.\nDepending on the cloud, the deployment will take some time. Up to two hours is not unusual."}),(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"make ENVIRONMENT=regiocloud deploy\n"})})]})]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:["If you want to verify the deployment with ",(0,n.jsx)(t.a,{href:"https://opendev.org/openinfra/refstack",children:"refstack"})," run\n",(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/check.sh"}),". This step will take some time and is optional."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"The machine images required for the use of Kubernetes Cluster API and the amphora driver of OpenStack Octavia\nservice are not provided by default to save resources on the OSISM Testbed and improve deployment time.\nThese can be provisioned if required."}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"/opt/configuration/scripts/bootstrap/301-openstack-octavia-amhpora-image.sh\n/opt/configuration/scripts/bootstrap/302-openstack-k8s-clusterapi-images.sh\n"})}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"If you want you can create a test project with a test user after login. It also\ncreates an instance with a volume attached to a network with a router. This step is optional."}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"osism apply --environment openstack test\n"})}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"When the OSISM Testbed is no longer needed, it can be deleted."}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"make ENVIRONMENT=regiocloud clean\n"})}),"\n"]}),"\n"]}),"\n",(0,n.jsx)(t.h2,{id:"usage",children:"Usage"}),"\n",(0,n.jsx)(t.p,{children:"Deployment must be completed at this point."}),"\n",(0,n.jsx)(t.h3,{id:"custom-ca",children:"Custom CA"}),"\n",(0,n.jsxs)(t.p,{children:["The OSISM Testbed deployment currently uses hostnames in the domain ",(0,n.jsx)(t.code,{children:"testbed.osism.xyz"}),". This is a real domain\nand we provide the DNS records matching the addresses used in the OSISM Testbed, so that once you connect to your testbed via a direct\nlink or Wireguard, you can access hosts and servers by their hostname (e.g. ",(0,n.jsx)(t.code,{children:"ssh testbed-manager.testbed.osism.xyz"}),")."]}),"\n",(0,n.jsxs)(t.p,{children:["We also provide a wildcard TLS certificate signed by a custom CA for ",(0,n.jsx)(t.code,{children:"testbed.osism.xyz"})," and ",(0,n.jsx)(t.code,{children:"*.testbed.osism.xyz"}),".\nThis CA is always used for each testbed. The CA is not regenerated and it is not planned to change this for the next 10 years."]}),"\n",(0,n.jsxs)(t.p,{children:["In order for these certificates to be recognized locally as valid, the CA\n",(0,n.jsx)(t.a,{href:"https://raw.githubusercontent.com/osism/testbed/main/environments/kolla/certificates/ca/testbed.crt",children:"environments/kolla/certificates/ca/testbed.crt"}),"\nmust be imported locally."]}),"\n",(0,n.jsx)(t.h3,{id:"vpn-access",children:"VPN access"}),"\n",(0,n.jsx)(t.h4,{id:"wireguard",children:"Wireguard"}),"\n",(0,n.jsxs)(t.p,{children:["Install wireguard on your workstation, if you have not done this before. For instructions how to do\nit on your workstation, please have a look on the documentation of your used distribution. The\nwireguard documentation you will find ",(0,n.jsx)(t.a,{href:"https://www.wireguard.com",children:"here"}),"."]}),"\n",(0,n.jsx)(t.p,{children:"Start the wireguard tunnel.\n(Press CTRL+c to keep the tunnel running forever. The make target also launches a browser tab with references to all services)"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"make vpn-wireguard ENVIRONMENT=regiocloud\n"})}),"\n",(0,n.jsx)(t.p,{children:"If you want to connect to the OSISM Testbed from multiple clients, change the client IP\naddress in the downloaded configuration file to be different on each client."}),"\n",(0,n.jsxs)(t.p,{children:["If you only want to download the Wireguard configuration, you can use the ",(0,n.jsx)(t.code,{children:"vpn-wireguard-config"}),"\ntarget. The configuration is then available in the file ",(0,n.jsx)(t.code,{children:"wg-testbed-regiocloud.conf"}),", for example."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"make vpn-wireguard-config ENVIRONMENT=regiocloud\n"})}),"\n",(0,n.jsx)(t.h4,{id:"sshuttle",children:"sshuttle"}),"\n",(0,n.jsxs)(t.p,{children:["If you do not want to use Wireguard you can also work with ",(0,n.jsx)(t.a,{href:"https://github.com/sshuttle/sshuttle",children:"sshuttle"}),"."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"make vpn-sshuttle ENVIRONMENT=regiocloud\nkillall sshuttle\n"})}),"\n",(0,n.jsxs)(t.h3,{id:"static-entries-in-etchosts",children:["Static entries in ",(0,n.jsx)(t.code,{children:"/etc/hosts"})]}),"\n",(0,n.jsxs)(t.p,{children:["If you are unable to access the following domains, you can customize your local ",(0,n.jsx)(t.code,{children:"/etc/hosts"}),"\nwith the following static entries. This may be necessary, for example, if you use Pi-hole and\nall DNS entries from a public DNS with a non-public IP address are filtered."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"# OSISM Testbed hosts\n192.168.16.5 ara.testbed.osism.xyz ara\n192.168.16.5 cgit.testbed.osism.xyz cgit\n192.168.16.5 flower.testbed.osism.xyz flower\n192.168.16.5 homer.testbed.osism.xyz homer\n192.168.16.5 netbox.testbed.osism.xyz netbox\n192.168.16.5 testbed-manager.testbed.osism.xyz testbed-manager\n192.168.16.5 nexus.testbed.osism.xyz nexus\n192.168.16.5 phpmyadmin.testbed.osism.xyz phpmyadmin\n192.168.16.9 api-int.testbed.osism.xyz api-int\n192.168.16.10 testbed-node-0.testbed.osism.xyz testbed-node-0\n192.168.16.11 testbed-node-1.testbed.osism.xyz testbed-node-1\n192.168.16.12 testbed-node-2.testbed.osism.xyz testbed-node-2\n192.168.16.13 testbed-node-3.testbed.osism.xyz testbed-node-3\n192.168.16.14 testbed-node-4.testbed.osism.xyz testbed-node-4\n192.168.16.15 testbed-node-5.testbed.osism.xyz testbed-node-5\n192.168.16.16 testbed-node-6.testbed.osism.xyz testbed-node-6\n192.168.16.17 testbed-node-7.testbed.osism.xyz testbed-node-7\n192.168.16.18 testbed-node-8.testbed.osism.xyz testbed-node-8\n192.168.16.19 testbed-node-9.testbed.osism.xyz testbed-node-9\n192.168.16.100 keycloak.testbed.osism.xyz keycloak\n192.168.16.254 api.testbed.osism.xyz api\n"})}),"\n",(0,n.jsx)(t.h3,{id:"webinterfaces",children:"Webinterfaces"}),"\n",(0,n.jsxs)(t.p,{children:["All SSL enabled services within the OSISM Testbed use certs which are signed by the self-signed\n",(0,n.jsx)(t.a,{href:"https://raw.githubusercontent.com/osism/testbed/main/environments/kolla/certificates/ca/testbed.crt",children:"OSISM Testbed CA"}),"\n(Download the file and import it as certification authority to your browser)."]}),"\n",(0,n.jsx)(t.p,{children:"If you want to access the services please choose the URL from the following table."}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Name"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"URL"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Username"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Password"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Note"})]})}),(0,n.jsxs)(t.tbody,{children:[(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"ARA"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"https://ara.testbed.osism.xyz",children:"https://ara.testbed.osism.xyz"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"ara"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Ceph"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"https://api-int.testbed.osism.xyz:8140",children:"https://api-int.testbed.osism.xyz:8140"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"admin"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Flower"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"https://flower.testbed.osism.xyz",children:"https://flower.testbed.osism.xyz"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}}),(0,n.jsx)(t.td,{style:{textAlign:"left"}}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Grafana"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"https://api-int.testbed.osism.xyz:3000",children:"https://api-int.testbed.osism.xyz:3000"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"admin"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"HAProxy (testbed-node-0)"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"http://testbed-node-0.testbed.osism.xyz:1984",children:"http://testbed-node-0.testbed.osism.xyz:1984"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"openstack"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"HAProxy (testbed-node-1)"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"http://testbed-node-1.testbed.osism.xyz:1984",children:"http://testbed-node-1.testbed.osism.xyz:1984"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"openstack"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"HAProxy (testbed-node-2)"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"http://testbed-node-2.testbed.osism.xyz:1984",children:"http://testbed-node-2.testbed.osism.xyz:1984"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"openstack"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Homer"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"https://homer.testbed.osism.xyz",children:"https://homer.testbed.osism.xyz"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}}),(0,n.jsx)(t.td,{style:{textAlign:"left"}}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Horizon (via Keycloak)"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"https://api.testbed.osism.xyz",children:"https://api.testbed.osism.xyz"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"alice"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Horizon (via Keystone)"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"https://api.testbed.osism.xyz",children:"https://api.testbed.osism.xyz"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"admin"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"domain: default"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Horizon (via Keystone)"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"https://api.testbed.osism.xyz",children:"https://api.testbed.osism.xyz"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"test"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"test"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"domain: test"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Keycloak"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"https://keycloak.testbed.osism.xyz/auth",children:"https://keycloak.testbed.osism.xyz/auth"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"admin"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Netbox"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"https://netbox.testbed.osism.xyz",children:"https://netbox.testbed.osism.xyz"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"admin"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Netdata"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"http://testbed-manager.testbed.osism.xyz:19999",children:"http://testbed-manager.testbed.osism.xyz:19999"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}}),(0,n.jsx)(t.td,{style:{textAlign:"left"}}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Nexus"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"https://nexus.testbed.osism.xyz",children:"https://nexus.testbed.osism.xyz"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"admin"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"OpenSearch Dashboards"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"https://api.testbed.osism.xyz:5601",children:"https://api.testbed.osism.xyz:5601"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"opensearch"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Prometheus"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"https://api-int.testbed.osism.xyz:9091",children:"https://api-int.testbed.osism.xyz:9091"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"admin"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"RabbitMQ"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"https://api-int.testbed.osism.xyz:15672",children:"https://api-int.testbed.osism.xyz:15672"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"openstack"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"phpMyAdmin"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"https://phpmyadmin.testbed.osism.xyz",children:"https://phpmyadmin.testbed.osism.xyz"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"root"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]})]})]}),"\n",(0,n.jsx)(t.h3,{id:"authentication-with-oidc",children:"Authentication with OIDC"}),"\n",(0,n.jsx)(t.p,{children:"Authentication with OpenID Connect (OIDC) is possible via Keycloak, which is automatically configured for the OIDC mechanism."}),"\n",(0,n.jsx)(t.h4,{id:"openstack-web-dashboard-horizon-login-via-oidc",children:"OpenStack web dashboard (Horizon) login via OIDC"}),"\n",(0,n.jsxs)(t.p,{children:["For logging in via OIDC, open your browser at OpenStack Dashboard Login Page, select ",(0,n.jsx)(t.strong,{children:"Authenticate via Keycloak"}),", after being\nredirected to the Keycloak login page, perform the login with the credentials ",(0,n.jsx)(t.strong,{children:"alice"})," and ",(0,n.jsx)(t.strong,{children:"password"}),".\nAfter that you will be redirected back to the Horizon dashboard, where you will be logged in with the user ",(0,n.jsx)(t.strong,{children:"alice"}),"."]}),"\n",(0,n.jsx)(t.h4,{id:"openstack-web-dashboard-horizon-logout",children:"OpenStack web dashboard (Horizon) logout"}),"\n",(0,n.jsxs)(t.p,{children:["Keep in mind, that clicking ",(0,n.jsx)(t.strong,{children:"Sign Out"})," on the Horizon dashboard currently doesn't revoke your OIDC token, and any consequent\nattempt to ",(0,n.jsx)(t.strong,{children:"Authenticate via Keycloak"})," will succeed without providing the credentials."]}),"\n",(0,n.jsx)(t.p,{children:"The expiration time of the Single Sign On tokens can be controlled on multiple levels in Keycloak."}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:["On realm level under ",(0,n.jsx)(t.em,{children:"Realm Settings"})," > ",(0,n.jsx)(t.em,{children:"Tokens"}),".\nAssuming the ",(0,n.jsx)(t.em,{children:"keycloak_realm"})," ansible variable is the default ",(0,n.jsx)(t.em,{children:"osism"}),", and keycloak is listening on\n",(0,n.jsx)(t.a,{href:"https://keycloak.testbed.osism.xyz",children:"keycloak.testbed.osism.xyz"}),", then the configuration form is available\n",(0,n.jsx)(t.a,{href:"https://keycloak.testbed.osism.xyz/auth/admin/master/console/#/realms/osism/token-settings",children:"here"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:["Detailed information is available in the Keycloak Server Administrator Documentation\n",(0,n.jsx)(t.a,{href:"https://www.keycloak.org/docs/latest/server_admin/#_timeouts",children:"Session and Token Timeouts"})," section."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:["In a realm down on the ",(0,n.jsx)(t.a,{href:"https://keycloak.testbed.osism.xyz/auth/admin/master/console/#/realms/osism/clients",children:"client level"}),"\nselect the client (keystone), and under ",(0,n.jsx)(t.em,{children:"Settings"})," > ",(0,n.jsx)(t.em,{children:"Advanced Settings"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:["It is recommended to keep the ",(0,n.jsx)(t.em,{children:"Access Token Lifespan"})," on a relatively low value, with the trend of blocking third party\ncookies. For further information see the Keycloak documentation's ",(0,n.jsx)(t.a,{href:"https://www.keycloak.org/docs/latest/securing_apps/#browsers-with-blocked-third-party-cookies",children:"Browsers with Blocked Third-Party Cookies"})," section."]}),"\n"]}),"\n"]}),"\n",(0,n.jsx)(t.h4,{id:"usage-of-the-openstack-cli",children:"Usage of the OpenStack CLI"}),"\n",(0,n.jsxs)(t.p,{children:["The ",(0,n.jsx)(t.code,{children:"environments/openstack"})," folder contains the needed files for the openstack client:"]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"cd environments/openstack\nexport OS_CLOUD= # i.e. admin\nopenstack floating ip list\n"})}),"\n",(0,n.jsx)(t.h4,{id:"openstack-cli-operations-with-openid-connect-password",children:"OpenStack CLI operations with OpenID Connect password"}),"\n",(0,n.jsxs)(t.p,{children:["Using the OpenStack cli is also possible via OIDC, assuming you provisioned the user ",(0,n.jsx)(t.strong,{children:"alice"})," with password ",(0,n.jsx)(t.strong,{children:"password"}),",\nthen you can perform a simple ",(0,n.jsx)(t.code,{children:"project list"})," operation like this:"]}),"\n",(0,n.jsx)(t.p,{children:'See chapter "Usage the OpenStack CLI" for basic openstack usage.'}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"openstack \\\n --os-cacert /etc/ssl/certs/ca-certificates.crt \\\n --os-auth-url https://api.testbed.osism.xyz:5000/v3 \\\n --os-auth-type v3oidcpassword \\\n --os-client-id keystone \\\n --os-client-secret 0056b89c-030f-486b-a6ad-f0fa398fa4ad \\\n --os-username alice \\\n --os-password password \\\n --os-identity-provider keycloak \\\n --os-protocol openid \\\n --os-identity-api-version 3 \\\n --os-discovery-endpoint https://keycloak.testbed.osism.xyz/auth/realms/osism/.well-known/openid-configuration \\\nproject list\n"})}),"\n",(0,n.jsx)(t.h4,{id:"openstack-cli-token-issue-with-openid-connect",children:"OpenStack CLI token issue with OpenID Connect"}),"\n",(0,n.jsxs)(t.p,{children:["It is also possible to exchange your username/password to a token, for further use with the cli.\nThe ",(0,n.jsx)(t.code,{children:"token issue"})," subcommand returns an SQL table, in which the ",(0,n.jsx)(t.code,{children:"id"})," column's ",(0,n.jsx)(t.code,{children:"value"})," field contains the token:"]}),"\n",(0,n.jsx)(t.p,{children:'See chapter "Usage the OpenStack CLI" for basic openstack usage.'}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:'openstack \\\n --os-cacert /etc/ssl/certs/ca-certificates.crt \\\n --os-auth-url https://api.testbed.osism.xyz:5000/v3 \\\n --os-auth-type v3oidcpassword \\\n --os-client-id keystone \\\n --os-client-secret 0056b89c-030f-486b-a6ad-f0fa398fa4ad \\\n --os-username alice \\\n --os-password password \\\n --os-identity-provider keycloak \\\n --os-protocol openid \\\n --os-identity-api-version 3 \\\n --os-discovery-endpoint https://keycloak.testbed.osism.xyz/auth/realms/osism/.well-known/openid-configuration \\\n --os-openid-scope "openid profile email" \\\ntoken issue \\\n -c id\n -f value\n'})}),"\n",(0,n.jsx)(t.p,{children:"An example token is like:"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"gAAAAABhC98gL8nsQWknro3JWDXWLFCG3CDr3Mi9OIlvVAZMjy2mNgYtlXv_0yAIy-\nnSlLAaLIGhht17-mwf8uclKgRuNVsYLSmgUpB163l89-ch2w2_OFe9zNSQNWf4qfd8\nCl7E7XvvUoFr1N8Gh09vaYLvRvYgCGV05xBUSs76qCHa0qElPUsk56s5ft4ALrSrzD\n4cEQRVb5PXNjywdZk9_gtJziz31A7sD4LPIy82O5N9NryDoDw\n"})}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"TODO: OpenStack CLI operations with token"}),"\n",(0,n.jsx)(t.li,{children:"TODO: OpenStack CLI token revoke"}),"\n"]}),"\n",(0,n.jsx)(t.h2,{id:"advanced-usage",children:"Advanced Usage"}),"\n",(0,n.jsx)(t.h3,{id:"external-api",children:"External API"}),"\n",(0,n.jsxs)(t.p,{children:["It is possible to provide the OpenStack APIs and the OpenStack Dashboard via the manager's public IP address.\nThis is not enabled by default, with the exception of the OTC profile. To provide the OpenStack APIs and the\nOpenStack dashboard via the public IP address of the manager, the following changes are necessary in the\n",(0,n.jsx)(t.code,{children:"terraform/environments/regiocloud.tfvars"})," file. If a cloud other than the REGIO.cloud is used, the profile\nof the other cloud is changed accordingly."]}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:["Add the customisation ",(0,n.jsx)(t.code,{children:"external_api"}),". This customisation makes sure that the required security group rules\nare created for the various OpenStack APIs and the OpenStack dashboard."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"# customisation:external_api\n"})}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:["Set parameter ",(0,n.jsx)(t.code,{children:"external_api"})," to ",(0,n.jsx)(t.code,{children:"true"}),". This makes sure that all necessary changes are made in the configuration\nrepository when the Manager service is deployed. It is correct that this is added as a comment."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"external_api = true\n"})}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:["After the deployment of the Manager service and the OpenStack services, the OpenStack APIs and the OpenStack\ndashboard can be reached via a DNS name. The service ",(0,n.jsx)(t.a,{href:"https://traefik.me",children:"traefik.me"})," is used for the DNS record.\nRun the following two commands on the manager node to get the DNS record."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:'$ source /opt/manager-vars.sh\n$ echo "api-${MANAGER_PUBLIC_IP_ADDRESS//./-}.traefik.me"\napi-80-158-46-219.traefik.me\n'})}),"\n"]}),"\n"]}),"\n",(0,n.jsx)(t.h3,{id:"change-versions",children:"Change versions"}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsxs)(t.li,{children:["Go to ",(0,n.jsx)(t.code,{children:"/opt/configuration"})," on ",(0,n.jsx)(t.code,{children:"testbed-manager"})]}),"\n",(0,n.jsxs)(t.li,{children:["Run ",(0,n.jsx)(t.code,{children:"./scripts/set-openstack-version.sh 2023.2"})," to set the OpenStack version to ",(0,n.jsx)(t.code,{children:"2023.2"})]}),"\n",(0,n.jsxs)(t.li,{children:["Run ",(0,n.jsx)(t.code,{children:"./scripts/set-ceph-version.sh reef"})," to set the Ceph version to ",(0,n.jsx)(t.code,{children:"reef"})]}),"\n",(0,n.jsxs)(t.li,{children:["Run ",(0,n.jsx)(t.code,{children:"osism update manager"})," to update the Manager service"]}),"\n"]}),"\n",(0,n.jsx)(t.h3,{id:"deploy-services",children:"Deploy services"}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Script"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Description"})]})}),(0,n.jsxs)(t.tbody,{children:[(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/deploy/000-manager-service.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/deploy/001-helper-services.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/deploy/100-ceph-services-basic.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/deploy/200-infrastructure-services-basic.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/deploy/210-infrastructure-services-extended.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/deploy/300-openstack-services-basic.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/deploy/310-openstack-services-extended.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/deploy/320-openstack-services-baremetal.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/deploy/330-openstack-services-additional.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/deploy/400-monitoring-services.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]})]})]}),"\n",(0,n.jsx)(t.h3,{id:"upgrade-services",children:"Upgrade services"}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Script"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Description"})]})}),(0,n.jsxs)(t.tbody,{children:[(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/upgrade/100-ceph-services.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/upgrade/200-infrastructure-services-basic.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/upgrade/300-openstack-services-basic.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/upgrade/310-openstack-services-extended.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/upgrade/320-openstack-services-baremetal.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/upgrade/330-openstack-services-additional.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]})]})]}),"\n",(0,n.jsx)(t.h2,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,n.jsx)(t.h3,{id:"ansible-errors",children:"Ansible errors"}),"\n",(0,n.jsxs)(t.p,{children:["Ansible errors that have something to do with undefined variables (e.g. ",(0,n.jsx)(t.code,{children:"AnsibleUndefined"}),") are most likely due to cached\nfacts that are no longer valid. The facts can be updated by running ",(0,n.jsx)(t.code,{children:"osism apply facts"}),"."]}),"\n",(0,n.jsx)(t.h3,{id:"unsupported-locale-setting",children:"Unsupported locale setting"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"$ make prepare\nansible-playbook -i localhost, ansible/check-local-versions.yml\nERROR: Ansible could not initialize the preferred locale: unsupported locale setting\nmake: *** [prepare] Error 1\n"})}),"\n",(0,n.jsxs)(t.p,{children:["To solve the problem you have to modify the ",(0,n.jsx)(t.code,{children:"Makefile"}),". Change the 1st line as follows."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"export LC_ALL=en_US.UTF-8\n"})}),"\n",(0,n.jsxs)(t.p,{children:["To find out the locale used on the system ",(0,n.jsx)(t.code,{children:"printenv"})," can be used."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:'$ printenv | grep -i lang|locale\nLANG="en_US.UTF-8"\nLC_COLLATE="en_US.UTF-8"\nLC_CTYPE="UTF-8"\nLC_MESSAGES="en_US.UTF-8"\nLC_MONETARY="en_US.UTF-8"\nLC_NUMERIC="en_US.UTF-8"\nLC_TIME="en_US.UTF-8"\nLC_ALL=\n'})}),"\n",(0,n.jsx)(t.h2,{id:"appendix",children:"Appendix"}),"\n",(0,n.jsx)(t.h3,{id:"configuration",children:"Configuration"}),"\n",(0,n.jsx)(t.p,{children:"This section describes how to configure and customise the OSISM Testbed."}),"\n",(0,n.jsx)(t.h4,{id:"variables",children:"Variables"}),"\n",(0,n.jsxs)(t.p,{children:["The defaults for the OpenTofu variables are intended for ",(0,n.jsx)(t.a,{href:"https://regio.digital",children:"REGIO.cloud"}),"."]}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Variable"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Default"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Note"})]})}),(0,n.jsxs)(t.tbody,{children:[(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"availability_zone"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"nova"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"ceph_version"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"quincy"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"cloud_provider"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"regiocloud"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"configuration_version"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"main"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"deploy_monitoring"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"false"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"dns_nameservers"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:'["8.8.8.8", "9.9.9.9"]'})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"enable_config_drive"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"true"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"external_api"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"false"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"flavor_manager"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"SCS-4V-16-50"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"flavor_node"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"SCS-8V-32-50"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"image"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"Ubuntu 22.04"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Only Ubuntu 22.04 is currently supported"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"image_node"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"Ubuntu 22.04"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Only Ubuntu 22.04 is currently supported"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"keypair"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"testbed"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"manager_version"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"latest"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"network_availability_zone"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"nova"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"number_of_nodes"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"3"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"number_of_volumes"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"3"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"openstack_version"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"2023.2"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"prefix"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"testbed"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"public"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"external"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"refstack"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"false"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"volume_availability_zone"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"nova"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"volume_size_base"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"30"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"volume_size_storage"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"10"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"volume_type"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"__DEFAULT__"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]})]})]}),"\n",(0,n.jsx)(t.h4,{id:"overrides",children:"Overrides"}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Name"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Description"})]})}),(0,n.jsxs)(t.tbody,{children:[(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"manager_boot_from_image"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"manager_boot_from_volume"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"neutron_availability_zone_hints_network"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"neutron_availability_zone_hints_router"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"neutron_router_enable_snat"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"nodes_boot_from_image"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"nodes_boot_from_volume"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"nodes_use_ephemeral_storage"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]})]})]}),"\n",(0,n.jsx)(t.h4,{id:"customisations",children:"Customisations"}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Name"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Description"})]})}),(0,n.jsxs)(t.tbody,{children:[(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"access_floatingip"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"access_ipv4"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"access_ipv6"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"default"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"external_api"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"neutron_floatingip"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]})]})]}),"\n",(0,n.jsx)(t.h3,{id:"notes",children:"Notes"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"The configuration is intentionally kept quite static. Please create no PRs to make the configuration more flexible/dynamic."}),"\n",(0,n.jsx)(t.li,{children:"The OSISM documentation uses hostnames, examples, addresses etc. from OSISM Testbed."}),"\n",(0,n.jsxs)(t.li,{children:["The third volume (",(0,n.jsx)(t.code,{children:"/dev/sdd"}),") is not enabled for Ceph by default. This is to test the scaling of Ceph."]}),"\n",(0,n.jsx)(t.li,{children:"The manager is used as pull through cache for Docker images and Ubuntu packages. This reduces the amount of traffic consumed."}),"\n"]}),"\n",(0,n.jsx)(t.h3,{id:"supported-releases",children:"Supported releases"}),"\n",(0,n.jsx)(t.p,{children:"The following stable Ceph and OpenStack releases are supported."}),"\n",(0,n.jsxs)(t.p,{children:["The deployment of Ceph is based on ",(0,n.jsx)(t.a,{href:"https://docs.ceph.com/ceph-ansible/",children:"ceph-ansible"}),"."]}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["Ceph Quincy (",(0,n.jsx)(t.strong,{children:"default"}),")"]}),"\n",(0,n.jsx)(t.li,{children:"Ceph Reef"}),"\n"]}),"\n",(0,n.jsxs)(t.p,{children:["The deployment of OpenStack is based on ",(0,n.jsx)(t.a,{href:"https://docs.openstack.org/kolla-ansible/latest/",children:"kolla-ansible"}),"."]}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"OpenStack 2023.1"}),"\n",(0,n.jsxs)(t.li,{children:["OpenStack 2023.2 (",(0,n.jsx)(t.strong,{children:"default"}),")"]}),"\n",(0,n.jsx)(t.li,{children:"OpenStack 2024.1"}),"\n"]}),"\n",(0,n.jsxs)(t.p,{children:["The deployment of Kubernetes is based on ",(0,n.jsx)(t.a,{href:"https://github.com/techno-tim/k3s-ansible",children:"k3s-ansible"}),"."]}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["Kubernetes v1.29 (",(0,n.jsx)(t.strong,{children:"default"}),")"]}),"\n"]}),"\n",(0,n.jsx)(t.h3,{id:"included-services",children:"Included services"}),"\n",(0,n.jsx)(t.p,{children:"The following services can currently be used with the OSISM Testbed without further adjustments."}),"\n",(0,n.jsx)(t.h4,{id:"infrastructure",children:"Infrastructure"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"Ceph"}),"\n",(0,n.jsx)(t.li,{children:"Cluster API Management Cluster"}),"\n",(0,n.jsx)(t.li,{children:"Fluentd"}),"\n",(0,n.jsx)(t.li,{children:"Gnocchi"}),"\n",(0,n.jsx)(t.li,{children:"Grafana"}),"\n",(0,n.jsx)(t.li,{children:"Haproxy"}),"\n",(0,n.jsx)(t.li,{children:"Influxdb"}),"\n",(0,n.jsx)(t.li,{children:"Keepalived"}),"\n",(0,n.jsx)(t.li,{children:"Keycloak"}),"\n",(0,n.jsx)(t.li,{children:"Kubernetes"}),"\n",(0,n.jsx)(t.li,{children:"Mariadb"}),"\n",(0,n.jsx)(t.li,{children:"Memcached"}),"\n",(0,n.jsx)(t.li,{children:"Netbox"}),"\n",(0,n.jsx)(t.li,{children:"Netdata"}),"\n",(0,n.jsx)(t.li,{children:"Opensearch"}),"\n",(0,n.jsx)(t.li,{children:"Openvswitch"}),"\n",(0,n.jsx)(t.li,{children:"Patchman"}),"\n",(0,n.jsx)(t.li,{children:"Prometheus exporters"}),"\n",(0,n.jsx)(t.li,{children:"Rabbitmq"}),"\n",(0,n.jsx)(t.li,{children:"Redis"}),"\n"]}),"\n",(0,n.jsx)(t.h4,{id:"openstack",children:"OpenStack"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"Barbican"}),"\n",(0,n.jsx)(t.li,{children:"Ceilometer"}),"\n",(0,n.jsx)(t.li,{children:"Cinder"}),"\n",(0,n.jsx)(t.li,{children:"Designate"}),"\n",(0,n.jsx)(t.li,{children:"Glance"}),"\n",(0,n.jsx)(t.li,{children:"Heat"}),"\n",(0,n.jsx)(t.li,{children:"Horizon"}),"\n",(0,n.jsx)(t.li,{children:"Ironic"}),"\n",(0,n.jsx)(t.li,{children:"Keystone"}),"\n",(0,n.jsx)(t.li,{children:"Magnum"}),"\n",(0,n.jsx)(t.li,{children:"Manila"}),"\n",(0,n.jsx)(t.li,{children:"Neutron"}),"\n",(0,n.jsx)(t.li,{children:"Nova (with Libvirt/KVM)"}),"\n",(0,n.jsx)(t.li,{children:"Octavia"}),"\n",(0,n.jsx)(t.li,{children:"Senlin"}),"\n",(0,n.jsx)(t.li,{children:"Skyline"}),"\n"]}),"\n",(0,n.jsx)(t.h3,{id:"makefile-reference",children:"Makefile reference"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"$ make help\n\nUsage:\n make \n help Display this help.\n clean Destroy infrastructure with OpenTofu.\n wipe-local-install Wipe the software dependencies in `venv`.\n create Create required infrastructure with OpenTofu.\n login Log in on the manager.\n vpn-wireguard Establish a wireguard vpn tunnel.\n vpn-sshuttle Establish a sshuttle vpn tunnel.\n bootstrap Bootstrap everything.\n manager Deploy only the manager service.\n identity Deploy only identity services.\n ceph Deploy only ceph services.\n deploy Deploy everything and then check it.\n prepare Run local preperations.\n deps Install software preconditions to `venv`.\n\n$ make \n"})}),"\n",(0,n.jsx)(t.h3,{id:"ci-jobs",children:"CI jobs"}),"\n",(0,n.jsxs)(t.p,{children:["You can inspect the ",(0,n.jsx)(t.a,{href:"https://zuul.services.betacloud.xyz/t/osism/builds?project=osism%2Ftestbed&skip=0",children:"results of the daily zuul jobs"}),"."]}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Name"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Description"})]})}),(0,n.jsxs)(t.tbody,{children:[(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"testbed-deploy"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"testbed-deploy-ceph"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"testbed-deploy-stable"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"testbed-update-stable"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"testbed-upgrade"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"testbed-upgrade-ceph"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"testbed-upgrade-stable"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]})]})]})]})}function u(e={}){const{wrapper:t}={...(0,l.a)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(x,{...e})}):x(e)}},5162:(e,t,s)=>{s.d(t,{Z:()=>r});s(7294);var n=s(6905);const l={tabItem:"tabItem_Ymn6"};var i=s(5893);function r(e){let{children:t,hidden:s,className:r}=e;return(0,i.jsx)("div",{role:"tabpanel",className:(0,n.Z)(l.tabItem,r),hidden:s,children:t})}},4866:(e,t,s)=>{s.d(t,{Z:()=>v});var n=s(7294),l=s(6905),i=s(2466),r=s(6550),d=s(469),c=s(1980),o=s(7392),a=s(812);function h(e){return n.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,n.isValidElement)(e)&&function(e){const{props:t}=e;return!!t&&"object"==typeof t&&"value"in t}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function x(e){const{values:t,children:s}=e;return(0,n.useMemo)((()=>{const e=t??function(e){return h(e).map((e=>{let{props:{value:t,label:s,attributes:n,default:l}}=e;return{value:t,label:s,attributes:n,default:l}}))}(s);return function(e){const t=(0,o.l)(e,((e,t)=>e.value===t.value));if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[t,s])}function u(e){let{value:t,tabValues:s}=e;return s.some((e=>e.value===t))}function j(e){let{queryString:t=!1,groupId:s}=e;const l=(0,r.k6)(),i=function(e){let{queryString:t=!1,groupId:s}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!s)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return s??null}({queryString:t,groupId:s});return[(0,c._X)(i),(0,n.useCallback)((e=>{if(!i)return;const t=new URLSearchParams(l.location.search);t.set(i,e),l.replace({...l.location,search:t.toString()})}),[i,l])]}function p(e){const{defaultValue:t,queryString:s=!1,groupId:l}=e,i=x(e),[r,c]=(0,n.useState)((()=>function(e){let{defaultValue:t,tabValues:s}=e;if(0===s.length)throw new Error("Docusaurus error: the component requires at least one children component");if(t){if(!u({value:t,tabValues:s}))throw new Error(`Docusaurus error: The has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${s.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const n=s.find((e=>e.default))??s[0];if(!n)throw new Error("Unexpected error: 0 tabValues");return n.value}({defaultValue:t,tabValues:i}))),[o,h]=j({queryString:s,groupId:l}),[p,f]=function(e){let{groupId:t}=e;const s=function(e){return e?`docusaurus.tab.${e}`:null}(t),[l,i]=(0,a.Nk)(s);return[l,(0,n.useCallback)((e=>{s&&i.set(e)}),[s,i])]}({groupId:l}),g=(()=>{const e=o??p;return u({value:e,tabValues:i})?e:null})();(0,d.Z)((()=>{g&&c(g)}),[g]);return{selectedValue:r,selectValue:(0,n.useCallback)((e=>{if(!u({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);c(e),h(e),f(e)}),[h,f,i]),tabValues:i}}var f=s(2389);const g={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var y=s(5893);function m(e){let{className:t,block:s,selectedValue:n,selectValue:r,tabValues:d}=e;const c=[],{blockElementScrollPositionUntilNextRender:o}=(0,i.o5)(),a=e=>{const t=e.currentTarget,s=c.indexOf(t),l=d[s].value;l!==n&&(o(t),r(l))},h=e=>{let t=null;switch(e.key){case"Enter":a(e);break;case"ArrowRight":{const s=c.indexOf(e.currentTarget)+1;t=c[s]??c[0];break}case"ArrowLeft":{const s=c.indexOf(e.currentTarget)-1;t=c[s]??c[c.length-1];break}}t?.focus()};return(0,y.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,l.Z)("tabs",{"tabs--block":s},t),children:d.map((e=>{let{value:t,label:s,attributes:i}=e;return(0,y.jsx)("li",{role:"tab",tabIndex:n===t?0:-1,"aria-selected":n===t,ref:e=>c.push(e),onKeyDown:h,onClick:a,...i,className:(0,l.Z)("tabs__item",g.tabItem,i?.className,{"tabs__item--active":n===t}),children:s??t},t)}))})}function b(e){let{lazy:t,children:s,selectedValue:l}=e;const i=(Array.isArray(s)?s:[s]).filter(Boolean);if(t){const e=i.find((e=>e.props.value===l));return e?(0,n.cloneElement)(e,{className:"margin-top--md"}):null}return(0,y.jsx)("div",{className:"margin-top--md",children:i.map(((e,t)=>(0,n.cloneElement)(e,{key:t,hidden:e.props.value!==l})))})}function A(e){const t=p(e);return(0,y.jsxs)("div",{className:(0,l.Z)("tabs-container",g.tabList),children:[(0,y.jsx)(m,{...t,...e}),(0,y.jsx)(b,{...t,...e})]})}function v(e){const t=(0,f.Z)();return(0,y.jsx)(A,{...e,children:h(e.children)},String(t))}},1151:(e,t,s)=>{s.d(t,{Z:()=>d,a:()=>r});var n=s(7294);const l={},i=n.createContext(l);function r(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function d(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(l):e.components||l:r(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6235e5b8.cfff537b.js b/assets/js/6235e5b8.cfff537b.js new file mode 100644 index 0000000000..cbc2446940 --- /dev/null +++ b/assets/js/6235e5b8.cfff537b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkosism=self.webpackChunkosism||[]).push([[9705],{5675:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>a,contentTitle:()=>c,default:()=>u,frontMatter:()=>d,metadata:()=>o,toc:()=>h});var n=s(5893),l=s(1151),i=s(4866),r=s(5162);const d={sidebar_label:"Testbed Guide"},c="Testbed",o={id:"guides/other-guides/testbed",title:"Testbed",description:"With the OSISM Testbed, it is possible to run a full Sovereign Cloud Stack",source:"@site/docs/guides/other-guides/testbed.mdx",sourceDirName:"guides/other-guides",slug:"/guides/other-guides/testbed",permalink:"/docs/guides/other-guides/testbed",draft:!1,unlisted:!1,editUrl:"https://github.com/osism/osism.github.io/tree/main/docs/guides/other-guides/testbed.mdx",tags:[],version:"current",frontMatter:{sidebar_label:"Testbed Guide"},sidebar:"tutorialSidebar",previous:{title:"Style Guide",permalink:"/docs/guides/other-guides/style-guide"},next:{title:"References",permalink:"/docs/references/"}},a={},h=[{value:"Requirements",id:"requirements",level:2},{value:"Cloud access",id:"cloud-access",level:3},{value:"Cloud resources",id:"cloud-resources",level:3},{value:"Software",id:"software",level:3},{value:"Deployment",id:"deployment",level:2},{value:"Usage",id:"usage",level:2},{value:"Custom CA",id:"custom-ca",level:3},{value:"VPN access",id:"vpn-access",level:3},{value:"Wireguard",id:"wireguard",level:4},{value:"sshuttle",id:"sshuttle",level:4},{value:"Static entries in /etc/hosts",id:"static-entries-in-etchosts",level:3},{value:"Webinterfaces",id:"webinterfaces",level:3},{value:"Authentication with OIDC",id:"authentication-with-oidc",level:3},{value:"OpenStack web dashboard (Horizon) login via OIDC",id:"openstack-web-dashboard-horizon-login-via-oidc",level:4},{value:"OpenStack web dashboard (Horizon) logout",id:"openstack-web-dashboard-horizon-logout",level:4},{value:"Usage of the OpenStack CLI",id:"usage-of-the-openstack-cli",level:4},{value:"OpenStack CLI operations with OpenID Connect password",id:"openstack-cli-operations-with-openid-connect-password",level:4},{value:"OpenStack CLI token issue with OpenID Connect",id:"openstack-cli-token-issue-with-openid-connect",level:4},{value:"Advanced Usage",id:"advanced-usage",level:2},{value:"External API",id:"external-api",level:3},{value:"Change versions",id:"change-versions",level:3},{value:"Deploy services",id:"deploy-services",level:3},{value:"Upgrade services",id:"upgrade-services",level:3},{value:"Ceph via Rook (technical preview)",id:"ceph-via-rook-technical-preview",level:3},{value:"Troubleshooting",id:"troubleshooting",level:2},{value:"Ansible errors",id:"ansible-errors",level:3},{value:"Unsupported locale setting",id:"unsupported-locale-setting",level:3},{value:"Appendix",id:"appendix",level:2},{value:"Configuration",id:"configuration",level:3},{value:"Variables",id:"variables",level:4},{value:"Overrides",id:"overrides",level:4},{value:"Customisations",id:"customisations",level:4},{value:"Notes",id:"notes",level:3},{value:"Supported releases",id:"supported-releases",level:3},{value:"Included services",id:"included-services",level:3},{value:"Infrastructure",id:"infrastructure",level:4},{value:"OpenStack",id:"openstack",level:4},{value:"Makefile reference",id:"makefile-reference",level:3},{value:"CI jobs",id:"ci-jobs",level:3}];function x(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,l.a)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h1,{id:"testbed",children:"Testbed"}),"\n",(0,n.jsxs)(t.p,{children:["With the OSISM Testbed, it is possible to run a full Sovereign Cloud Stack\ndeployment on an existing OpenStack environment such as Cleura or ",(0,n.jsx)(t.a,{href:"https://regio.digital",children:"REGIO.cloud"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:["OSISM is the reference implementation for the Infrastructure as a Service (IaaS) layer in the\n",(0,n.jsx)(t.a,{href:"https://scs.community",children:"Sovereign Cloud Stack"})," (SCS) project. The OSISM Testbed is therefore\nused in the SCS project to test and work on the Instrastructure as a Service layer."]}),"\n",(0,n.jsx)(t.p,{children:"The OSISM Testbed is intended as a playground. Further services and integration will\nbe added over time. A increasing number of best practices and experiences from the productive\ndeployments will be included here in the future. It will become more production-like\nover time. However, at no point does it claim to represent a production setup exactly."}),"\n",(0,n.jsx)(t.h2,{id:"requirements",children:"Requirements"}),"\n",(0,n.jsx)(t.h3,{id:"cloud-access",children:"Cloud access"}),"\n",(0,n.jsx)(t.p,{children:"The usual prerequisite is to have an account on one of the supported OpenStack cloud providers.\nAs the OSISM Testbed also virtualizes systems itself, the OpenStack cluster should provide\nthe capabilities for nested virtualization."}),"\n",(0,n.jsx)(t.p,{children:"It is not part of this guide to describe the registration with the individual cloud\nproviders. Please contact the respective cloud provider for this."}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Product"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Provider"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Profile name"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Note"})]})}),(0,n.jsxs)(t.tbody,{children:[(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Cleura"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Cleura"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"cleura"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Fuga Cloud"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"FUGA"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"fuga"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"HuaweiCloud"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"HuaweiCloud"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"huaweicloud"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"OVH"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"OVH"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"ovh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"OpenTelekomCloud"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"T-Systems"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"otc"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"pluscloud open"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"plusserver"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"pluscloudopen"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"pluscloud SCS Test"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"plusserver"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"gx-scs"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"REGIO.cloud"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"OSISM"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"regiocloud"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"REGIO.cloud"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"OSISM"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"regio-fast"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"boot from NVMe SSD backed volumes"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Wavestack"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"noris network"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"wavestack"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]})]})]}),"\n",(0,n.jsxs)(t.p,{children:["For each cloud provider listed in the table, a predefined profile is available in the\n",(0,n.jsx)(t.code,{children:"terraform/environments"})," directory. This profile contains the name of the public\nnetwork, which flavors to use, etc."]}),"\n",(0,n.jsxs)(t.p,{children:["Here is an example from the profile for ",(0,n.jsx)(t.a,{href:"https://regio.digital",children:"REGIO.cloud"}),"."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-text",children:'flavor_manager = "SCS-4V-16-50"\nflavor_node = "SCS-8V-32-50"\nvolume_type = "ssd"\nimage = "Ubuntu 22.04"\nimage_node = "Ubuntu 22.04"\npublic = "public"\navailability_zone = "nova"\nvolume_availability_zone = "nova"\nnetwork_availability_zone = "nova"\n'})}),"\n",(0,n.jsx)(t.h3,{id:"cloud-resources",children:"Cloud resources"}),"\n",(0,n.jsx)(t.p,{children:"The OSISM Testbed requires at least the following project quota when using the default flavors:"}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Quantity"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Resource"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Note"})]})}),(0,n.jsxs)(t.tbody,{children:[(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"4"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Instances"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"28 VCPUs + 112 GByte RAM (3 modes, 1 manager)"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"9"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Volumes"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"90 GByte volume storage"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"1"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Floating IP"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"1"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Keypair"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"3"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Security group"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"16"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Security group rules"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"1"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Network"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"1"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Subetwork"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"6"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Ports"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"1"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Router"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]})]})]}),"\n",(0,n.jsx)(t.h3,{id:"software",children:"Software"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.code,{children:"make"})," must be installed on the system"]}),"\n",(0,n.jsxs)(t.li,{children:["Wireguard or ",(0,n.jsx)(t.code,{children:"sshuttle"})," must be installed on your system for VPN access"]}),"\n",(0,n.jsxs)(t.li,{children:["Python must be installed, the Python version used must be at least 3.10, otherwise\nthe current Ansible release cannot be used (details in the\n",(0,n.jsx)(t.a,{href:"https://docs.ansible.com/ansible/latest/reference_appendices/release_and_maintenance.html#ansible-core-support-matrix",children:"Ansible support matrix"}),")"]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.code,{children:"python3-venv"})," must be installed for managing Python dependencies like Ansible"]}),"\n"]}),"\n",(0,n.jsx)(t.h2,{id:"deployment",children:"Deployment"}),"\n",(0,n.jsx)(t.p,{children:"This section describes step by step how to deploy the OSISM Testbed."}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"Request access from the administrator of the respective cloud or get access to an OpenStack cloud."}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:["Clone the ",(0,n.jsx)(t.a,{href:"https://github.com/osism/testbed",children:"osism/testbed"})," repository."]}),"\n",(0,n.jsx)(t.p,{children:"The repository can also be cloned to any other location."}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"mkdir -p ~/src/github.com/osism\ngit clone https://github.com/osism/testbed ~/src/github.com/osism/testbed\ncd ~/src/github.com/osism/testbed\n"})}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"Configure your cloud access profile"}),"\n",(0,n.jsxs)(t.p,{children:["The access data for the cloud provider used is stored in ",(0,n.jsx)(t.code,{children:"terraform/clouds.yaml"})," and (optionally)\nin ",(0,n.jsx)(t.code,{children:"terraform/secure.yaml"})," (same structure, if you want to store credentials on a separate place)."]}),"\n",(0,n.jsxs)(t.p,{children:["In file ",(0,n.jsx)(t.a,{href:"https://github.com/osism/testbed/blob/main/terraform/clouds.yaml.sample",children:"terraform/clouds.yaml.sample"}),"\nyou will find examples of typical setups. Settings that are identical for all users of a cloud can be defined\ncentrally via the profiles of the file\n",(0,n.jsx)(t.a,{href:"https://github.com/osism/testbed/blob/main/terraform/clouds-public.yaml",children:"terraform/clouds-public.yaml"}),".\nYou can reference these settings by using the ",(0,n.jsx)(t.code,{children:"profile"})," parameter in cloud-specific\ndefinition in ",(0,n.jsx)(t.code,{children:"terraform/clouds.yaml"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:["The user specific settings of the ",(0,n.jsx)(t.code,{children:"clouds.yaml"})," file are provided by the cloud provider. Please check the\ndocumentation of the cloud provider you are using or their support for details."]}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.a,{href:"https://regio.digital",children:"REGIO.cloud"})," is used as an example here. The cloud name in ",(0,n.jsx)(t.code,{children:"clouds.yaml"}),"\nand the environment name (value of ",(0,n.jsx)(t.code,{children:"ENVIRONMENT"}),") are ",(0,n.jsx)(t.code,{children:"regiocloud"})," in this case. It is important that\nthe name of the cloud in ",(0,n.jsx)(t.code,{children:"clouds.yaml"})," matches the name of the environment to be used. The names must\nbe identical. It is currently not possible to name the cloud ",(0,n.jsx)(t.code,{children:"regiocloud-123"})," in ",(0,n.jsx)(t.code,{children:"clouds.yaml"})," if the\nenvironment is ",(0,n.jsx)(t.code,{children:"regiocloud"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:["If another cloud is used, replace ",(0,n.jsx)(t.code,{children:"regiocloud"})," with the respective profile name ",(0,n.jsx)(t.a,{href:"#cloud-access",children:"from the table above"}),"."]}),"\n",(0,n.jsxs)(i.Z,{children:[(0,n.jsxs)(r.Z,{value:"testbed-cloud-access-with-app-credentials",label:"Application Credentials",children:[(0,n.jsxs)(t.p,{children:["The use of application credentials is preferred. This way it is not necessary to store\ndetails like username, project name or sensitive information like the password in the\n",(0,n.jsx)(t.code,{children:"clouds.yaml"})," file."]}),(0,n.jsxs)(t.p,{children:["The application credentials can be found in Horizon under ",(0,n.jsx)(t.strong,{children:"Identity"}),". Use ",(0,n.jsx)(t.code,{children:"OSISM Testbed"})," as\nname and click ",(0,n.jsx)(t.code,{children:"Create Application Credential"}),"."]}),(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-yaml",metastring:'title="terraform/clouds.yaml"',children:'clouds:\n regiocloud:\n profile: regiocloud\n auth:\n application_credential_id: ID\n application_credential_secret: SECRET\n auth_type: "v3applicationcredential"\n'})}),(0,n.jsxs)(t.p,{children:["If you want to make use of ",(0,n.jsx)(t.code,{children:"terraform/secure.yaml"})," add your application credential secret there\ninstead of ",(0,n.jsx)(t.code,{children:"terraform/clouds.yaml"}),"."]}),(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-yaml",metastring:'title="terraform/secure.yaml"',children:"clouds:\n regiocloud:\n auth:\n application_credential_secret: SECRET\n"})})]}),(0,n.jsxs)(r.Z,{value:"testbed-cloud-access-with-username-password",label:"Username/Password",children:[(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-yaml",metastring:'title="terraform/clouds.yaml"',children:"clouds:\n regiocloud:\n profile: regiocloud\n auth:\n project_name: PROJECT\n username: USERNAME\n project_domain_name: DOMAIN\n user_domain_name: DOMAIN\n"})}),(0,n.jsxs)(t.p,{children:["If you want to make use of ",(0,n.jsx)(t.code,{children:"terraform/secure.yaml"})," add your password there instead of ",(0,n.jsx)(t.code,{children:"terraform/clouds.yaml"}),"."]}),(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-yaml",metastring:'title="terraform/secure.yaml"',children:"clouds:\n regiocloud:\n auth:\n password: PASSWORD\n"})})]})]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"Prepare the deployment."}),"\n",(0,n.jsxs)(t.p,{children:["The versions of Ansible and ",(0,n.jsx)(t.a,{href:"https://opentofu.org",children:"OpenTofu"})," are managed\nautomatically and necessary dependencies are cloned."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"make prepare\n"})}),"\n",(0,n.jsxs)(t.p,{children:["If any error occurs during preparation and you want to run the preparation\nagain, it is important to run ",(0,n.jsx)(t.code,{children:"make wipe-local-install"})," first. Otherwise the\npreparation will not be redone completely and necessary parts will be missing\nlater on."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"Create the infrastructure with OpenTofu."}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"make ENVIRONMENT=regiocloud create\n"})}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"Deploy the OSISM manager and bootstrap all nodes."}),"\n",(0,n.jsxs)(i.Z,{children:[(0,n.jsx)(r.Z,{value:"testbed-deploy-latst",label:"Deploy latest manager version",children:(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"make ENVIRONMENT=regiocloud manager\n"})})}),(0,n.jsx)(r.Z,{value:"testbed-deploy-stable",label:"Deploy a stable manager version",children:(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"make ENVIRONMENT=regiocloud VERSION_MANAGER=7.0.3 manager\n"})})})]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"After the bootstrap, you can log in to the manager via SSH."}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"make ENVIRONMENT=regiocloud login\n"})}),"\n",(0,n.jsx)(t.p,{children:"Yo can log in to the nodes of the cluster via the manager."}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"osism console testbed-node-0\n"})}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"Deploy all services."}),"\n",(0,n.jsxs)(i.Z,{children:[(0,n.jsxs)(r.Z,{value:"testbed-deploy-multi-steps",label:"Deployment in single steps",children:[(0,n.jsxs)(t.p,{children:["It is also possible to deploy the services step by step on the\nmanager. To do this, first log in to the manager with ",(0,n.jsx)(t.code,{children:"make ENVIRONMENT=regiocloud login"}),"\nand then execute the deploy scripts one after the other. It is recommended to do this\nwithin a screen session."]}),(0,n.jsx)(t.p,{children:"Deploying the services takes some time and depends on how much bandwidth is available,\nhow the instances are equipped, etc. 90-120 minutes is not unusual when Ceph and OpenStack\nare fully deployed."}),(0,n.jsxs)(t.p,{children:["To speed up the Ansible playbooks, ",(0,n.jsx)(t.a,{href:"https://ara.recordsansible.org",children:"ARA"})," can be disabled. This\nis done by executing ",(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/disable-ara.sh"}),". Run this script ",(0,n.jsx)(t.strong,{children:"before"})," the deployment scripts.\nAfterwards no more logs are available in the ARA web\ninterface. To re-enable ARA use ",(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/enable-ara.sh"}),"."]}),(0,n.jsxs)(t.p,{children:["There is also the option of pre-population of images with ",(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/pull-images.sh"}),"\nso that deployments do not have to be lengthy. Run this script ",(0,n.jsx)(t.strong,{children:"before"})," the deployment scripts."]}),(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"/opt/configuration/scripts/deploy/001-helper-services.sh\n/opt/configuration/scripts/deploy/005-kubernetes.sh\n/opt/configuration/scripts/deploy/100-ceph-services-basic.sh\n/opt/configuration/scripts/deploy/200-infrastructure-services-basic.sh\n/opt/configuration/scripts/deploy/300-openstack-services-basic.sh\n/opt/configuration/scripts/deploy/400-monitoring-services.sh\n"})}),(0,n.jsxs)(t.p,{children:["Prepare OpenStack resources like public network, flavors and images by running\n",(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/bootstrap.sh"}),". Run this script ",(0,n.jsx)(t.strong,{children:"after"})," the deployment scripts."]}),(0,n.jsxs)(t.admonition,{type:"info",children:[(0,n.jsxs)(t.p,{children:["If you only want to deploy the monitoring services with ",(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/deploy/400-monitoring-services.sh"}),",\na few dependencies must be deployed first. You can then use the monitoring services without having to install a\ncomplete OpenStack & Ceph environment."]}),(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"osism apply common\nosism apply loadbalancer\nosism apply opensearch\nosism apply mariadb\n"})})]})]}),(0,n.jsxs)(r.Z,{value:"testbed-deploy-single-step",label:"Deployment of all services",children:[(0,n.jsx)(t.p,{children:"In this single step deployment, Ceph, OpenStack and all necessary\ninfrastructure services (MariaDB, RabbitMQ, ...) are deployed.\nDepending on the cloud, the deployment will take some time. Up to two hours is not unusual."}),(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"make ENVIRONMENT=regiocloud deploy\n"})})]})]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:["If you want to verify the deployment with ",(0,n.jsx)(t.a,{href:"https://opendev.org/openinfra/refstack",children:"refstack"})," run\n",(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/check.sh"}),". This step will take some time and is optional."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"The machine images required for the use of Kubernetes Cluster API and the amphora driver of OpenStack Octavia\nservice are not provided by default to save resources on the OSISM Testbed and improve deployment time.\nThese can be provisioned if required."}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"/opt/configuration/scripts/bootstrap/301-openstack-octavia-amhpora-image.sh\n/opt/configuration/scripts/bootstrap/302-openstack-k8s-clusterapi-images.sh\n"})}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"If you want you can create a test project with a test user after login. It also\ncreates an instance with a volume attached to a network with a router. This step is optional."}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"osism apply --environment openstack test\n"})}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"When the OSISM Testbed is no longer needed, it can be deleted."}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"make ENVIRONMENT=regiocloud clean\n"})}),"\n"]}),"\n"]}),"\n",(0,n.jsx)(t.h2,{id:"usage",children:"Usage"}),"\n",(0,n.jsx)(t.p,{children:"Deployment must be completed at this point."}),"\n",(0,n.jsx)(t.h3,{id:"custom-ca",children:"Custom CA"}),"\n",(0,n.jsxs)(t.p,{children:["The OSISM Testbed deployment currently uses hostnames in the domain ",(0,n.jsx)(t.code,{children:"testbed.osism.xyz"}),". This is a real domain\nand we provide the DNS records matching the addresses used in the OSISM Testbed, so that once you connect to your testbed via a direct\nlink or Wireguard, you can access hosts and servers by their hostname (e.g. ",(0,n.jsx)(t.code,{children:"ssh testbed-manager.testbed.osism.xyz"}),")."]}),"\n",(0,n.jsxs)(t.p,{children:["We also provide a wildcard TLS certificate signed by a custom CA for ",(0,n.jsx)(t.code,{children:"testbed.osism.xyz"})," and ",(0,n.jsx)(t.code,{children:"*.testbed.osism.xyz"}),".\nThis CA is always used for each testbed. The CA is not regenerated and it is not planned to change this for the next 10 years."]}),"\n",(0,n.jsxs)(t.p,{children:["In order for these certificates to be recognized locally as valid, the CA\n",(0,n.jsx)(t.a,{href:"https://raw.githubusercontent.com/osism/testbed/main/environments/kolla/certificates/ca/testbed.crt",children:"environments/kolla/certificates/ca/testbed.crt"}),"\nmust be imported locally."]}),"\n",(0,n.jsx)(t.h3,{id:"vpn-access",children:"VPN access"}),"\n",(0,n.jsx)(t.h4,{id:"wireguard",children:"Wireguard"}),"\n",(0,n.jsxs)(t.p,{children:["Install wireguard on your workstation, if you have not done this before. For instructions how to do\nit on your workstation, please have a look on the documentation of your used distribution. The\nwireguard documentation you will find ",(0,n.jsx)(t.a,{href:"https://www.wireguard.com",children:"here"}),"."]}),"\n",(0,n.jsx)(t.p,{children:"Start the wireguard tunnel.\n(Press CTRL+c to keep the tunnel running forever. The make target also launches a browser tab with references to all services)"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"make vpn-wireguard ENVIRONMENT=regiocloud\n"})}),"\n",(0,n.jsx)(t.p,{children:"If you want to connect to the OSISM Testbed from multiple clients, change the client IP\naddress in the downloaded configuration file to be different on each client."}),"\n",(0,n.jsxs)(t.p,{children:["If you only want to download the Wireguard configuration, you can use the ",(0,n.jsx)(t.code,{children:"vpn-wireguard-config"}),"\ntarget. The configuration is then available in the file ",(0,n.jsx)(t.code,{children:"wg-testbed-regiocloud.conf"}),", for example."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"make vpn-wireguard-config ENVIRONMENT=regiocloud\n"})}),"\n",(0,n.jsx)(t.h4,{id:"sshuttle",children:"sshuttle"}),"\n",(0,n.jsxs)(t.p,{children:["If you do not want to use Wireguard you can also work with ",(0,n.jsx)(t.a,{href:"https://github.com/sshuttle/sshuttle",children:"sshuttle"}),"."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"make vpn-sshuttle ENVIRONMENT=regiocloud\nkillall sshuttle\n"})}),"\n",(0,n.jsxs)(t.h3,{id:"static-entries-in-etchosts",children:["Static entries in ",(0,n.jsx)(t.code,{children:"/etc/hosts"})]}),"\n",(0,n.jsxs)(t.p,{children:["If you are unable to access the following domains, you can customize your local ",(0,n.jsx)(t.code,{children:"/etc/hosts"}),"\nwith the following static entries. This may be necessary, for example, if you use Pi-hole and\nall DNS entries from a public DNS with a non-public IP address are filtered."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"# OSISM Testbed hosts\n192.168.16.5 ara.testbed.osism.xyz ara\n192.168.16.5 cgit.testbed.osism.xyz cgit\n192.168.16.5 flower.testbed.osism.xyz flower\n192.168.16.5 homer.testbed.osism.xyz homer\n192.168.16.5 netbox.testbed.osism.xyz netbox\n192.168.16.5 testbed-manager.testbed.osism.xyz testbed-manager\n192.168.16.5 nexus.testbed.osism.xyz nexus\n192.168.16.5 phpmyadmin.testbed.osism.xyz phpmyadmin\n192.168.16.9 api-int.testbed.osism.xyz api-int\n192.168.16.10 testbed-node-0.testbed.osism.xyz testbed-node-0\n192.168.16.11 testbed-node-1.testbed.osism.xyz testbed-node-1\n192.168.16.12 testbed-node-2.testbed.osism.xyz testbed-node-2\n192.168.16.13 testbed-node-3.testbed.osism.xyz testbed-node-3\n192.168.16.14 testbed-node-4.testbed.osism.xyz testbed-node-4\n192.168.16.15 testbed-node-5.testbed.osism.xyz testbed-node-5\n192.168.16.16 testbed-node-6.testbed.osism.xyz testbed-node-6\n192.168.16.17 testbed-node-7.testbed.osism.xyz testbed-node-7\n192.168.16.18 testbed-node-8.testbed.osism.xyz testbed-node-8\n192.168.16.19 testbed-node-9.testbed.osism.xyz testbed-node-9\n192.168.16.100 keycloak.testbed.osism.xyz keycloak\n192.168.16.254 api.testbed.osism.xyz api\n"})}),"\n",(0,n.jsx)(t.h3,{id:"webinterfaces",children:"Webinterfaces"}),"\n",(0,n.jsxs)(t.p,{children:["All SSL enabled services within the OSISM Testbed use certs which are signed by the self-signed\n",(0,n.jsx)(t.a,{href:"https://raw.githubusercontent.com/osism/testbed/main/environments/kolla/certificates/ca/testbed.crt",children:"OSISM Testbed CA"}),"\n(Download the file and import it as certification authority to your browser)."]}),"\n",(0,n.jsx)(t.p,{children:"If you want to access the services please choose the URL from the following table."}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Name"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"URL"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Username"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Password"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Note"})]})}),(0,n.jsxs)(t.tbody,{children:[(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"ARA"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"https://ara.testbed.osism.xyz",children:"https://ara.testbed.osism.xyz"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"ara"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Ceph"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"https://api-int.testbed.osism.xyz:8140",children:"https://api-int.testbed.osism.xyz:8140"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"admin"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Flower"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"https://flower.testbed.osism.xyz",children:"https://flower.testbed.osism.xyz"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}}),(0,n.jsx)(t.td,{style:{textAlign:"left"}}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Grafana"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"https://api-int.testbed.osism.xyz:3000",children:"https://api-int.testbed.osism.xyz:3000"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"admin"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"HAProxy (testbed-node-0)"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"http://testbed-node-0.testbed.osism.xyz:1984",children:"http://testbed-node-0.testbed.osism.xyz:1984"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"openstack"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"HAProxy (testbed-node-1)"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"http://testbed-node-1.testbed.osism.xyz:1984",children:"http://testbed-node-1.testbed.osism.xyz:1984"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"openstack"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"HAProxy (testbed-node-2)"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"http://testbed-node-2.testbed.osism.xyz:1984",children:"http://testbed-node-2.testbed.osism.xyz:1984"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"openstack"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Homer"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"https://homer.testbed.osism.xyz",children:"https://homer.testbed.osism.xyz"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}}),(0,n.jsx)(t.td,{style:{textAlign:"left"}}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Horizon (via Keycloak)"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"https://api.testbed.osism.xyz",children:"https://api.testbed.osism.xyz"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"alice"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Horizon (via Keystone)"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"https://api.testbed.osism.xyz",children:"https://api.testbed.osism.xyz"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"admin"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"domain: default"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Horizon (via Keystone)"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"https://api.testbed.osism.xyz",children:"https://api.testbed.osism.xyz"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"test"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"test"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"domain: test"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Keycloak"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"https://keycloak.testbed.osism.xyz/auth",children:"https://keycloak.testbed.osism.xyz/auth"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"admin"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Netbox"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"https://netbox.testbed.osism.xyz",children:"https://netbox.testbed.osism.xyz"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"admin"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Netdata"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"http://testbed-manager.testbed.osism.xyz:19999",children:"http://testbed-manager.testbed.osism.xyz:19999"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}}),(0,n.jsx)(t.td,{style:{textAlign:"left"}}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Nexus"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"https://nexus.testbed.osism.xyz",children:"https://nexus.testbed.osism.xyz"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"admin"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"OpenSearch Dashboards"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"https://api.testbed.osism.xyz:5601",children:"https://api.testbed.osism.xyz:5601"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"opensearch"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Prometheus"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"https://api-int.testbed.osism.xyz:9091",children:"https://api-int.testbed.osism.xyz:9091"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"admin"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"RabbitMQ"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"https://api-int.testbed.osism.xyz:15672",children:"https://api-int.testbed.osism.xyz:15672"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"openstack"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"phpMyAdmin"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"https://phpmyadmin.testbed.osism.xyz",children:"https://phpmyadmin.testbed.osism.xyz"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"root"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]})]})]}),"\n",(0,n.jsx)(t.h3,{id:"authentication-with-oidc",children:"Authentication with OIDC"}),"\n",(0,n.jsx)(t.p,{children:"Authentication with OpenID Connect (OIDC) is possible via Keycloak, which is automatically configured for the OIDC mechanism."}),"\n",(0,n.jsx)(t.h4,{id:"openstack-web-dashboard-horizon-login-via-oidc",children:"OpenStack web dashboard (Horizon) login via OIDC"}),"\n",(0,n.jsxs)(t.p,{children:["For logging in via OIDC, open your browser at OpenStack Dashboard Login Page, select ",(0,n.jsx)(t.strong,{children:"Authenticate via Keycloak"}),", after being\nredirected to the Keycloak login page, perform the login with the credentials ",(0,n.jsx)(t.strong,{children:"alice"})," and ",(0,n.jsx)(t.strong,{children:"password"}),".\nAfter that you will be redirected back to the Horizon dashboard, where you will be logged in with the user ",(0,n.jsx)(t.strong,{children:"alice"}),"."]}),"\n",(0,n.jsx)(t.h4,{id:"openstack-web-dashboard-horizon-logout",children:"OpenStack web dashboard (Horizon) logout"}),"\n",(0,n.jsxs)(t.p,{children:["Keep in mind, that clicking ",(0,n.jsx)(t.strong,{children:"Sign Out"})," on the Horizon dashboard currently doesn't revoke your OIDC token, and any consequent\nattempt to ",(0,n.jsx)(t.strong,{children:"Authenticate via Keycloak"})," will succeed without providing the credentials."]}),"\n",(0,n.jsx)(t.p,{children:"The expiration time of the Single Sign On tokens can be controlled on multiple levels in Keycloak."}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:["On realm level under ",(0,n.jsx)(t.em,{children:"Realm Settings"})," > ",(0,n.jsx)(t.em,{children:"Tokens"}),".\nAssuming the ",(0,n.jsx)(t.em,{children:"keycloak_realm"})," ansible variable is the default ",(0,n.jsx)(t.em,{children:"osism"}),", and keycloak is listening on\n",(0,n.jsx)(t.a,{href:"https://keycloak.testbed.osism.xyz",children:"keycloak.testbed.osism.xyz"}),", then the configuration form is available\n",(0,n.jsx)(t.a,{href:"https://keycloak.testbed.osism.xyz/auth/admin/master/console/#/realms/osism/token-settings",children:"here"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:["Detailed information is available in the Keycloak Server Administrator Documentation\n",(0,n.jsx)(t.a,{href:"https://www.keycloak.org/docs/latest/server_admin/#_timeouts",children:"Session and Token Timeouts"})," section."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:["In a realm down on the ",(0,n.jsx)(t.a,{href:"https://keycloak.testbed.osism.xyz/auth/admin/master/console/#/realms/osism/clients",children:"client level"}),"\nselect the client (keystone), and under ",(0,n.jsx)(t.em,{children:"Settings"})," > ",(0,n.jsx)(t.em,{children:"Advanced Settings"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:["It is recommended to keep the ",(0,n.jsx)(t.em,{children:"Access Token Lifespan"})," on a relatively low value, with the trend of blocking third party\ncookies. For further information see the Keycloak documentation's ",(0,n.jsx)(t.a,{href:"https://www.keycloak.org/docs/latest/securing_apps/#browsers-with-blocked-third-party-cookies",children:"Browsers with Blocked Third-Party Cookies"})," section."]}),"\n"]}),"\n"]}),"\n",(0,n.jsx)(t.h4,{id:"usage-of-the-openstack-cli",children:"Usage of the OpenStack CLI"}),"\n",(0,n.jsxs)(t.p,{children:["The ",(0,n.jsx)(t.code,{children:"environments/openstack"})," folder contains the needed files for the openstack client:"]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"cd environments/openstack\nexport OS_CLOUD= # i.e. admin\nopenstack floating ip list\n"})}),"\n",(0,n.jsx)(t.h4,{id:"openstack-cli-operations-with-openid-connect-password",children:"OpenStack CLI operations with OpenID Connect password"}),"\n",(0,n.jsxs)(t.p,{children:["Using the OpenStack cli is also possible via OIDC, assuming you provisioned the user ",(0,n.jsx)(t.strong,{children:"alice"})," with password ",(0,n.jsx)(t.strong,{children:"password"}),",\nthen you can perform a simple ",(0,n.jsx)(t.code,{children:"project list"})," operation like this:"]}),"\n",(0,n.jsx)(t.p,{children:'See chapter "Usage the OpenStack CLI" for basic openstack usage.'}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"openstack \\\n --os-cacert /etc/ssl/certs/ca-certificates.crt \\\n --os-auth-url https://api.testbed.osism.xyz:5000/v3 \\\n --os-auth-type v3oidcpassword \\\n --os-client-id keystone \\\n --os-client-secret 0056b89c-030f-486b-a6ad-f0fa398fa4ad \\\n --os-username alice \\\n --os-password password \\\n --os-identity-provider keycloak \\\n --os-protocol openid \\\n --os-identity-api-version 3 \\\n --os-discovery-endpoint https://keycloak.testbed.osism.xyz/auth/realms/osism/.well-known/openid-configuration \\\nproject list\n"})}),"\n",(0,n.jsx)(t.h4,{id:"openstack-cli-token-issue-with-openid-connect",children:"OpenStack CLI token issue with OpenID Connect"}),"\n",(0,n.jsxs)(t.p,{children:["It is also possible to exchange your username/password to a token, for further use with the cli.\nThe ",(0,n.jsx)(t.code,{children:"token issue"})," subcommand returns an SQL table, in which the ",(0,n.jsx)(t.code,{children:"id"})," column's ",(0,n.jsx)(t.code,{children:"value"})," field contains the token:"]}),"\n",(0,n.jsx)(t.p,{children:'See chapter "Usage the OpenStack CLI" for basic openstack usage.'}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:'openstack \\\n --os-cacert /etc/ssl/certs/ca-certificates.crt \\\n --os-auth-url https://api.testbed.osism.xyz:5000/v3 \\\n --os-auth-type v3oidcpassword \\\n --os-client-id keystone \\\n --os-client-secret 0056b89c-030f-486b-a6ad-f0fa398fa4ad \\\n --os-username alice \\\n --os-password password \\\n --os-identity-provider keycloak \\\n --os-protocol openid \\\n --os-identity-api-version 3 \\\n --os-discovery-endpoint https://keycloak.testbed.osism.xyz/auth/realms/osism/.well-known/openid-configuration \\\n --os-openid-scope "openid profile email" \\\ntoken issue \\\n -c id\n -f value\n'})}),"\n",(0,n.jsx)(t.p,{children:"An example token is like:"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"gAAAAABhC98gL8nsQWknro3JWDXWLFCG3CDr3Mi9OIlvVAZMjy2mNgYtlXv_0yAIy-\nnSlLAaLIGhht17-mwf8uclKgRuNVsYLSmgUpB163l89-ch2w2_OFe9zNSQNWf4qfd8\nCl7E7XvvUoFr1N8Gh09vaYLvRvYgCGV05xBUSs76qCHa0qElPUsk56s5ft4ALrSrzD\n4cEQRVb5PXNjywdZk9_gtJziz31A7sD4LPIy82O5N9NryDoDw\n"})}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"TODO: OpenStack CLI operations with token"}),"\n",(0,n.jsx)(t.li,{children:"TODO: OpenStack CLI token revoke"}),"\n"]}),"\n",(0,n.jsx)(t.h2,{id:"advanced-usage",children:"Advanced Usage"}),"\n",(0,n.jsx)(t.h3,{id:"external-api",children:"External API"}),"\n",(0,n.jsxs)(t.p,{children:["It is possible to provide the OpenStack APIs and the OpenStack Dashboard via the manager's public IP address.\nThis is not enabled by default, with the exception of the OTC profile. To provide the OpenStack APIs and the\nOpenStack dashboard via the public IP address of the manager, the following changes are necessary in the\n",(0,n.jsx)(t.code,{children:"terraform/environments/regiocloud.tfvars"})," file. If a cloud other than the REGIO.cloud is used, the profile\nof the other cloud is changed accordingly."]}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:["Add the customisation ",(0,n.jsx)(t.code,{children:"external_api"}),". This customisation makes sure that the required security group rules\nare created for the various OpenStack APIs and the OpenStack dashboard."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"# customisation:external_api\n"})}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:["Set parameter ",(0,n.jsx)(t.code,{children:"external_api"})," to ",(0,n.jsx)(t.code,{children:"true"}),". This makes sure that all necessary changes are made in the configuration\nrepository when the Manager service is deployed. It is correct that this is added as a comment."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"external_api = true\n"})}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:["After the deployment of the Manager service and the OpenStack services, the OpenStack APIs and the OpenStack\ndashboard can be reached via a DNS name. The service ",(0,n.jsx)(t.a,{href:"https://traefik.me",children:"traefik.me"})," is used for the DNS record.\nRun the following two commands on the manager node to get the DNS record."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:'$ source /opt/manager-vars.sh\n$ echo "api-${MANAGER_PUBLIC_IP_ADDRESS//./-}.traefik.me"\napi-80-158-46-219.traefik.me\n'})}),"\n"]}),"\n"]}),"\n",(0,n.jsx)(t.h3,{id:"change-versions",children:"Change versions"}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsxs)(t.li,{children:["Go to ",(0,n.jsx)(t.code,{children:"/opt/configuration"})," on ",(0,n.jsx)(t.code,{children:"testbed-manager"})]}),"\n",(0,n.jsxs)(t.li,{children:["Run ",(0,n.jsx)(t.code,{children:"./scripts/set-openstack-version.sh 2023.2"})," to set the OpenStack version to ",(0,n.jsx)(t.code,{children:"2023.2"})]}),"\n",(0,n.jsxs)(t.li,{children:["Run ",(0,n.jsx)(t.code,{children:"./scripts/set-ceph-version.sh reef"})," to set the Ceph version to ",(0,n.jsx)(t.code,{children:"reef"})]}),"\n",(0,n.jsxs)(t.li,{children:["Run ",(0,n.jsx)(t.code,{children:"osism update manager"})," to update the Manager service"]}),"\n"]}),"\n",(0,n.jsx)(t.h3,{id:"deploy-services",children:"Deploy services"}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Script"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Description"})]})}),(0,n.jsxs)(t.tbody,{children:[(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/deploy/000-manager-service.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/deploy/001-helper-services.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/deploy/100-ceph-services-basic.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"alternative to ceph"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/deploy/100-rook-services-basic.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/deploy/200-infrastructure-services-basic.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/deploy/210-infrastructure-services-extended.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/deploy/300-openstack-services-basic.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/deploy/310-openstack-services-extended.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/deploy/320-openstack-services-baremetal.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/deploy/330-openstack-services-additional.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/deploy/400-monitoring-services.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]})]})]}),"\n",(0,n.jsx)(t.h3,{id:"upgrade-services",children:"Upgrade services"}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Script"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Description"})]})}),(0,n.jsxs)(t.tbody,{children:[(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/upgrade/100-ceph-services.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/upgrade/100-rook-services.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"alternative to ceph"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/upgrade/200-infrastructure-services-basic.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/upgrade/300-openstack-services-basic.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/upgrade/310-openstack-services-extended.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/upgrade/320-openstack-services-baremetal.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/upgrade/330-openstack-services-additional.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]})]})]}),"\n",(0,n.jsx)(t.h3,{id:"ceph-via-rook-technical-preview",children:"Ceph via Rook (technical preview)"}),"\n",(0,n.jsxs)(t.p,{children:["Please have a look at ",(0,n.jsx)(t.a,{href:"/docs/guides/deploy-guide/services/rook",children:"Deploy Guide - Services - Rook"})," and ",(0,n.jsx)(t.a,{href:"/docs/guides/configuration-guide/rook",children:"Configuration Guide - Rook"})," for details on how to configure Rook."]}),"\n",(0,n.jsx)(t.p,{children:"To deploy this in the testbed, you can use an environment variable in your make target."}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"make CEPH_STACK=rook manager\nmake CEPH_STACK=rook ceph\n"})}),"\n",(0,n.jsxs)(t.p,{children:["This will make sure ",(0,n.jsx)(t.code,{children:"/opt/manager-vars.sh"})," gets ",(0,n.jsx)(t.code,{children:"CEPH_STACK=rook"})," set which is later being used by:"]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/deploy-services.sh\n/opt/configuration/scripts/deploy-ceph-services.sh\n/opt/configuration/scripts/upgrade/100-rook-services.sh\n"})}),"\n",(0,n.jsx)(t.h2,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,n.jsx)(t.h3,{id:"ansible-errors",children:"Ansible errors"}),"\n",(0,n.jsxs)(t.p,{children:["Ansible errors that have something to do with undefined variables (e.g. ",(0,n.jsx)(t.code,{children:"AnsibleUndefined"}),") are most likely due to cached\nfacts that are no longer valid. The facts can be updated by running ",(0,n.jsx)(t.code,{children:"osism apply facts"}),"."]}),"\n",(0,n.jsx)(t.h3,{id:"unsupported-locale-setting",children:"Unsupported locale setting"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"$ make prepare\nansible-playbook -i localhost, ansible/check-local-versions.yml\nERROR: Ansible could not initialize the preferred locale: unsupported locale setting\nmake: *** [prepare] Error 1\n"})}),"\n",(0,n.jsxs)(t.p,{children:["To solve the problem you have to modify the ",(0,n.jsx)(t.code,{children:"Makefile"}),". Change the 1st line as follows."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"export LC_ALL=en_US.UTF-8\n"})}),"\n",(0,n.jsxs)(t.p,{children:["To find out the locale used on the system ",(0,n.jsx)(t.code,{children:"printenv"})," can be used."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:'$ printenv | grep -i lang|locale\nLANG="en_US.UTF-8"\nLC_COLLATE="en_US.UTF-8"\nLC_CTYPE="UTF-8"\nLC_MESSAGES="en_US.UTF-8"\nLC_MONETARY="en_US.UTF-8"\nLC_NUMERIC="en_US.UTF-8"\nLC_TIME="en_US.UTF-8"\nLC_ALL=\n'})}),"\n",(0,n.jsx)(t.h2,{id:"appendix",children:"Appendix"}),"\n",(0,n.jsx)(t.h3,{id:"configuration",children:"Configuration"}),"\n",(0,n.jsx)(t.p,{children:"This section describes how to configure and customise the OSISM Testbed."}),"\n",(0,n.jsx)(t.h4,{id:"variables",children:"Variables"}),"\n",(0,n.jsxs)(t.p,{children:["The defaults for the OpenTofu variables are intended for ",(0,n.jsx)(t.a,{href:"https://regio.digital",children:"REGIO.cloud"}),"."]}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Variable"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Default"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Note"})]})}),(0,n.jsxs)(t.tbody,{children:[(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"availability_zone"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"nova"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"ceph_version"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"quincy"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"cloud_provider"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"regiocloud"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"configuration_version"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"main"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"deploy_monitoring"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"false"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"dns_nameservers"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:'["8.8.8.8", "9.9.9.9"]'})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"enable_config_drive"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"true"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"external_api"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"false"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"flavor_manager"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"SCS-4V-16-50"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"flavor_node"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"SCS-8V-32-50"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"image"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"Ubuntu 22.04"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Only Ubuntu 22.04 is currently supported"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"image_node"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"Ubuntu 22.04"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Only Ubuntu 22.04 is currently supported"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"keypair"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"testbed"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"manager_version"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"latest"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"network_availability_zone"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"nova"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"number_of_nodes"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"3"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"number_of_volumes"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"3"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"openstack_version"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"2023.2"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"prefix"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"testbed"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"public"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"external"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"refstack"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"false"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"volume_availability_zone"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"nova"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"volume_size_base"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"30"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"volume_size_storage"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"10"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"volume_type"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"__DEFAULT__"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]})]})]}),"\n",(0,n.jsx)(t.h4,{id:"overrides",children:"Overrides"}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Name"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Description"})]})}),(0,n.jsxs)(t.tbody,{children:[(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"manager_boot_from_image"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"manager_boot_from_volume"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"neutron_availability_zone_hints_network"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"neutron_availability_zone_hints_router"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"neutron_router_enable_snat"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"nodes_boot_from_image"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"nodes_boot_from_volume"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"nodes_use_ephemeral_storage"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]})]})]}),"\n",(0,n.jsx)(t.h4,{id:"customisations",children:"Customisations"}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Name"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Description"})]})}),(0,n.jsxs)(t.tbody,{children:[(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"access_floatingip"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"access_ipv4"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"access_ipv6"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"default"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"external_api"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"neutron_floatingip"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]})]})]}),"\n",(0,n.jsx)(t.h3,{id:"notes",children:"Notes"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"The configuration is intentionally kept quite static. Please create no PRs to make the configuration more flexible/dynamic."}),"\n",(0,n.jsx)(t.li,{children:"The OSISM documentation uses hostnames, examples, addresses etc. from OSISM Testbed."}),"\n",(0,n.jsxs)(t.li,{children:["The third volume (",(0,n.jsx)(t.code,{children:"/dev/sdd"}),") is not enabled for Ceph by default. This is to test the scaling of Ceph."]}),"\n",(0,n.jsx)(t.li,{children:"The manager is used as pull through cache for Docker images and Ubuntu packages. This reduces the amount of traffic consumed."}),"\n"]}),"\n",(0,n.jsx)(t.h3,{id:"supported-releases",children:"Supported releases"}),"\n",(0,n.jsx)(t.p,{children:"The following stable Ceph and OpenStack releases are supported."}),"\n",(0,n.jsxs)(t.p,{children:["The deployment of Ceph is based on ",(0,n.jsx)(t.a,{href:"https://docs.ceph.com/ceph-ansible/",children:"ceph-ansible"}),"."]}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["Ceph Quincy (",(0,n.jsx)(t.strong,{children:"default"}),")"]}),"\n",(0,n.jsx)(t.li,{children:"Ceph Reef"}),"\n"]}),"\n",(0,n.jsxs)(t.p,{children:["The deployment of OpenStack is based on ",(0,n.jsx)(t.a,{href:"https://docs.openstack.org/kolla-ansible/latest/",children:"kolla-ansible"}),"."]}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"OpenStack 2023.1"}),"\n",(0,n.jsxs)(t.li,{children:["OpenStack 2023.2 (",(0,n.jsx)(t.strong,{children:"default"}),")"]}),"\n",(0,n.jsx)(t.li,{children:"OpenStack 2024.1"}),"\n"]}),"\n",(0,n.jsxs)(t.p,{children:["The deployment of Kubernetes is based on ",(0,n.jsx)(t.a,{href:"https://github.com/techno-tim/k3s-ansible",children:"k3s-ansible"}),"."]}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["Kubernetes v1.29 (",(0,n.jsx)(t.strong,{children:"default"}),")"]}),"\n"]}),"\n",(0,n.jsx)(t.h3,{id:"included-services",children:"Included services"}),"\n",(0,n.jsx)(t.p,{children:"The following services can currently be used with the OSISM Testbed without further adjustments."}),"\n",(0,n.jsx)(t.h4,{id:"infrastructure",children:"Infrastructure"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"Ceph"}),"\n",(0,n.jsx)(t.li,{children:"Cluster API Management Cluster"}),"\n",(0,n.jsx)(t.li,{children:"Fluentd"}),"\n",(0,n.jsx)(t.li,{children:"Gnocchi"}),"\n",(0,n.jsx)(t.li,{children:"Grafana"}),"\n",(0,n.jsx)(t.li,{children:"Haproxy"}),"\n",(0,n.jsx)(t.li,{children:"Influxdb"}),"\n",(0,n.jsx)(t.li,{children:"Keepalived"}),"\n",(0,n.jsx)(t.li,{children:"Keycloak"}),"\n",(0,n.jsx)(t.li,{children:"Kubernetes"}),"\n",(0,n.jsx)(t.li,{children:"Mariadb"}),"\n",(0,n.jsx)(t.li,{children:"Memcached"}),"\n",(0,n.jsx)(t.li,{children:"Netbox"}),"\n",(0,n.jsx)(t.li,{children:"Netdata"}),"\n",(0,n.jsx)(t.li,{children:"Opensearch"}),"\n",(0,n.jsx)(t.li,{children:"Openvswitch"}),"\n",(0,n.jsx)(t.li,{children:"Patchman"}),"\n",(0,n.jsx)(t.li,{children:"Prometheus exporters"}),"\n",(0,n.jsx)(t.li,{children:"Rabbitmq"}),"\n",(0,n.jsx)(t.li,{children:"Redis"}),"\n"]}),"\n",(0,n.jsx)(t.h4,{id:"openstack",children:"OpenStack"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"Barbican"}),"\n",(0,n.jsx)(t.li,{children:"Ceilometer"}),"\n",(0,n.jsx)(t.li,{children:"Cinder"}),"\n",(0,n.jsx)(t.li,{children:"Designate"}),"\n",(0,n.jsx)(t.li,{children:"Glance"}),"\n",(0,n.jsx)(t.li,{children:"Heat"}),"\n",(0,n.jsx)(t.li,{children:"Horizon"}),"\n",(0,n.jsx)(t.li,{children:"Ironic"}),"\n",(0,n.jsx)(t.li,{children:"Keystone"}),"\n",(0,n.jsx)(t.li,{children:"Magnum"}),"\n",(0,n.jsx)(t.li,{children:"Manila"}),"\n",(0,n.jsx)(t.li,{children:"Neutron"}),"\n",(0,n.jsx)(t.li,{children:"Nova (with Libvirt/KVM)"}),"\n",(0,n.jsx)(t.li,{children:"Octavia"}),"\n",(0,n.jsx)(t.li,{children:"Senlin"}),"\n",(0,n.jsx)(t.li,{children:"Skyline"}),"\n"]}),"\n",(0,n.jsx)(t.h3,{id:"makefile-reference",children:"Makefile reference"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"$ make help\n\nUsage:\n make \n help Display this help.\n clean Destroy infrastructure with OpenTofu.\n wipe-local-install Wipe the software dependencies in `venv`.\n create Create required infrastructure with OpenTofu.\n login Log in on the manager.\n vpn-wireguard Establish a wireguard vpn tunnel.\n vpn-sshuttle Establish a sshuttle vpn tunnel.\n bootstrap Bootstrap everything.\n manager Deploy only the manager service.\n identity Deploy only identity services.\n ceph Deploy only ceph services.\n deploy Deploy everything and then check it.\n prepare Run local preperations.\n deps Install software preconditions to `venv`.\n\n$ make \n"})}),"\n",(0,n.jsx)(t.h3,{id:"ci-jobs",children:"CI jobs"}),"\n",(0,n.jsxs)(t.p,{children:["You can inspect the ",(0,n.jsx)(t.a,{href:"https://zuul.services.betacloud.xyz/t/osism/builds?project=osism%2Ftestbed&skip=0",children:"results of the daily zuul jobs"}),"."]}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Name"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Description"})]})}),(0,n.jsxs)(t.tbody,{children:[(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"testbed-deploy"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"testbed-deploy-ceph"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"testbed-deploy-stable"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"testbed-update-stable"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"testbed-upgrade"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"testbed-upgrade-ceph"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"testbed-upgrade-stable"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]})]})]})]})}function u(e={}){const{wrapper:t}={...(0,l.a)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(x,{...e})}):x(e)}},5162:(e,t,s)=>{s.d(t,{Z:()=>r});s(7294);var n=s(6905);const l={tabItem:"tabItem_Ymn6"};var i=s(5893);function r(e){let{children:t,hidden:s,className:r}=e;return(0,i.jsx)("div",{role:"tabpanel",className:(0,n.Z)(l.tabItem,r),hidden:s,children:t})}},4866:(e,t,s)=>{s.d(t,{Z:()=>v});var n=s(7294),l=s(6905),i=s(2466),r=s(6550),d=s(469),c=s(1980),o=s(7392),a=s(812);function h(e){return n.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,n.isValidElement)(e)&&function(e){const{props:t}=e;return!!t&&"object"==typeof t&&"value"in t}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function x(e){const{values:t,children:s}=e;return(0,n.useMemo)((()=>{const e=t??function(e){return h(e).map((e=>{let{props:{value:t,label:s,attributes:n,default:l}}=e;return{value:t,label:s,attributes:n,default:l}}))}(s);return function(e){const t=(0,o.l)(e,((e,t)=>e.value===t.value));if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[t,s])}function u(e){let{value:t,tabValues:s}=e;return s.some((e=>e.value===t))}function p(e){let{queryString:t=!1,groupId:s}=e;const l=(0,r.k6)(),i=function(e){let{queryString:t=!1,groupId:s}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!s)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return s??null}({queryString:t,groupId:s});return[(0,c._X)(i),(0,n.useCallback)((e=>{if(!i)return;const t=new URLSearchParams(l.location.search);t.set(i,e),l.replace({...l.location,search:t.toString()})}),[i,l])]}function j(e){const{defaultValue:t,queryString:s=!1,groupId:l}=e,i=x(e),[r,c]=(0,n.useState)((()=>function(e){let{defaultValue:t,tabValues:s}=e;if(0===s.length)throw new Error("Docusaurus error: the component requires at least one children component");if(t){if(!u({value:t,tabValues:s}))throw new Error(`Docusaurus error: The has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${s.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const n=s.find((e=>e.default))??s[0];if(!n)throw new Error("Unexpected error: 0 tabValues");return n.value}({defaultValue:t,tabValues:i}))),[o,h]=p({queryString:s,groupId:l}),[j,f]=function(e){let{groupId:t}=e;const s=function(e){return e?`docusaurus.tab.${e}`:null}(t),[l,i]=(0,a.Nk)(s);return[l,(0,n.useCallback)((e=>{s&&i.set(e)}),[s,i])]}({groupId:l}),g=(()=>{const e=o??j;return u({value:e,tabValues:i})?e:null})();(0,d.Z)((()=>{g&&c(g)}),[g]);return{selectedValue:r,selectValue:(0,n.useCallback)((e=>{if(!u({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);c(e),h(e),f(e)}),[h,f,i]),tabValues:i}}var f=s(2389);const g={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var y=s(5893);function m(e){let{className:t,block:s,selectedValue:n,selectValue:r,tabValues:d}=e;const c=[],{blockElementScrollPositionUntilNextRender:o}=(0,i.o5)(),a=e=>{const t=e.currentTarget,s=c.indexOf(t),l=d[s].value;l!==n&&(o(t),r(l))},h=e=>{let t=null;switch(e.key){case"Enter":a(e);break;case"ArrowRight":{const s=c.indexOf(e.currentTarget)+1;t=c[s]??c[0];break}case"ArrowLeft":{const s=c.indexOf(e.currentTarget)-1;t=c[s]??c[c.length-1];break}}t?.focus()};return(0,y.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,l.Z)("tabs",{"tabs--block":s},t),children:d.map((e=>{let{value:t,label:s,attributes:i}=e;return(0,y.jsx)("li",{role:"tab",tabIndex:n===t?0:-1,"aria-selected":n===t,ref:e=>c.push(e),onKeyDown:h,onClick:a,...i,className:(0,l.Z)("tabs__item",g.tabItem,i?.className,{"tabs__item--active":n===t}),children:s??t},t)}))})}function b(e){let{lazy:t,children:s,selectedValue:l}=e;const i=(Array.isArray(s)?s:[s]).filter(Boolean);if(t){const e=i.find((e=>e.props.value===l));return e?(0,n.cloneElement)(e,{className:"margin-top--md"}):null}return(0,y.jsx)("div",{className:"margin-top--md",children:i.map(((e,t)=>(0,n.cloneElement)(e,{key:t,hidden:e.props.value!==l})))})}function A(e){const t=j(e);return(0,y.jsxs)("div",{className:(0,l.Z)("tabs-container",g.tabList),children:[(0,y.jsx)(m,{...t,...e}),(0,y.jsx)(b,{...t,...e})]})}function v(e){const t=(0,f.Z)();return(0,y.jsx)(A,{...e,children:h(e.children)},String(t))}},1151:(e,t,s)=>{s.d(t,{Z:()=>d,a:()=>r});var n=s(7294);const l={},i=n.createContext(l);function r(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function d(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(l):e.components||l:r(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/78b4ae99.362b3977.js b/assets/js/78b4ae99.362b3977.js deleted file mode 100644 index 9af0ac3ebd..0000000000 --- a/assets/js/78b4ae99.362b3977.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkosism=self.webpackChunkosism||[]).push([[2681],{3112:(e,o,a)=>{a.r(o),a.d(o,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>s,metadata:()=>r,toc:()=>l});var t=a(5893),n=a(1151);const s={sidebar_label:"Octavia"},i="Octavia",r={id:"guides/operations-guide/openstack/octavia",title:"Octavia",description:"Cleanup of amphorae missing from the DB",source:"@site/docs/guides/operations-guide/openstack/octavia.md",sourceDirName:"guides/operations-guide/openstack",slug:"/guides/operations-guide/openstack/octavia",permalink:"/docs/guides/operations-guide/openstack/octavia",draft:!1,unlisted:!1,editUrl:"https://github.com/osism/osism.github.io/tree/main/docs/guides/operations-guide/openstack/octavia.md",tags:[],version:"current",frontMatter:{sidebar_label:"Octavia"},sidebar:"tutorialSidebar",previous:{title:"Nova",permalink:"/docs/guides/operations-guide/openstack/nova"},next:{title:"Troubleshooting Guide",permalink:"/docs/guides/troubleshooting-guide/"}},c={},l=[{value:"Cleanup of amphorae missing from the DB",id:"cleanup-of-amphorae-missing-from-the-db",level:2},{value:"SSH access to amphorae",id:"ssh-access-to-amphorae",level:2}];function d(e){const o={code:"code",h1:"h1",h2:"h2",li:"li",ol:"ol",p:"p",pre:"pre",...(0,n.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(o.h1,{id:"octavia",children:"Octavia"}),"\n",(0,t.jsx)(o.h2,{id:"cleanup-of-amphorae-missing-from-the-db",children:"Cleanup of amphorae missing from the DB"}),"\n",(0,t.jsx)(o.pre,{children:(0,t.jsx)(o.code,{className:"language-none",metastring:'title="/var/log/kolla/octavia/octavia-health-manager.log"',children:"2023-10-25 16:43:52.547 22 WARNING octavia.amphorae.drivers.health.heartbeat_udp [-]\nThe amphora 2a33a889-4f9a-4340-84a5-e58a7a8af17e with IP 10.1.0.79 is missing from the\nDB, so it cannot be automatically deleted (the compute_id is unknown). An operator must\nmanually delete it from the compute service.\n"})}),"\n",(0,t.jsx)(o.h2,{id:"ssh-access-to-amphorae",children:"SSH access to amphorae"}),"\n",(0,t.jsxs)(o.ol,{children:["\n",(0,t.jsxs)(o.li,{children:["\n",(0,t.jsxs)(o.p,{children:["Get the local IP address (",(0,t.jsx)(o.code,{children:"lb_network_ip"}),") of the amphora you want to access via\n",(0,t.jsx)(o.code,{children:"openstack --os-cloud admin loadbalancer amphora list"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(o.li,{children:["\n",(0,t.jsx)(o.p,{children:"Connect to one of the nodes that you use for Octavia. Normally the control-\nor network nodes."}),"\n"]}),"\n",(0,t.jsxs)(o.li,{children:["\n",(0,t.jsxs)(o.p,{children:["You can now use SSH to access the amphora. The use of sudo is required here because\nyou cannot access ",(0,t.jsx)(o.code,{children:"/etc/kolla/octavia-worker/octavia_ssh_key"})," with the operator user\naccount. Replace ",(0,t.jsx)(o.code,{children:"lb_network_ip"})," with the local IP address of the amphora."]}),"\n",(0,t.jsx)(o.pre,{children:(0,t.jsx)(o.code,{children:"sudo ssh -i /etc/kolla/octavia-worker/octavia_ssh_key ubuntu@lb_network_ip\n"})}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:o}={...(0,n.a)(),...e.components};return o?(0,t.jsx)(o,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},1151:(e,o,a)=>{a.d(o,{Z:()=>r,a:()=>i});var t=a(7294);const n={},s=t.createContext(n);function i(e){const o=t.useContext(s);return t.useMemo((function(){return"function"==typeof e?e(o):{...o,...e}}),[o,e])}function r(e){let o;return o=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:i(e.components),t.createElement(s.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/78b4ae99.c07703fc.js b/assets/js/78b4ae99.c07703fc.js new file mode 100644 index 0000000000..3d52c00af8 --- /dev/null +++ b/assets/js/78b4ae99.c07703fc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkosism=self.webpackChunkosism||[]).push([[2681],{3112:(e,o,a)=>{a.r(o),a.d(o,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>s,metadata:()=>r,toc:()=>l});var t=a(5893),n=a(1151);const s={sidebar_label:"Octavia"},i="Octavia",r={id:"guides/operations-guide/openstack/octavia",title:"Octavia",description:"Cleanup of amphorae missing from the DB",source:"@site/docs/guides/operations-guide/openstack/octavia.md",sourceDirName:"guides/operations-guide/openstack",slug:"/guides/operations-guide/openstack/octavia",permalink:"/docs/guides/operations-guide/openstack/octavia",draft:!1,unlisted:!1,editUrl:"https://github.com/osism/osism.github.io/tree/main/docs/guides/operations-guide/openstack/octavia.md",tags:[],version:"current",frontMatter:{sidebar_label:"Octavia"},sidebar:"tutorialSidebar",previous:{title:"Nova",permalink:"/docs/guides/operations-guide/openstack/nova"},next:{title:"Ceph via Rook (technical preview)",permalink:"/docs/guides/operations-guide/rook"}},c={},l=[{value:"Cleanup of amphorae missing from the DB",id:"cleanup-of-amphorae-missing-from-the-db",level:2},{value:"SSH access to amphorae",id:"ssh-access-to-amphorae",level:2}];function d(e){const o={code:"code",h1:"h1",h2:"h2",li:"li",ol:"ol",p:"p",pre:"pre",...(0,n.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(o.h1,{id:"octavia",children:"Octavia"}),"\n",(0,t.jsx)(o.h2,{id:"cleanup-of-amphorae-missing-from-the-db",children:"Cleanup of amphorae missing from the DB"}),"\n",(0,t.jsx)(o.pre,{children:(0,t.jsx)(o.code,{className:"language-none",metastring:'title="/var/log/kolla/octavia/octavia-health-manager.log"',children:"2023-10-25 16:43:52.547 22 WARNING octavia.amphorae.drivers.health.heartbeat_udp [-]\nThe amphora 2a33a889-4f9a-4340-84a5-e58a7a8af17e with IP 10.1.0.79 is missing from the\nDB, so it cannot be automatically deleted (the compute_id is unknown). An operator must\nmanually delete it from the compute service.\n"})}),"\n",(0,t.jsx)(o.h2,{id:"ssh-access-to-amphorae",children:"SSH access to amphorae"}),"\n",(0,t.jsxs)(o.ol,{children:["\n",(0,t.jsxs)(o.li,{children:["\n",(0,t.jsxs)(o.p,{children:["Get the local IP address (",(0,t.jsx)(o.code,{children:"lb_network_ip"}),") of the amphora you want to access via\n",(0,t.jsx)(o.code,{children:"openstack --os-cloud admin loadbalancer amphora list"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(o.li,{children:["\n",(0,t.jsx)(o.p,{children:"Connect to one of the nodes that you use for Octavia. Normally the control-\nor network nodes."}),"\n"]}),"\n",(0,t.jsxs)(o.li,{children:["\n",(0,t.jsxs)(o.p,{children:["You can now use SSH to access the amphora. The use of sudo is required here because\nyou cannot access ",(0,t.jsx)(o.code,{children:"/etc/kolla/octavia-worker/octavia_ssh_key"})," with the operator user\naccount. Replace ",(0,t.jsx)(o.code,{children:"lb_network_ip"})," with the local IP address of the amphora."]}),"\n",(0,t.jsx)(o.pre,{children:(0,t.jsx)(o.code,{children:"sudo ssh -i /etc/kolla/octavia-worker/octavia_ssh_key ubuntu@lb_network_ip\n"})}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:o}={...(0,n.a)(),...e.components};return o?(0,t.jsx)(o,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},1151:(e,o,a)=>{a.d(o,{Z:()=>r,a:()=>i});var t=a(7294);const n={},s=t.createContext(n);function i(e){const o=t.useContext(s);return t.useMemo((function(){return"function"==typeof e?e(o):{...o,...e}}),[o,e])}function r(e){let o;return o=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:i(e.components),t.createElement(s.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8e5f32ed.90ba9b85.js b/assets/js/8e5f32ed.90ba9b85.js new file mode 100644 index 0000000000..1a5866e956 --- /dev/null +++ b/assets/js/8e5f32ed.90ba9b85.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkosism=self.webpackChunkosism||[]).push([[1748],{526:(s,o,e)=>{e.r(o),e.d(o,{assets:()=>d,contentTitle:()=>c,default:()=>l,frontMatter:()=>i,metadata:()=>r,toc:()=>m});var n=e(5893),t=e(1151);const i={sidebar_label:"Commons",sidebar_position:50},c="Commons",r={id:"guides/configuration-guide/commons/index",title:"Commons",description:"This section contains the documentation of the Ansible collection osism.commons.",source:"@site/docs/guides/configuration-guide/commons/index.md",sourceDirName:"guides/configuration-guide/commons",slug:"/guides/configuration-guide/commons/",permalink:"/docs/guides/configuration-guide/commons/",draft:!1,unlisted:!1,editUrl:"https://github.com/osism/osism.github.io/tree/main/docs/guides/configuration-guide/commons/index.md",tags:[],version:"current",sidebarPosition:50,frontMatter:{sidebar_label:"Commons",sidebar_position:50},sidebar:"tutorialSidebar",previous:{title:"Ceph via Rook (technical preview)",permalink:"/docs/guides/configuration-guide/rook"},next:{title:"Certificates",permalink:"/docs/guides/configuration-guide/commons/certificates"}},d={},m=[];function a(s){const o={a:"a",h1:"h1",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,t.a)(),...s.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(o.h1,{id:"commons",children:"Commons"}),"\n",(0,n.jsxs)(o.p,{children:["This section contains the documentation of the Ansible collection ",(0,n.jsx)(o.a,{href:"https://github.com/osism/ansible-collection-commons",children:"osism.commons"}),"."]}),"\n",(0,n.jsxs)(o.table,{children:[(0,n.jsx)(o.thead,{children:(0,n.jsxs)(o.tr,{children:[(0,n.jsx)(o.th,{children:(0,n.jsx)(o.strong,{children:"Role"})}),(0,n.jsx)(o.th,{children:(0,n.jsx)(o.strong,{children:"Description"})})]})}),(0,n.jsxs)(o.tbody,{children:[(0,n.jsxs)(o.tr,{children:[(0,n.jsx)(o.td,{children:"osism.commons.network"}),(0,n.jsx)(o.td,{})]}),(0,n.jsxs)(o.tr,{children:[(0,n.jsx)(o.td,{children:"osism.commons.packages"}),(0,n.jsx)(o.td,{})]}),(0,n.jsxs)(o.tr,{children:[(0,n.jsx)(o.td,{children:"osism.commons.services"}),(0,n.jsx)(o.td,{})]}),(0,n.jsxs)(o.tr,{children:[(0,n.jsx)(o.td,{children:"osism.commons.sshconfig"}),(0,n.jsx)(o.td,{})]}),(0,n.jsxs)(o.tr,{children:[(0,n.jsx)(o.td,{children:"osism.commons.timezone"}),(0,n.jsx)(o.td,{})]})]})]})]})}function l(s={}){const{wrapper:o}={...(0,t.a)(),...s.components};return o?(0,n.jsx)(o,{...s,children:(0,n.jsx)(a,{...s})}):a(s)}},1151:(s,o,e)=>{e.d(o,{Z:()=>r,a:()=>c});var n=e(7294);const t={},i=n.createContext(t);function c(s){const o=n.useContext(i);return n.useMemo((function(){return"function"==typeof s?s(o):{...o,...s}}),[o,s])}function r(s){let o;return o=s.disableParentContext?"function"==typeof s.components?s.components(t):s.components||t:c(s.components),n.createElement(i.Provider,{value:o},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/8e5f32ed.cdb5aefb.js b/assets/js/8e5f32ed.cdb5aefb.js deleted file mode 100644 index 57892049c2..0000000000 --- a/assets/js/8e5f32ed.cdb5aefb.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkosism=self.webpackChunkosism||[]).push([[1748],{526:(s,o,n)=>{n.r(o),n.d(o,{assets:()=>d,contentTitle:()=>c,default:()=>l,frontMatter:()=>i,metadata:()=>r,toc:()=>m});var e=n(5893),t=n(1151);const i={sidebar_label:"Commons",sidebar_position:50},c="Commons",r={id:"guides/configuration-guide/commons/index",title:"Commons",description:"This section contains the documentation of the Ansible collection osism.commons.",source:"@site/docs/guides/configuration-guide/commons/index.md",sourceDirName:"guides/configuration-guide/commons",slug:"/guides/configuration-guide/commons/",permalink:"/docs/guides/configuration-guide/commons/",draft:!1,unlisted:!1,editUrl:"https://github.com/osism/osism.github.io/tree/main/docs/guides/configuration-guide/commons/index.md",tags:[],version:"current",sidebarPosition:50,frontMatter:{sidebar_label:"Commons",sidebar_position:50},sidebar:"tutorialSidebar",previous:{title:"Skyline",permalink:"/docs/guides/configuration-guide/openstack/skyline"},next:{title:"Certificates",permalink:"/docs/guides/configuration-guide/commons/certificates"}},d={},m=[];function a(s){const o={a:"a",h1:"h1",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,t.a)(),...s.components};return(0,e.jsxs)(e.Fragment,{children:[(0,e.jsx)(o.h1,{id:"commons",children:"Commons"}),"\n",(0,e.jsxs)(o.p,{children:["This section contains the documentation of the Ansible collection ",(0,e.jsx)(o.a,{href:"https://github.com/osism/ansible-collection-commons",children:"osism.commons"}),"."]}),"\n",(0,e.jsxs)(o.table,{children:[(0,e.jsx)(o.thead,{children:(0,e.jsxs)(o.tr,{children:[(0,e.jsx)(o.th,{children:(0,e.jsx)(o.strong,{children:"Role"})}),(0,e.jsx)(o.th,{children:(0,e.jsx)(o.strong,{children:"Description"})})]})}),(0,e.jsxs)(o.tbody,{children:[(0,e.jsxs)(o.tr,{children:[(0,e.jsx)(o.td,{children:"osism.commons.network"}),(0,e.jsx)(o.td,{})]}),(0,e.jsxs)(o.tr,{children:[(0,e.jsx)(o.td,{children:"osism.commons.packages"}),(0,e.jsx)(o.td,{})]}),(0,e.jsxs)(o.tr,{children:[(0,e.jsx)(o.td,{children:"osism.commons.services"}),(0,e.jsx)(o.td,{})]}),(0,e.jsxs)(o.tr,{children:[(0,e.jsx)(o.td,{children:"osism.commons.sshconfig"}),(0,e.jsx)(o.td,{})]}),(0,e.jsxs)(o.tr,{children:[(0,e.jsx)(o.td,{children:"osism.commons.timezone"}),(0,e.jsx)(o.td,{})]})]})]})]})}function l(s={}){const{wrapper:o}={...(0,t.a)(),...s.components};return o?(0,e.jsx)(o,{...s,children:(0,e.jsx)(a,{...s})}):a(s)}},1151:(s,o,n)=>{n.d(o,{Z:()=>r,a:()=>c});var e=n(7294);const t={},i=e.createContext(t);function c(s){const o=e.useContext(i);return e.useMemo((function(){return"function"==typeof s?s(o):{...o,...s}}),[o,s])}function r(s){let o;return o=s.disableParentContext?"function"==typeof s.components?s.components(t):s.components||t:c(s.components),e.createElement(i.Provider,{value:o},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/b82e88c8.1febd88e.js b/assets/js/b82e88c8.1febd88e.js new file mode 100644 index 0000000000..c07025d1f4 --- /dev/null +++ b/assets/js/b82e88c8.1febd88e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkosism=self.webpackChunkosism||[]).push([[3177],{8665:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>l,contentTitle:()=>t,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>d});var s=o(5893),i=o(1151);const r={sidebar_label:"Ceph via Rook (technical preview)"},t="Ceph via Rook (technical preview)",a={id:"guides/operations-guide/rook",title:"Ceph via Rook (technical preview)",description:"This is a technical preview and not recommended for production use yet.",source:"@site/docs/guides/operations-guide/rook.md",sourceDirName:"guides/operations-guide",slug:"/guides/operations-guide/rook",permalink:"/docs/guides/operations-guide/rook",draft:!1,unlisted:!1,editUrl:"https://github.com/osism/osism.github.io/tree/main/docs/guides/operations-guide/rook.md",tags:[],version:"current",frontMatter:{sidebar_label:"Ceph via Rook (technical preview)"},sidebar:"tutorialSidebar",previous:{title:"Octavia",permalink:"/docs/guides/operations-guide/openstack/octavia"},next:{title:"Troubleshooting Guide",permalink:"/docs/guides/troubleshooting-guide/"}},l={},d=[{value:"Where to find docs",id:"where-to-find-docs",level:2},{value:"Advice on Ceph releases",id:"advice-on-ceph-releases",level:2},{value:"Troubleshooting",id:"troubleshooting",level:2},{value:"Updating",id:"updating",level:2},{value:"Rook Upgrades",id:"rook-upgrades",level:3},{value:"Ceph Upgrades",id:"ceph-upgrades",level:3},{value:"General maintenance",id:"general-maintenance",level:2},{value:"60 seconds cluster overview",id:"60-seconds-cluster-overview",level:3},{value:"Mute/Unmute a health warning",id:"muteunmute-a-health-warning",level:3},{value:"Disable/Enable (deep-)scrubbing",id:"disableenable-deep-scrubbing",level:3},{value:"Reboot a single node",id:"reboot-a-single-node",level:3},{value:"Gathering information about block devices",id:"gathering-information-about-block-devices",level:2},{value:"Enumerate typical storage devices and LVM",id:"enumerate-typical-storage-devices-and-lvm",level:3},{value:"SMART data for SATA/SAS and NVME devices",id:"smart-data-for-satasas-and-nvme-devices",level:3},{value:"Check format of a NVME device",id:"check-format-of-a-nvme-device",level:3},{value:"Format a NVME device to a different LBA format using nvme-cli",id:"format-a-nvme-device-to-a-different-lba-format-using-nvme-cli",level:3},{value:"Secure Erase a NVME drive using nvme-cli",id:"secure-erase-a-nvme-drive-using-nvme-cli",level:3},{value:"Secure Erase a SATA/SAS drive using hdparm",id:"secure-erase-a-satasas-drive-using-hdparm",level:3},{value:"OSD maintenance tasks",id:"osd-maintenance-tasks",level:2},{value:"Disable backfills/recovery completely",id:"disable-backfillsrecovery-completely",level:3},{value:"Rebalance OSDs",id:"rebalance-osds",level:3},{value:"Placement Group maintenance",id:"placement-group-maintenance",level:2},{value:"Dump placement groups",id:"dump-placement-groups",level:3},{value:"Query a PG about its status",id:"query-a-pg-about-its-status",level:3},{value:"Start (deep-)scrubbing of a placement group",id:"start-deep-scrubbing-of-a-placement-group",level:3},{value:"HEALTH_WARN - Large omap objects found...",id:"health_warn---large-omap-objects-found",level:3},{value:"Instruct a PG to repair in case of scrub errors (inconsistent PG)",id:"instruct-a-pg-to-repair-in-case-of-scrub-errors-inconsistent-pg",level:3},{value:"RADOS Pool maintenance",id:"rados-pool-maintenance",level:2},{value:"Get pools and their configuration",id:"get-pools-and-their-configuration",level:3},{value:"Dump all CRUSH rules",id:"dump-all-crush-rules",level:3},{value:"Get autoscaler status",id:"get-autoscaler-status",level:3},{value:"Create a replicated pool",id:"create-a-replicated-pool",level:3},{value:"Enabling an application on a pool",id:"enabling-an-application-on-a-pool",level:3},{value:"Delete a pool",id:"delete-a-pool",level:3},{value:"Set number of PGs for a pool",id:"set-number-of-pgs-for-a-pool",level:3},{value:"Create CRUSH rules for different storage classes",id:"create-crush-rules-for-different-storage-classes",level:3},{value:"Change CRUSH rule for a pool ("move pool")",id:"change-crush-rule-for-a-pool-move-pool",level:3},{value:"Advanced topics",id:"advanced-topics",level:2},{value:"Performance benchmark",id:"performance-benchmark",level:2},{value:"Where and how to get further help",id:"where-and-how-to-get-further-help",level:2}];function c(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"ceph-via-rook-technical-preview",children:"Ceph via Rook (technical preview)"}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsx)(n.p,{children:"This is a technical preview and not recommended for production use yet."})}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsx)(n.p,{children:"This whole document has to be reworkded with more rook like handling. Do not take it for granted yet."})}),"\n",(0,s.jsx)(n.h2,{id:"where-to-find-docs",children:"Where to find docs"}),"\n",(0,s.jsxs)(n.p,{children:["The official Rook documentation starts here ",(0,s.jsx)(n.a,{href:"https://rook.io/docs/rook/latest-release/Getting-Started/intro/",children:"https://rook.io/docs/rook/latest-release/Getting-Started/intro/"})]}),"\n",(0,s.jsx)(n.p,{children:"Some sections to point out are:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://rook.io/docs/rook/latest-release/Troubleshooting/common-issues/",children:"Rook Common Issues Documentation"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://rook.io/docs/rook/latest-release/Troubleshooting/ceph-common-issues/",children:"Rook Ceph Common Issues Documentation"})}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The official Ceph documentation is located on ",(0,s.jsx)(n.a,{href:"https://docs.ceph.com/en/latest/rados/operations/",children:"https://docs.ceph.com/en/latest/rados/operations/"})]}),"\n",(0,s.jsxs)(n.p,{children:["It is ",(0,s.jsx)(n.strong,{children:"strongly advised"})," to use the documentation for the version being used."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Quincy - ",(0,s.jsx)(n.a,{href:"https://docs.ceph.com/en/quincy/rados/operations/",children:"https://docs.ceph.com/en/quincy/rados/operations/"})]}),"\n",(0,s.jsxs)(n.li,{children:["Reef - ",(0,s.jsx)(n.a,{href:"https://docs.ceph.com/en/reef/rados/operations/",children:"https://docs.ceph.com/en/reef/rados/operations/"})]}),"\n"]}),"\n",(0,s.jsxs)(n.admonition,{type:"note",children:[(0,s.jsxs)(n.p,{children:["Do not take information in the documentation at face value.\nEspecially when it comes to advanced/rarely used/very new features it is ",(0,s.jsx)(n.strong,{children:"strongly advised"}),"\nto test any claims made in the documentation about any particular feature."]}),(0,s.jsx)(n.p,{children:"Never assume that things will work as written without actually testing it on a test setup\nas close to your real workload scenario as possible."})]}),"\n",(0,s.jsx)(n.h2,{id:"advice-on-ceph-releases",children:"Advice on Ceph releases"}),"\n",(0,s.jsxs)(n.p,{children:["The current Ceph releases and their support status can be found on ",(0,s.jsx)(n.a,{href:"https://docs.ceph.com/en/latest/releases/",children:"https://docs.ceph.com/en/latest/releases/"})]}),"\n",(0,s.jsxs)(n.p,{children:["When a new Ceph stable version is released you are ",(0,s.jsx)(n.strong,{children:"strongly advised"}),"\nto not roll it out on any production cluster whatsoever.\nEven though its listed as \"stable\" it doesn't mean that this is actually true.\nEspecially avoid using .0 releases on anything remotely production\nunless you really, really now what you're doing and can live with a possible catastrophic failure."]}),"\n",(0,s.jsxs)(n.p,{children:["Be ",(0,s.jsx)(n.strong,{children:"very"})," conservative about what version you run on production systems."]}),"\n",(0,s.jsx)(n.p,{children:"Shiny new features aren't worth the risk of total or partial data loss/corruption."}),"\n",(0,s.jsx)(n.h2,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,s.jsxs)(n.p,{children:["Please have a look at the ",(0,s.jsx)(n.a,{href:"https://rook.io/docs/rook/latest-release/Troubleshooting/ceph-toolbox/",children:"Rook Troubleshooting documentation"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["The Rook toolbox is available via the ",(0,s.jsx)(n.code,{children:"ceph"})," command on the manager node, after you deployed the wrapper via ",(0,s.jsx)(n.code,{children:"osism apply cephclient"}),". You have to make sure the correct ",(0,s.jsx)(n.a,{href:"/docs/guides/configuration-guide/rook#client",children:"Configuration Options for the Rook Ceph Client Wrapper"})," are net."]}),"\n",(0,s.jsx)(n.h2,{id:"updating",children:"Updating"}),"\n",(0,s.jsx)(n.h3,{id:"rook-upgrades",children:"Rook Upgrades"}),"\n",(0,s.jsxs)(n.p,{children:["Please have a look at the ",(0,s.jsx)(n.a,{href:"https://rook.io/docs/rook/latest-release/Upgrade/rook-upgrade/",children:"Rook Upgrades documentation"}),". Take note of update instructions specific to your version."]}),"\n",(0,s.jsxs)(n.p,{children:["Usually you can simply update by bumping the ",(0,s.jsx)(n.code,{children:"rook_operator_image_tag"})," ansible variable and applying ",(0,s.jsx)(n.code,{children:"osism apply rook-operator"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"ceph-upgrades",children:"Ceph Upgrades"}),"\n",(0,s.jsxs)(n.p,{children:["Please have a look at the ",(0,s.jsx)(n.a,{href:"https://rook.io/docs/rook/latest-release/Upgrade/ceph-upgrade/",children:"Rook Ceph Upgrades documentation"}),". Take note of update instructions specific to your version."]}),"\n",(0,s.jsxs)(n.p,{children:["Usually you can simply update by bumping the ",(0,s.jsx)(n.code,{children:"rook_ceph_image_tag"})," ansible variable and applying ",(0,s.jsx)(n.code,{children:"osism apply rook"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"general-maintenance",children:"General maintenance"}),"\n",(0,s.jsx)(n.h3,{id:"60-seconds-cluster-overview",children:"60 seconds cluster overview"}),"\n",(0,s.jsx)(n.p,{children:"The following commands can be used to quickly check the status of Ceph:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Print overall cluster status"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"ceph -s\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Print detailed health information"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"ceph health detail\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Display current OSD tree"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"ceph osd tree\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Cluster storage usage by pool and storage class"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"ceph df\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"List pools with detailed configuration"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"ceph osd pool ls detail\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Get usage stats for OSDs"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"ceph osd df {plain|tree} {class e.g. hdd|ssd}\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Watch Ceph health messages sequentially"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"ceph -w\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"List daemon versions running in the cluster"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"ceph versions\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Also you can run the following on each node running ceph-daemons,\nto provide further debug information about the environment:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"# lscpu\n# cat /proc/cpuinfo # if lscpu isn't available\n# free -g\n# ip l\n# ethtool # for each network adapter\n"})}),"\n",(0,s.jsx)(n.h3,{id:"muteunmute-a-health-warning",children:"Mute/Unmute a health warning"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ ceph health mute \n$ ceph health unmute \n"})}),"\n",(0,s.jsx)(n.h3,{id:"disableenable-deep-scrubbing",children:"Disable/Enable (deep-)scrubbing"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ ceph osd set noscrub\n$ ceph osd set nodeep-scrub\n$ ceph osd unset noscrub\n$ ceph osd unset nodeep-scrub\n"})}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsx)(n.p,{children:"Use this sparingly only in emergency situations.\nSetting these flags will cause a HEALTH_WARN status,\nincrease risk of data corruption and also the risk of generating\na HEALTH_WARN due to PGs not being (deep-)scrubbed in time."})}),"\n",(0,s.jsx)(n.h3,{id:"reboot-a-single-node",children:"Reboot a single node"}),"\n",(0,s.jsxs)(n.p,{children:["The traditional way of doing this is by setting the ",(0,s.jsx)(n.code,{children:"noout"})," flag,\ndo the appropriate maintenance work and after the node is back online\nunset the flag like so:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"ceph osd set noout\n"})}),"\n",(0,s.jsx)(n.p,{children:"After maintenance is done and host is back up:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"ceph osd unset noout\n"})}),"\n",(0,s.jsx)(n.p,{children:"On versions Luminous or above you can set the flag individually for single\nOSDs or entire CRUSH buckets, which can be a safer option in case of prolonged\nmaintenance periods."}),"\n",(0,s.jsx)(n.p,{children:"Add noout for a OSD:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"ceph osd add-noout osd.\n"})}),"\n",(0,s.jsx)(n.p,{children:"Remove noout for a OSD:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"ceph osd rm-noout osd.\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Add noout for CRUSH bucket (e.g. host name as seen in ",(0,s.jsx)(n.code,{children:"ceph osd tree"}),"):"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"ceph osd set-group noout \n"})}),"\n",(0,s.jsx)(n.p,{children:"Remove noout for CRUSH bucket:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"ceph osd unset-group noout \n"})}),"\n",(0,s.jsx)(n.h2,{id:"gathering-information-about-block-devices",children:"Gathering information about block devices"}),"\n",(0,s.jsx)(n.h3,{id:"enumerate-typical-storage-devices-and-lvm",children:"Enumerate typical storage devices and LVM"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"# lsblk\n# lsblk -S\n# lsscsi\n# nvme list\n# pvs\n# vgs\n# lvs\n"})}),"\n",(0,s.jsx)(n.h3,{id:"smart-data-for-satasas-and-nvme-devices",children:"SMART data for SATA/SAS and NVME devices"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"# smartctl -a /dev/sdX\n# nvme smart-log /dev/nvmeXnY\n"})}),"\n",(0,s.jsx)(n.h3,{id:"check-format-of-a-nvme-device",children:"Check format of a NVME device"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"# nvme id-ns -H /dev/nvmeXnY\n"})}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsx)(n.p,{children:'Check the last lines named "LBA Format".\nIt will show which formats are supported,\nwhich format is in use and which format offers the best performance\naccording to the vendor.'})}),"\n",(0,s.jsx)(n.h3,{id:"format-a-nvme-device-to-a-different-lba-format-using-nvme-cli",children:"Format a NVME device to a different LBA format using nvme-cli"}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsx)(n.p,{children:"This will destroy all data on the device!"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"# nvme format --lbaf= /dev/nvmeXnY\n"})}),"\n",(0,s.jsx)(n.h3,{id:"secure-erase-a-nvme-drive-using-nvme-cli",children:"Secure Erase a NVME drive using nvme-cli"}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsx)(n.p,{children:"This will destroy all data on the device!"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"# nvme format -s2 /dev/nvmeXnY\n# blkdiscard /dev/nvmeXnY\n# nvme format -s1 /dev/nvmeXnY\n"})}),"\n",(0,s.jsx)(n.h3,{id:"secure-erase-a-satasas-drive-using-hdparm",children:"Secure Erase a SATA/SAS drive using hdparm"}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsx)(n.p,{children:"This will destroy all data on the device!"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Gather device info:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"# hdparm -I /dev/sdX\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Check that the output says ",(0,s.jsx)(n.strong,{children:'"not frozen"'})," and ",(0,s.jsx)(n.strong,{children:'"not locked"'}),",\nalso it should list support for enhanced erase and list time estimates\nfor ",(0,s.jsx)(n.strong,{children:"SECURITY ERASE UNIT"})," and/or ",(0,s.jsx)(n.strong,{children:"ENHANCED SECURITY ERASE UNIT"})]}),"\n",(0,s.jsxs)(n.ol,{start:"2",children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Set a master password for the disk (required, will be automatically removed after wipe)"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"# hdparm --user-master wipeit --security-set-pass wipeit /dev/sdX\n# hdparm -I /dev/sdX\n"})}),"\n",(0,s.jsxs)(n.p,{children:['Check that "Security level" is now ',(0,s.jsx)(n.strong,{children:'"high"'})," and master password is now\n",(0,s.jsx)(n.strong,{children:'"enabled"'})," instead of ",(0,s.jsx)(n.strong,{children:'"not enabled"'})," before"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Wipe the device"}),"\n",(0,s.jsx)(n.p,{children:"If device supports enhanced security erase (better), use the following:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"# hdparm --user-master wipeit --security-erase-enhanced wipeit /dev/sdX\n"})}),"\n",(0,s.jsx)(n.p,{children:"If not, use standard security erase:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"# hdparm --user-master wipeit --security-erase wipeit /dev/sdX\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:['On some systems the system firmware might "freeze" the device,\nwhich makes it impossible to issue a secure erase or reformat the device.\nIn that case it might be necessary to either "unfreeze" the drive or\nto install the drive in another system where it can be unfrozen.\nAlso make sure that the device is ',(0,s.jsx)(n.em,{children:"actually"})," wiped. Its recommended to\nat least perform a blanking pass on HDDs with a tool like nwipe."]})}),"\n",(0,s.jsx)(n.h2,{id:"osd-maintenance-tasks",children:"OSD maintenance tasks"}),"\n",(0,s.jsxs)(n.p,{children:["Please have a look at the ",(0,s.jsx)(n.a,{href:"https://rook.io/docs/rook/latest-release/Storage-Configuration/Advanced/ceph-osd-mgmt/.",children:"Rook Ceph OSD Management documentation"})]}),"\n",(0,s.jsx)(n.h3,{id:"disable-backfillsrecovery-completely",children:"Disable backfills/recovery completely"}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsx)(n.p,{children:"Use only in emergency situations!"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ ceph osd set nobackfill\n$ ceph osd set norecovery\n$ ceph osd set norebalance\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Unset the flags with ",(0,s.jsx)(n.code,{children:"ceph osd unset "}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"rebalance-osds",children:"Rebalance OSDs"}),"\n",(0,s.jsx)(n.h2,{id:"placement-group-maintenance",children:"Placement Group maintenance"}),"\n",(0,s.jsx)(n.h3,{id:"dump-placement-groups",children:"Dump placement groups"}),"\n",(0,s.jsx)(n.p,{children:"Usually only useful when parsing it, so here are two ways to get the data:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ ceph pg dump\n$ ceph pg dump --format=json-pretty\n"})}),"\n",(0,s.jsx)(n.h3,{id:"query-a-pg-about-its-status",children:"Query a PG about its status"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ ceph pg query\n"})}),"\n",(0,s.jsx)(n.h3,{id:"start-deep-scrubbing-of-a-placement-group",children:"Start (deep-)scrubbing of a placement group"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ ceph pg scrub \n$ ceph pg deep-scrub \n"})}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsx)(n.p,{children:"Instructing a PG to (deep-)scrub does not mean that it will do so immediately,\nit can take some time for the scrub to start."})}),"\n",(0,s.jsx)(n.h3,{id:"health_warn---large-omap-objects-found",children:"HEALTH_WARN - Large omap objects found..."}),"\n",(0,s.jsx)(n.p,{children:"Finding PGs which have large OMAP objects:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"# ceph pg dump --format=json | jq '.pg_map.pg_stats[] |\nselect(.stat_sum.num_large_omap_objects != 0) |\n(.pgid, .stat_sum.num_large_omap_objects, .up, .acting)'\n"})}),"\n",(0,s.jsxs)(n.p,{children:["(Remove the line breaks between the single quotes or ",(0,s.jsx)(n.code,{children:"jq"})," might act weird!)"]}),"\n",(0,s.jsxs)(n.p,{children:["This will dump all PG IDs with large OMAP objects and their up/acting OSDs.\nYou then can grep the logs of these OSDs for ",(0,s.jsx)(n.strong,{children:'"Large omap object"'}),"\nto find the actual objects causing the health warning."]}),"\n",(0,s.jsx)(n.p,{children:"Also the PG ID before the dot is equal to the pool ID it belongs to."}),"\n",(0,s.jsx)(n.p,{children:"In case the logs have been rotated, instruct those OSDs to do a deep-scrub\nand watch the logs for the message to appear."}),"\n",(0,s.jsx)(n.p,{children:"From there you can investigate the issue further,\nmostly it'll be due to the index of a RGW bucket getting too big due to too many objects,\nthus resharding that bucket's index will be necessary."}),"\n",(0,s.jsx)(n.h3,{id:"instruct-a-pg-to-repair-in-case-of-scrub-errors-inconsistent-pg",children:"Instruct a PG to repair in case of scrub errors (inconsistent PG)"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ ceph pg repair \n"})}),"\n",(0,s.jsxs)(n.admonition,{type:"note",children:[(0,s.jsxs)(n.p,{children:["Recovery might not start immediately and might take some time.\nYou can query the status of the recovery through ",(0,s.jsx)(n.code,{children:"ceph pg query"}),".\nBe sure to read the Ceph manual about this topic ",(0,s.jsx)(n.em,{children:"thoroughly"}),":"]}),(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"https://docs.ceph.com/en/latest/rados/troubleshooting/troubleshooting-pg/",children:"https://docs.ceph.com/en/latest/rados/troubleshooting/troubleshooting-pg/"})})]}),"\n",(0,s.jsx)(n.h2,{id:"rados-pool-maintenance",children:"RADOS Pool maintenance"}),"\n",(0,s.jsxs)(n.admonition,{type:"note",children:[(0,s.jsx)(n.p,{children:"Read the RADOS pool operations documentation in detail before playing around with pools.\nEspecially when considering making changes to the CRUSH map.\nWrong decisions there can lead to data loss or other catastrophic failures."}),(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"https://docs.ceph.com/en/latest/rados/operations/pools/",children:"https://docs.ceph.com/en/latest/rados/operations/pools/"})})]}),"\n",(0,s.jsx)(n.h3,{id:"get-pools-and-their-configuration",children:"Get pools and their configuration"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ ceph osd pool ls detail\n"})}),"\n",(0,s.jsx)(n.h3,{id:"dump-all-crush-rules",children:"Dump all CRUSH rules"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ ceph osd crush rule dump\n"})}),"\n",(0,s.jsx)(n.h3,{id:"get-autoscaler-status",children:"Get autoscaler status"}),"\n",(0,s.jsx)(n.p,{children:"Autoscaler is enabled by default in a Rook Ceph cluster."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ ceph osd pool autoscale-status\n"})}),"\n",(0,s.jsx)(n.h3,{id:"create-a-replicated-pool",children:"Create a replicated pool"}),"\n",(0,s.jsxs)(n.p,{children:["This should be done by updating your ",(0,s.jsx)(n.code,{children:"values.yml"})," file via the variables in ",(0,s.jsx)(n.a,{href:"/docs/guides/configuration-guide/rook#extra-pool--cephblockpool-crd",children:"Rook Extra pools - CephBlockPoolC CRD"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"It also can be done by hand but Rook will not know about the pool in this case."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ ceph osd pool create replicated []\n"})}),"\n",(0,s.jsx)(n.h3,{id:"enabling-an-application-on-a-pool",children:"Enabling an application on a pool"}),"\n",(0,s.jsx)(n.p,{children:"Required, otherwise a health warning will be raised after some time."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ ceph osd pool application enable # Syntax\n$ ceph osd pool application enable cinder rbd # Example\n"})}),"\n",(0,s.jsx)(n.p,{children:"Typical application names are: rbd, rgw, cephfs"}),"\n",(0,s.jsx)(n.h3,{id:"delete-a-pool",children:"Delete a pool"}),"\n",(0,s.jsxs)(n.p,{children:["This should be done by updating your ",(0,s.jsx)(n.code,{children:"values.yml"})," file via the variables in ",(0,s.jsx)(n.a,{href:"/docs/guides/configuration-guide/rook#extra-pool--cephblockpool-crd",children:"Rook Extra pools - CephBlockPoolC CRD"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"It also can be done by hand but Rook will not know about the pool in this case."}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsx)(n.p,{children:"This will delete all data in that pool. There is no undo/undelete."})}),"\n",(0,s.jsx)(n.h3,{id:"set-number-of-pgs-for-a-pool",children:"Set number of PGs for a pool"}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsx)(n.p,{children:"PG autoscaling is enabled by default in Rook managed Ceph Clusters."})}),"\n",(0,s.jsx)(n.p,{children:"If no autoscaling of PGs is used, it is very important to adapt the PGs per pool to the\nreal world when operating a Ceph cluster. If, for example, OSDs are exchanged, added, new\nnodes are added, etc., the number of PGs must also be taken into account."}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"https://docs.ceph.com/en/latest/rados/operations/pgcalc/",children:"PG Calc Tool"})," can be used\nto calculate a reasonable number of PGs per pool depending on all ODSs and pools."]}),"\n",(0,s.jsxs)(n.p,{children:["Further information on placement groups can be found in the\n",(0,s.jsx)(n.a,{href:"https://docs.ceph.com/en/latest/rados/operations/placement-groups/",children:"Ceph documentation"}),".\nYou should definitely read ",(0,s.jsx)(n.em,{children:"FACTORS RELEVANT TO SPECIFYING PG_NUM"})," and ",(0,s.jsx)(n.em,{children:"CHOOSING THE NUMBER OF PGS"}),"\nthere."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ ceph osd pool set pg_num \n"})}),"\n",(0,s.jsxs)(n.admonition,{type:"note",children:[(0,s.jsx)(n.p,{children:"Num PGs must be a power of two! Be careful about changing number of PGs.\nChanging pg_num to a new value will gradually increase pgp_num on newer versions of Ceph."}),(0,s.jsx)(n.p,{children:"In older versions one also has to set pgp_num manually, either in increments or in one big leap."})]}),"\n",(0,s.jsx)(n.h3,{id:"create-crush-rules-for-different-storage-classes",children:"Create CRUSH rules for different storage classes"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ ceph osd crush rule create-replicated replicated_hdd default host hdd\n$ ceph osd crush rule create-replicated replicated_ssd default host ssd\n$ ceph osd crush rule create-replicated replicated_nvme default host nvme\n"})}),"\n",(0,s.jsx)(n.h3,{id:"change-crush-rule-for-a-pool-move-pool",children:'Change CRUSH rule for a pool ("move pool")'}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ ceph osd pool set crush_rule \n"})}),"\n",(0,s.jsx)(n.p,{children:"This can be used to move a pool from e.g. HDD to SSD or NVME class\nor anything else that the new CRUSH rule specifies."}),"\n",(0,s.jsx)(n.h2,{id:"advanced-topics",children:"Advanced topics"}),"\n",(0,s.jsx)(n.h2,{id:"performance-benchmark",children:"Performance benchmark"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"# apt-get install -y fio\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'#!/usr/bin/env bash\n\nBENCH_DEVICE="$2"\nDATE=$(date +%s)\nIOENGINE="libaio"\nLOGPATH="$1"\nSIZE=1G\n\nmkdir -p $LOGPATH\n\nfor RW in "write" "randwrite" "read" "randread"\ndo\n for BS in "4K" "64K" "1M" "4M" "16M" "64M"\n do\n (\n echo "==== $RW - $BS - DIRECT ===="\n echo 3 > /proc/sys/vm/drop_caches\n fio --rw=$RW --ioengine=${IOENGINE} --size=$SIZE --bs=$BS --direct=1 --runtime=60 --time_based --name=bench --filename=$BENCH_DEVICE --output=$LOGPATH/$RW.${BS}-direct-$(basename $BENCH_DEVICE).$DATE.log.json --output-format=json\n sync\n echo 3 > /proc/sys/vm/drop_caches\n echo "==== $RW - $BS - DIRECT IODEPTH 32 ===="\n fio --rw=$RW --ioengine=${IOENGINE} --size=$SIZE --bs=$BS --iodepth=32 --direct=1 --runtime=60 --time_based --name=bench --filename=$BENCH_DEVICE --output=$LOGPATH/$RW.${BS}-direct-iod32-$(basename $BENCH_DEVICE).$DATE.log.json --output-format=json\n sync\n ) | tee $LOGPATH/$RW.$BS-$(basename $BENCH_DEVICE).$DATE.log\n echo\n done\ndone\n'})}),"\n",(0,s.jsx)(n.h2,{id:"where-and-how-to-get-further-help",children:"Where and how to get further help"}),"\n",(0,s.jsxs)(n.p,{children:["Join the ",(0,s.jsx)(n.strong,{children:"#ceph"})," IRC channel on ",(0,s.jsx)(n.strong,{children:"irc.oftc.net"}),', state the problem with as many details as possible\nincluding information about what steps have already been taken to solve the problem\nalso provide information from the command output from the "60 seconds cluster overview" above\nthrough a pastebin or a similar service. In order for people to be able\nto help, details and some patience are important.']})]})}function h(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},1151:(e,n,o)=>{o.d(n,{Z:()=>a,a:()=>t});var s=o(7294);const i={},r=s.createContext(i);function t(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:t(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/bd92db3a.3a5624a5.js b/assets/js/bd92db3a.3a5624a5.js new file mode 100644 index 0000000000..fbc0891445 --- /dev/null +++ b/assets/js/bd92db3a.3a5624a5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkosism=self.webpackChunkosism||[]).push([[1594],{1693:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>r,toc:()=>d});var o=t(5893),s=t(1151);const i={sidebar_label:"OpenStack Health Monitor"},a="Setting up OpenStack health monitor on Debian",r={id:"guides/operations-guide/openstack/tools/openstack-health-monitor",title:"Setting up OpenStack health monitor on Debian",description:"Kurt Garloff, 2024-02-20",source:"@site/docs/guides/operations-guide/openstack/tools/openstack-health-monitor.md",sourceDirName:"guides/operations-guide/openstack/tools",slug:"/guides/operations-guide/openstack/tools/openstack-health-monitor",permalink:"/docs/guides/operations-guide/openstack/tools/openstack-health-monitor",draft:!1,unlisted:!1,editUrl:"https://github.com/osism/osism.github.io/tree/main/docs/guides/operations-guide/openstack/tools/openstack-health-monitor.md",tags:[],version:"current",frontMatter:{sidebar_label:"OpenStack Health Monitor"},sidebar:"tutorialSidebar",previous:{title:"Simple Stress",permalink:"/docs/guides/operations-guide/openstack/tools/simple-stress"},next:{title:"Cinder",permalink:"/docs/guides/operations-guide/openstack/cinder"}},l={},d=[{value:"Intro",id:"intro",level:2},{value:"Setting up the driver VM",id:"setting-up-the-driver-vm",level:2},{value:"Internal vs external monitoring",id:"internal-vs-external-monitoring",level:3},{value:"Unprivileged operation",id:"unprivileged-operation",level:3},{value:"Driver VM via openstack CLI",id:"driver-vm-via-openstack-cli",level:3},{value:"Configuring openstack CLI on the driver VM",id:"configuring-openstack-cli-on-the-driver-vm",level:3},{value:"Custom CA",id:"custom-ca",level:3},{value:"Your first api_monitor.sh iteration",id:"your-first-api_monitorsh-iteration",level:2},{value:"Resource impact and charging",id:"resource-impact-and-charging",level:3},{value:"Automating startup and cleanup",id:"automating-startup-and-cleanup",level:2},{value:"Changing parameters and restarting",id:"changing-parameters-and-restarting",level:3},{value:"Multiple instances",id:"multiple-instances",level:3},{value:"Alarming and Logs",id:"alarming-and-logs",level:2},{value:"eMail",id:"email",level:3},{value:"Log files",id:"log-files",level:3},{value:"Data collection and dashboard",id:"data-collection-and-dashboard",level:2},{value:"telegraf",id:"telegraf",level:3},{value:"influxdb",id:"influxdb",level:3},{value:"Add -S CLOUDNAME to your run_CLOUDNAME.sh script",id:"add--s-cloudname-to-your-run_cloudnamesh-script",level:3},{value:"grafana",id:"grafana",level:3},{value:"Basic config",id:"basic-config",level:4},{value:"Enable influx database in grafana",id:"enable-influx-database-in-grafana",level:4},{value:"Importing the dashboard",id:"importing-the-dashboard",level:4},{value:"No data displayed?",id:"no-data-displayed",level:4},{value:"Dashboard features",id:"dashboard-features",level:4},{value:"github OIDC integration",id:"github-oidc-integration",level:4},{value:"Alternative approach to install and configure the dashboard behind a reverse proxy",id:"alternative-approach-to-install-and-configure-the-dashboard-behind-a-reverse-proxy",level:2},{value:"Maintenance",id:"maintenance",level:2},{value:"Unattended upgrades",id:"unattended-upgrades",level:3},{value:"Updating openstack-health-monitor",id:"updating-openstack-health-monitor",level:3},{value:"Backup",id:"backup",level:3},{value:"Troubleshooting",id:"troubleshooting",level:2},{value:"Debugging issues",id:"debugging-issues",level:3},{value:"Analyzing failures",id:"analyzing-failures",level:3},{value:"Cleaning things up",id:"cleaning-things-up",level:3}];function c(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.a)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"setting-up-openstack-health-monitor-on-debian",children:"Setting up OpenStack health monitor on Debian"}),"\n",(0,o.jsx)(n.p,{children:"Kurt Garloff, 2024-02-20"}),"\n",(0,o.jsx)(n.h2,{id:"intro",children:"Intro"}),"\n",(0,o.jsxs)(n.p,{children:["The development of ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/",children:"openstack-health-monitor"})," was done on ",(0,o.jsx)(n.a,{href:"https://kfg.images.obs-website.eu-de.otc.t-systems.com/",children:"openSUSE 15.x images"}),", just because the author is very familiar with it and has some of the needed tools preinstalled. That said, the setup is not depending on anything specific from openSUSE and should work on every modern Linux distribution."]}),"\n",(0,o.jsx)(n.p,{children:"Setting it up again in a different environment using Debian 12 images avoids a few of the shortcuts that were used and thus should be very suitable instructions to get it working in general. The step by step instructions are covered here."}),"\n",(0,o.jsxs)(n.p,{children:["Note: This is a rather classical snowflake setup -- we create a VM and do some manual configuration to get everything configured. Having it well documented here should make this more replicatable, and is an important precondition for more automation, but larger steps to full automate this using ansible or helm charts (in a containerized variant) are not addressed here. As we expect a ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/scs-health-monitor",children:"successor project"})," for the increasingly hard to maintain shell code, this may not be worth the trouble."]}),"\n",(0,o.jsxs)(n.p,{children:["openstack-health-monitor implements a scripted scenario test with a large shell-script that uses the openstackclient tools to set up the scenario, test it and tear everything down again in a loop. Any errors are recorded, as well as timings and some very basic benchmarks. The script sets up some virtual network infrastructure (routers, networks, subnets, floating IPs), security groups, keypairs, volumes and finally boots some VMs. Access to these is tested (ensuring metadata injection works) and connectivity between them tested and measured. A loadbalancer (optionally) is set up with a health-monitor and access via it before and after killing some backends is tested.\nThe scenario is described in a bit more detail in the ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/README.md",children:"repository's README.md"})," file."]}),"\n",(0,o.jsxs)(n.p,{children:["The openstack-health-monitor is not the intended long-term solution for monitoring your infrastructure. The SCS project has a project underway that will create more modern, flexible, and more maintainable monitoring infrastructure; the concepts are described on the ",(0,o.jsx)(n.a,{href:"https://docs.scs.community/docs/category/monitoring",children:"monitoring section"})," of the project's documentation. The openstack-health-monitor will thus not see any significant enhancements any more; it will be maintained and kept alive as long as there are users. This guide exclusively focuses on how to set it up."]}),"\n",(0,o.jsx)(n.h2,{id:"setting-up-the-driver-vm",children:"Setting up the driver VM"}),"\n",(0,o.jsxs)(n.p,{children:["So we start a ",(0,o.jsx)(n.code,{children:"Debian 12"})," image on a cloud of our choice. This should work on any OpenStack cloud that is reasonably standard;\nthe instructions use flavor names and image names from the SCS standards.\nFor many, the simplest way may be to use the Web-UI of their cloud (e.g. horizon for OpenStack)."]}),"\n",(0,o.jsx)(n.h3,{id:"internal-vs-external-monitoring",children:"Internal vs external monitoring"}),"\n",(0,o.jsx)(n.p,{children:"There are pros and cons to run the driver VM in the same cloud that is also under test. We obviously don't test the external reachability of the cloud (more precisely its API endpoints and VMs) if we run it on the same cloud -- which may or may not be desirable. Having the tests happily continuing to collect data may actually be valuable in times when external access is barred. If the cloud goes down, we will no longer see API calls against it, although the information of them not being available does not reveal much in terms of insight into the reasons for the outage. Also, the driver VM is the only long-lived VM in the openstack-health-monitor setup, so it may be useful to have it in the same cloud to reveal any issues that do not occur on the short-lived resources created and deleted by the health-monitor."}),"\n",(0,o.jsx)(n.p,{children:"The author tends to see running it internally as advantageous -- ideally combined with a simple API reachability test from the outside that sends alarms as needed to detect any reachability problems."}),"\n",(0,o.jsx)(n.h3,{id:"unprivileged-operation",children:"Unprivileged operation"}),"\n",(0,o.jsx)(n.p,{children:"Nothing in this test requires admin privileges on the cloud where the driver runs nor on the cloud under test. We do install and configure a few software packages in the driver VM, which requires sudo power there, but the script should just run as a normal user. For the cloud under test it is recommended to use a user (or an application credential) with a normal tenant member role to access the cloud under test. If you can, give it an OpenStack project on its own."}),"\n",(0,o.jsxs)(n.p,{children:["If ",(0,o.jsx)(n.code,{children:"openstack availability zone list --compute"})," fails for you without admin rights, please fix your openstack client, e.g. by applying the ",(0,o.jsx)(n.a,{href:"https://raw.githubusercontent.com/SovereignCloudStack/openstack-health-monitor/main/docs/openstackclient-az-list-fallback-f3207bd.diff",children:"patch"})," I mentioned in ",(0,o.jsx)(n.a,{href:"https://storyboard.openstack.org/#!/story/2010989",children:"this issue"}),". (Versions 6.3.0 and 6.4.0 are broken.) Do not consider giving the OpenStack Health-Monitor admin power. (Note: It has a workaround for the broken AZ listing using curl now.)"]}),"\n",(0,o.jsx)(n.h3,{id:"driver-vm-via-openstack-cli",children:"Driver VM via openstack CLI"}),"\n",(0,o.jsxs)(n.p,{children:["The author prefers to setup the VM via ",(0,o.jsx)(n.code,{children:"openstack"})," CLI tooling. He has working entries for all clouds he uses in his ",(0,o.jsx)(n.code,{children:"~/.config/openstack/clouds.yaml"})," and ",(0,o.jsx)(n.code,{children:"secure.yaml"})," and has exported the ",(0,o.jsx)(n.code,{children:"OS_CLOUD"})," environment variable to point to the cloud he is working on to set up the driver VM. The author uses the ",(0,o.jsx)(n.code,{children:"bash"})," shell. All of this of course could be scripted."]}),"\n",(0,o.jsx)(n.p,{children:"So here we go"}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsxs)(n.li,{children:["Create the network setup for a VM in a network ",(0,o.jsx)(n.code,{children:"oshm-network"})," with an IPv4 subnet, connected to a router that connects (and by default SNATs) to the public network."]}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"PUBLIC=$(openstack network list --external -f value -c Name)\nopenstack router create oshm-router\nopenstack router set --external-gateway $PUBLIC oshm-driver-router\nopenstack network create oshm-network\nopenstack subnet create --subnet-range 192.168.192.0/24 --network oshm-network oshm-subnet\nopenstack router add subnet oshm-router oshm-subnet\n"})}),"\n",(0,o.jsxs)(n.ol,{start:"2",children:["\n",(0,o.jsx)(n.li,{children:"Create a security group that allows ssh and ping access"}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"openstack security group create sshping\nopenstack security group rule create --ingress --ethertype ipv4 --protocol tcp --dst-port 22 sshping\nopenstack security group rule create --ingress --ethertype ipv4 --protocol icmp --icmp-type 8 sshping\n"})}),"\n",(0,o.jsxs)(n.ol,{start:"3",children:["\n",(0,o.jsx)(n.li,{children:"Being at it, we also create the security group for grafana"}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"openstack security group create grafana\nopenstack security group rule create --ingress --ethertype ipv4 --protocol tcp --dst-port 3000 grafana\n"})}),"\n",(0,o.jsxs)(n.ol,{start:"4",children:["\n",(0,o.jsx)(n.li,{children:"To connect to the VM via ssh later, we create an SSH keypair"}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"openstack keypair create --private-key ~/.ssh/oshm-key.pem oshm-key\nchmod og-r ~/.ssh/oshm-key.pem \n"})}),"\n",(0,o.jsxs)(n.p,{children:["Rather than creating a new key (and storing and protecting the private key), we could have passed ",(0,o.jsx)(n.code,{children:"--public-key"})," and used an existing keypair."]}),"\n",(0,o.jsxs)(n.ol,{start:"5",children:["\n",(0,o.jsx)(n.li,{children:"Look up Debian 12 image UUID."}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"IMGUUID=$(openstack image list --name \"Debian 12\" -f value -c ID | tr -d '\\r')\necho $IMGUUID\n"})}),"\n",(0,o.jsxs)(n.p,{children:["Sidenote: The ",(0,o.jsx)(n.code,{children:"tr"})," command is there to handle broken tooling that embeds a trailing ",(0,o.jsx)(n.code,{children:"\\r"})," in the output."]}),"\n",(0,o.jsxs)(n.ol,{start:"6",children:["\n",(0,o.jsx)(n.li,{children:"Boot the driver VM"}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"openstack server create --network oshm-network --key-name oshm-key --security-group default --security-group sshping --security-group grafana --flavor SCS-2V-4 --block-device boot_index=0,uuid=$IMGUUID,source_type=image,volume_size=10,destination_type=volume,delete_on_termination=true oshm-driver\n"})}),"\n",(0,o.jsxs)(n.p,{children:["Chose a flavor that exists on your cloud. Here we have used one without root disk and asked nova to create a volume on the fly by passing ",(0,o.jsx)(n.code,{children:"--block-device"}),". See ",(0,o.jsx)(n.a,{href:"https://scs.community/2023/08/21/diskless-flavors/",children:"diskless flavor blog article"}),". For flavors with local root disks, you could have used the ",(0,o.jsx)(n.code,{children:"--image $IMGUUID"})," parameter instead."]}),"\n",(0,o.jsxs)(n.ol,{start:"7",children:["\n",(0,o.jsxs)(n.li,{children:["Wait for it to boot (optional)\nYou can look at the boot log with ",(0,o.jsx)(n.code,{children:"openstack console log show oshm-driver"})," or connect to it via VNC at the URL given by ",(0,o.jsx)(n.code,{children:"openstack console url show oshm-driver"}),". You can of course also query openstack on the status ",(0,o.jsx)(n.code,{children:"openstack server list"})," or ",(0,o.jsx)(n.code,{children:"openstack server show oshm-driver"}),". You can also just create a simple loop:"]}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'declare -i ctr=0 RC=0\nwhile [ $ctr -le 120 ]; do\n STATUS="$(openstack server list --name oshm-driver -f value -c Status)"\n if [ "$STATUS" = "ACTIVE" ]; then echo "$STATUS"; break; fi \n if [ "$STATUS" = "ERROR" ]; then echo "$STATUS"; RC=1; break; fi\n if [ -z "$STATUS" ]; then echo "No such VM"; RC=2; break; fi\n sleep 2\n let ctr+=1\ndone\n# return $RC\nif [ $RC != 0 ]; then false; fi\n'})}),"\n",(0,o.jsxs)(n.ol,{start:"8",children:["\n",(0,o.jsx)(n.li,{children:"Attach a floating IP so it's reachable from the outside."}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'FIXEDIP=$(openstack server list --name oshm-driver -f value -c Networks | sed "s@^[^:]*:[^\']*\'\\([0-9\\.]*\\)\'.*\\$@\\1@")\nFIXEDPORT=$(openstack port list --fixed-ip ip-address=$FIXEDIP,subnet=oshm-subnet -f value -c ID)\necho $FIXEDIP $FIXEDPORT\nopenstack floating ip create --port $FIXEDPORT $PUBLIC\nFLOATINGIP=$(openstack floating ip list --fixed-ip-address $FIXEDIP -f value -c "Floating IP Address")\necho "Floating IP: $FLOATINGIP"\n'})}),"\n",(0,o.jsx)(n.p,{children:"Remember this floating IP address."}),"\n",(0,o.jsxs)(n.ol,{start:"9",children:["\n",(0,o.jsx)(n.li,{children:"Connect to it via ssh"}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"ssh -i ~/.ssh/oshm-key.pem debian@$FLOATINGIP\n"})}),"\n",(0,o.jsx)(n.p,{children:"On the first connection, you need to accept the new ssh host key. (Very careful people would compare the fingerprint with the console log output.)"}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsx)(n.strong,{children:"All the following commands are performed on the newly started driver VM."})}),"\n",(0,o.jsx)(n.h3,{id:"configuring-openstack-cli-on-the-driver-vm",children:"Configuring openstack CLI on the driver VM"}),"\n",(0,o.jsx)(n.p,{children:"We need to install the openstack client utilities."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"sudo apt-get update\nsudo apt-get install python3-openstackclient\nsudo apt-get install python3-cinderclient python3-octaviaclient python3-swiftclient python3-designateclient\n"})}),"\n",(0,o.jsxs)(n.p,{children:["Configure your cloud access in ",(0,o.jsx)(n.code,{children:"~/.config/openstack/clouds.yaml"})]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",children:"clouds:\n CLOUDNAME:\n interface: public\n identity-api-version: 3\n #region_name: REGION\n auth:\n auth_url: KEYSTONE_ENDPOINT\n project_id: PROJECT_UUID\n #alternatively project_name and project_domain_name\n user_domain_name: default\n # change to your real domain\n"})}),"\n",(0,o.jsxs)(n.p,{children:["and ",(0,o.jsx)(n.code,{children:"secure.yaml"})," (in the same directory)"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",children:"clouds:\n CLOUDNAME:\n auth:\n username: USERNAME\n password: PASSWORD\n"})}),"\n",(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.code,{children:"CLOUDNAME"})," can be freely chosen. This is the value passed to the openstack CLI with ",(0,o.jsx)(n.code,{children:"--os-cloud"})," or exported to your environment in ",(0,o.jsx)(n.code,{children:"OS_CLOUD"}),". The other uppercase words need to be adjusted to match your cloud. Hint: horizon typically lets you download a sample ",(0,o.jsx)(n.code,{children:"clouds.yaml"})," file that works (but lacks the password)."]}),"\n",(0,o.jsxs)(n.p,{children:["Protect your ",(0,o.jsx)(n.code,{children:"secure.yaml"})," from being read by others: ",(0,o.jsx)(n.code,{children:"chmod 0600 ~/.config/openstack/secure.yaml"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["If you are using application credentials instead of username, password to authenticate, you don't need to specify ",(0,o.jsx)(n.code,{children:"project_id"})," nor project's nor user's domain names in ",(0,o.jsx)(n.code,{children:"clouds.yaml"}),". Just (in ",(0,o.jsx)(n.code,{children:"secure.yaml"}),"):"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",children:'clouds:\n CLOUDNAME:\n auth_type: v3applicationcredential\n auth:\n application_credential_id: APPCRED_ID\n application_credential_secret: "APPCRED_SECRET"\n'})}),"\n",(0,o.jsx)(n.p,{children:"Configure this to be your default cloud:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"export OS_CLOUD=CLOUDNAME\n"})}),"\n",(0,o.jsxs)(n.p,{children:["You might consider adding this to your ",(0,o.jsx)(n.code,{children:"~/.bashrc"})," for convenience. Being at it, you might want to add ",(0,o.jsx)(n.code,{children:"export CLIFF_FIT_WIDTH=1"})," there as well to make openstack command output tables more readable (but sometimes less easy to cut'n'paste)."]}),"\n",(0,o.jsx)(n.p,{children:"Verify that your openstack CLI works:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"openstack catalog list\nopenstack server list\n"})}),"\n",(0,o.jsx)(n.p,{children:"You can use the same project as you use for your driver VM (and possibly other workloads). The openstack-health-monitor is carefully designed to not clean up anything that it has not created. There is however some trickiness, as not all resources have names (floating IPs for example do not) and sometimes names need to be assigned after creation of a resource (volumes of diskless flavors), so in case there are API errors, some heuristics is used to identify resources which may not be safe under all circumstances. So ideally, you have an extra project created just for the health-monitor and configure the credentials for it here, so you can not possibly hit any wrong resource in the script's extensive efforts to clean up in error cases."}),"\n",(0,o.jsx)(n.h3,{id:"custom-ca",children:"Custom CA"}),"\n",(0,o.jsxs)(n.p,{children:["If your cloud API's endpoints don't use TLS certificates that are signed by an official CA, you need to provide your CA to this VM and configure it. (On a SCS Cloud-in-a-Box system, you find it on the manager node in ",(0,o.jsx)(n.code,{children:"/etc/ssl/certs/ca-certificates.crt"}),". You may extract the last cert or just leave them all together.) Copy the CA file to your driver VM and ensure it's readable by the ",(0,o.jsx)(n.code,{children:"debian"})," user."]}),"\n",(0,o.jsxs)(n.p,{children:["Add it to your ",(0,o.jsx)(n.code,{children:"clouds.yaml"})]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"clouds:\n CLOUDNAME:\n cacert: /PATH/TO/CACERT.CRT\n [...]\n"})}),"\n",(0,o.jsxs)(n.p,{children:["If you want to allow ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," to be able to talk to the service endpoints directly to avoid getting a fresh token from keystone for each call, you also need to export it to your environment:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"export OS_CACERT=/PATH/TO/CACERT.CRT\n"})}),"\n",(0,o.jsxs)(n.p,{children:["Consider adding this to your ",(0,o.jsx)(n.code,{children:"~/.bashrc"})," as well."]}),"\n",(0,o.jsxs)(n.h2,{id:"your-first-api_monitorsh-iteration",children:["Your first ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," iteration"]}),"\n",(0,o.jsx)(n.p,{children:"Checkout openstack-health-monitor:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"sudo apt-get install git bc jq netcat-traditional tmux zstd\ngit clone https://github.com/SovereignCloudStack/openstack-health-monitor\ncd openstack-health-monitor\n"})}),"\n",(0,o.jsxs)(n.p,{children:["You may want to start a ",(0,o.jsx)(n.code,{children:"tmux"})," (or ",(0,o.jsx)(n.code,{children:"screen"}),") session now, so you can do multiple things in parallel (e.g. for debugging) and reconnect."]}),"\n",(0,o.jsxs)(n.p,{children:["The script ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," is the main worker of openstack-health-monitor and runs one to many iterations of a cycle where resources are created, tested and torn down. Its operation is described in the ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/README.md",children:"README.md"})," file."]}),"\n",(0,o.jsxs)(n.p,{children:["It is good practice to use ",(0,o.jsx)(n.code,{children:"tmux"}),". This allows you to return (reattach) to console sessions and to open new windows to investigate things. Traditional people may prefer to ",(0,o.jsx)(n.code,{children:"screen"})," over ",(0,o.jsx)(n.code,{children:"tmux"}),"."]}),"\n",(0,o.jsx)(n.p,{children:"You should be ready to run one iteration of the openstack-health-monitor now. Run it like this:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:'export IMG="Debian 12"\nexport JHIMG="Debian 12"\n./api_monitor.sh -O -C -D -n 6 -s -b -B -M -T -LL -i 1\n'})}),"\n",(0,o.jsxs)(n.p,{children:["Leave out the ",(0,o.jsx)(n.code,{children:"-LL"})," if you don't have a working loadbalancer service or replace ",(0,o.jsx)(n.code,{children:"-LL"})," with ",(0,o.jsx)(n.code,{children:"-LO"})," if you want to test the ovn loadbalancer instead of amphorae (saving quite some resources)."]}),"\n",(0,o.jsxs)(n.p,{children:["Feel free to study the meaning of all the command line parameters by looking at the ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/README.md",children:"README.md"}),". (Note: Many of the things enabled by the parameters should be default, but are not for historic reasons. This would change if we rewrite this whole thing in python.)"]}),"\n",(0,o.jsxs)(n.p,{children:["This will run for ~7 minutes, depending on the performance of your OpenStack environment. You should not get any error. (The amber-colored outputs ",(0,o.jsx)(n.code,{children:"DOWN"}),", ",(0,o.jsx)(n.code,{children:"BUILD"}),", ",(0,o.jsx)(n.code,{children:"creating"})," are not errors. Nothing in red should be displayed.) Studying the console output may be instructive to follow the script's progress. You may also open another window (remember the tmux recommendation above) and look at the resources with the usual ",(0,o.jsx)(n.code,{children:"openstack RESOURCE list"})," and ",(0,o.jsx)(n.code,{children:"openstack RESOURCE show NAME"})," and ",(0,o.jsx)(n.code,{children:"RESOURCE"})," being something like ",(0,o.jsx)(n.code,{children:"router"}),", ",(0,o.jsx)(n.code,{children:"network"}),", ",(0,o.jsx)(n.code,{children:"subnet"}),", ",(0,o.jsx)(n.code,{children:"port"}),", ",(0,o.jsx)(n.code,{children:"volume"}),", ",(0,o.jsx)(n.code,{children:"server"}),", ",(0,o.jsx)(n.code,{children:"floating ip"}),", ",(0,o.jsx)(n.code,{children:"loadbalancer"}),", ",(0,o.jsx)(n.code,{children:"loadbalancer pool"}),", ",(0,o.jsx)(n.code,{children:"loadbalancer listener"}),", ",(0,o.jsx)(n.code,{children:"security group"}),", ",(0,o.jsx)(n.code,{children:"keypair"}),", ",(0,o.jsx)(n.code,{children:"image"}),", ...)"]}),"\n",(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," uses and ",(0,o.jsx)(n.code,{children:"APIMonitor_TIMESTAMP"})," prefix for all OpenStack resource names. This allows to identify the created resources and clean them up even if things go wrong.\n",(0,o.jsx)(n.code,{children:"TIMESTAMP"})," is an integer number representing the seconds after 1970-01-01 00:00:00 UTC (Unix time)."]}),"\n",(0,o.jsxs)(n.p,{children:["This may be the time to check that you have sufficient quota to create the resources. While we only create 6+N VMs (and volumes) with the above call (N being the number of AZs), we would want to increase this number for larger clouds. For single-AZ deployments, we would want to still use 2 networks at least ",(0,o.jsx)(n.code,{children:"-N 2"})," to test the ability of the router to route traffic between networks. So expect ",(0,o.jsx)(n.code,{children:"-n 6"})," to become ",(0,o.jsx)(n.code,{children:"-N 2 -n 6"})," for a very small single-AZ cloud or ",(0,o.jsx)(n.code,{children:"-n 12"})," for a large 3 AZ cloud region. So, re-run the ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," with the target sizing."]}),"\n",(0,o.jsx)(n.h3,{id:"resource-impact-and-charging",children:"Resource impact and charging"}),"\n",(0,o.jsxs)(n.p,{children:["Note that ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," uses small flavors (",(0,o.jsx)(n.code,{children:"SCS-1V-2"})," for the N jump hosts and ",(0,o.jsx)(n.code,{children:"SCS-1L-1"})," for the other VMs) to keep the impact on your cloud (and on your invoice if you are not monitoring your own cloud) small. You can change the flavors."]}),"\n",(0,o.jsxs)(n.p,{children:["If you have to pay for this, also consider that some clouds are not charging by the minute but may count by the started hour. So when you run ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," in a loop (which you will) with say 10 VMs (e.g. ",(0,o.jsx)(n.code,{children:"-N 2 -n 8"}),") in each iteration and run this for an hour with 8 iterations, you will never have more than 10 VMs in parallel and they only are alive a bit more than half of the time, but rather than being charged for ~6 VM hours, you end up being charged for ~80 VM hours. Similar for volumes, routers, floating IPs. This makes a huge difference."]}),"\n",(0,o.jsxs)(n.p,{children:["Sometimes the cloud under test has issues. That's why we do monitoring ... One thing that might happen is that loadbalancers and volumes (and other resources, but those two are the most prone to this) end up in a broken state that can not be cleaned up by the user any more. Bad providers may charge for these anyhow, although this will never stand a legal dispute. (IANAL, but charging for providing something that is not working is not typically supported by civil law in most jurisdictions and T&Cs that would say so would not normally be legally enforceable.) If this happens, I recommend to keep records of the broken state (store the output of ",(0,o.jsx)(n.code,{children:"openstack volume list"}),", ",(0,o.jsx)(n.code,{children:"openstack volume show BROKEN_VOLUME"}),", ",(0,o.jsx)(n.code,{children:"openstack loadbalancer list"}),", ",(0,o.jsx)(n.code,{children:"openstack loadbalancer show BROKEN_LB"}),".)"]}),"\n",(0,o.jsxs)(n.p,{children:["Using ",(0,o.jsx)(n.code,{children:"-w -1"})," makes ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," wait for interactive input whenever an error occurs; this can be convenient for debugging."]}),"\n",(0,o.jsx)(n.p,{children:"Once you have single iterations working nicely, we can proceed."}),"\n",(0,o.jsx)(n.h2,{id:"automating-startup-and-cleanup",children:"Automating startup and cleanup"}),"\n",(0,o.jsxs)(n.p,{children:["Typically, we run ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," with a limited amount of iterations (200) and then restart it. For each restart, we also output some statistics, compress the log file and look at any leftovers that did not get cleaned up. The latter happens in the start script that we create here."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'#!/bin/bash\n# run_CLOUDNAME.sh\n# Do some global settings\nexport IMG="Debian 12"\nexport JHIMG="Debian 12"\n#export OS_CACERT=/home/debian/ca-certificates.pem\n# Additional settings to override flavors or to\n# configure email addresses for sending alarms can be set here\n\n# Does openstack CLI work?\nopenstack server list >/dev/null || exit 1\n# Upload log files to this swift container (which you need to create)\n#export SWIFTCONTAINER=OS-HM-Logfiles\n\n# CLEANUP\necho "Finding resources from previous runs to clean up ..."\n# Find Floating IPs\nFIPLIST=""\nFIPS=$(openstack floating ip list -f value -c ID)\nfor fip in $FIPS; do\n FIP=$(openstack floating ip show $fip | grep -o "APIMonitor_[0-9]*")\n if test -n "$FIP"; then FIPLIST="${FIPLIST}${FIP}_\n"; fi\ndone\nFIPLIST=$(echo "$FIPLIST" | grep -v \'^$\' | sort -u)\n# Cleanup previous interrupted runs\nSERVERS=$(openstack server list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nKEYPAIR=$(openstack keypair list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nVOLUMES=$(openstack volume list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nNETWORK=$(openstack network list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nLOADBAL=$(openstack loadbalancer list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nROUTERS=$(openstack router list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nSECGRPS=$(openstack security group list | grep -o "APIMonitor_[0-9]*_" | sort -u)\necho CLEANUP: FIPs $FIPLIST Servers $SERVERS Keypairs $KEYPAIR Volumes $VOLUMES Networks $NETWORK LoadBalancers $LOADBAL Routers $ROUTERS SecGrps $SECGRPS\nfor ENV in $FIPLIST; do\n echo "******************************"\n echo "CLEAN $ENV"\n bash ./api_monitor.sh -o -T -q -c CLEANUP $ENV\n echo "******************************"\ndone\nTOCLEAN=$(echo "$SERVERS\n$KEYPAIR\n$VOLUMES\n$NETWORK\n$LOADBAL\n$ROUTERS\n$SECGRPS\n" | grep -v \'^$\' | sort -u)\nfor ENV in $TOCLEAN; do\n echo "******************************"\n echo "CLEAN $ENV"\n bash ./api_monitor.sh -o -q -LL -c CLEANUP $ENV\n echo "******************************"\ndone\n\n# Now run the monitor\n#exec ./api_monitor.sh -O -C -D -N 2 -n 6 -s -M -LO -b -B -a 2 -t -T -R -S ciab "$@"\nexec ./api_monitor.sh -O -C -D -N 2 -n 6 -s -M -LO -b -B -T "$@"\n'})}),"\n",(0,o.jsxs)(n.p,{children:["Compared to the previous run, we have explicitly set two networks here ",(0,o.jsx)(n.code,{children:"-N 2"})," and rely on the iterations being passed in as command line arguments. Add parameter ",(0,o.jsx)(n.code,{children:"-t"})," if your cloud is slow to increase timeouts. We have enabled the ovtavia loadbalancer (",(0,o.jsx)(n.code,{children:"-LO"}),") in this example rather than the amphora based one (",(0,o.jsx)(n.code,{children:"-LL"}),")."]}),"\n",(0,o.jsxs)(n.p,{children:["You may use one of the existing ",(0,o.jsx)(n.code,{children:"run_XXXX.sh"})," scripts as example. Beware: eMail alerting with ",(0,o.jsx)(n.code,{children:"ALARM_EMAIL_ADDRESS"})," and ",(0,o.jsx)(n.code,{children:"NOTE_EMAIL_ADDRESS"})," (and limiting with ",(0,o.jsx)(n.code,{children:"-a"})," and ",(0,o.jsx)(n.code,{children:"-R"})," ) and reporting data to telegraf (option ",(0,o.jsx)(n.code,{children:"-S"}),") may be present in the samples. Make this script executable (",(0,o.jsx)(n.code,{children:"chmod +x run_CLOUDNAME.sh"}),")."]}),"\n",(0,o.jsxs)(n.p,{children:["We wrap a loop around this in ",(0,o.jsx)(n.code,{children:"run_in_loop.sh"}),":"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'#!/bin/bash\n# run_in_loop.sh\nrm stop-os-hm 2>/dev/null\nwhile true; do\n ./run_CLOUDNAME.sh -i 200\n if test -e stop-os-hm; then break; fi\n echo -n "Hit ^C to abort ..."\n sleep 15; echo\ndone\n'})}),"\n",(0,o.jsxs)(n.p,{children:["Also make this executable (",(0,o.jsx)(n.code,{children:"chmod +x run_in_loop.sh"}),").\nTo run this automatically in a tmux window whenever the system starts, we follow the steps in the ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/startup/README.md",children:"startup README.md"})]}),"\n",(0,o.jsxs)(n.p,{children:["Change ",(0,o.jsx)(n.code,{children:"OS_CLOUD"})," in ",(0,o.jsx)(n.code,{children:"startup/run-apimon-in-tmux.sh"}),". (If you need to set ",(0,o.jsx)(n.code,{children:"OS_CACERT"}),", also add it in this file and pass it into the windows.)"]}),"\n",(0,o.jsx)(n.p,{children:"Activate everything:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"mkdir -p ~/.config/systemd/user/\ncp -p startup/apimon.service ~/.config/systemd/user/\nsystemctl --user enable apimon\nsystemctl --user start apimon\nsudo loginctl enable-linger debian\ntmux attach oshealthmon\n"})}),"\n",(0,o.jsxs)(n.p,{children:["This assumes that you are using the user ",(0,o.jsx)(n.code,{children:"debian"})," for this monitoring and have checked out the repository at ",(0,o.jsx)(n.code,{children:"~/openstack-health-monitor/"}),". Adjust the paths and user name otherwise. (If for whatever reason you have chosen to install things as root, you will have to install the systemd service unit in the system paths and ensure it's not started too early in the boot process.)"]}),"\n",(0,o.jsx)(n.h3,{id:"changing-parameters-and-restarting",children:"Changing parameters and restarting"}),"\n",(0,o.jsxs)(n.p,{children:["If you want to change the parameters passed to ",(0,o.jsx)(n.code,{children:"api_monitor.sh"}),", you best do this by editing ",(0,o.jsx)(n.code,{children:"run_CLOUDNAME.sh"}),", potentially after testing it with one iteration before."]}),"\n",(0,o.jsxs)(n.p,{children:["To make the change effective, you can wait until the current 200 iterations are completed and the ",(0,o.jsx)(n.code,{children:"run_in_loop.sh"})," calls ",(0,o.jsx)(n.code,{children:"run_CLOUDNAME.sh"})," again. You can also hit ",(0,o.jsx)(n.code,{children:"^C"})," in the tmux window that has",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," running. The script will then exit after the current iteration. Note that sending this interrupt is handled by the script, so it does still continue the current iteration and do all the cleanup work. However, you may interrupt an API call and thus cause a spurious error (which may in the worst case lead to a couple more spurious errors). If you want to avoid this, hit ",(0,o.jsx)(n.code,{children:"^C"})," during the wait/sleep phases of the script (after having done all the tests or after having completed the iteration). If you hit ",(0,o.jsx)(n.code,{children:"^C"})," twice, it will abort the the current iteration, but still try to clean up. Then the outer script will also exit and you have to restart by manually calling ",(0,o.jsx)(n.code,{children:"./run_in_loop.sh"})," again."]}),"\n",(0,o.jsxs)(n.p,{children:["You can also issue the ",(0,o.jsx)(n.code,{children:"systemctl --user stop apimon"})," command; it will basically do the same thing: Send ",(0,o.jsx)(n.code,{children:"^C"})," and then wait for everything to be completed and tear down the tmux session.\nAfter waiting for that to complete, you can start it again with ",(0,o.jsx)(n.code,{children:"systemctl --user start apimon"}),"."]}),"\n",(0,o.jsx)(n.h3,{id:"multiple-instances",children:"Multiple instances"}),"\n",(0,o.jsxs)(n.p,{children:["You can run multiple instances of ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," on the same driver VM. In this case, you should rename ",(0,o.jsx)(n.code,{children:"run_in_loop.sh"})," to e.g. ",(0,o.jsx)(n.code,{children:"run_in_loop_CLOUDNAME1.sh"})," and call ",(0,o.jsx)(n.code,{children:"run_CLOUDNAME1.sh"})," from there. Don't forget to adjust ",(0,o.jsx)(n.code,{children:"startup/run-apimon-in-tmux.sh"})," and ",(0,o.jsx)(n.code,{children:"startup/kill-apimon-in-tmux.sh"})," to start more windows."]}),"\n",(0,o.jsxs)(n.p,{children:["It is not recommended to run multiple instances against the same OpenStack project however. While the ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," script carefully keeps track of its own resources and avoids to delete things it has not created, this is not the case for the ",(0,o.jsx)(n.code,{children:"run_CLOUDNAME.sh"})," script, which is explicitly meant to identify anything in the target project that was created by a health monitor and clean it up. If it hits the resources that are currently in use by another health mon instance, this will create spurious errors. This will happen every ~200 iterations, so you could still have some short-term coexistence when you are performing debug operations."]}),"\n",(0,o.jsx)(n.h2,{id:"alarming-and-logs",children:"Alarming and Logs"}),"\n",(0,o.jsx)(n.h3,{id:"email",children:"eMail"}),"\n",(0,o.jsxs)(n.p,{children:["If wanted, the ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," can send statistics and error messages via email, so operator personnel is informed about the state of the monitoring. This email notification service potentially results in many emails; one error may produce several mails. So in case of a systematic problem, expect to receive dozens of mails per hour. This can be reduced a bit using the ",(0,o.jsx)(n.code,{children:"-a N"})," and ",(0,o.jsx)(n.code,{children:"-R"})," options. In order to enable sending emails from the driver VM, it needs to have ",(0,o.jsx)(n.code,{children:"postfix"})," (or another MTA) installed and configured and outgoing connections for eMail need to be allowed. Note that many operators prefer not to use the eMail notifications but rather rely on looking at the dashboards (see further down) regularly."]}),"\n",(0,o.jsxs)(n.p,{children:["Once you have configured ",(0,o.jsx)(n.code,{children:"postfix"}),", you can enable eMail notifications using the option ",(0,o.jsx)(n.code,{children:"-e"}),". Using it twice allows you to differentiate between notes (statistical summaries) and errors. If you want to send mails to more than one recipient, you can do so by passing ",(0,o.jsx)(n.code,{children:"ALARM_EMAIL_ADDRESSES"})," and ",(0,o.jsx)(n.code,{children:"NOTE_EMAIL_ADDRESSES"})," environment variables to ",(0,o.jsx)(n.code,{children:"api_monitor.sh"}),", e.g. by setting it in the ",(0,o.jsx)(n.code,{children:"run_CLOUDNAME.sh"}),"."]}),"\n",(0,o.jsx)(n.h3,{id:"log-files",children:"Log files"}),"\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.code,{children:"api_monitor.sh"})," writes a log file with the name ",(0,o.jsx)(n.code,{children:"APIMonitor_TIMESTAMP.log"}),". It contains a bit of information to see the progress of the script; more importantly, it logs every single openstack CLI call along with parameters and results. (",(0,o.jsx)(n.code,{children:"TIMESTAMP"})," is the Unix time, i.e. seconds since 1970-01-01 00:00:00 UTC.)"]}),"\n",(0,o.jsxs)(n.p,{children:["Note that ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," does take some care not to expose secrets -- since v1.99, it does also redact issued tokens (which would otherwise give you up to 24hrs of access). But the Log files still may contain moderately sensitive information, so we suggest to not share it with untrusted parties."]}),"\n",(0,o.jsxs)(n.p,{children:["The log file is written to the file system. After finishing the 200 iterations, the log file is compressed. If the environment variable ",(0,o.jsx)(n.code,{children:"SWIFTCONTAINER"})," has been set (in ",(0,o.jsx)(n.code,{children:"run_COULDNAME.sh"}),") when starting ",(0,o.jsx)(n.code,{children:"api_monitor.sh"}),". the log file will be uploaded to a container with that name if it exists and if the swift object storage service is supported by the cloud. So create the container (a bucket in S3 speak) before if you want to use this: ",(0,o.jsx)(n.code,{children:"export SWIFTCONTAINER=OSHM_Logs; openstack container create $SWIFTCONTAINER"})]}),"\n",(0,o.jsxs)(n.p,{children:["After the 200 iterations, a ",(0,o.jsx)(n.code,{children:".psv"})," file (pipe-separated values) is created ",(0,o.jsx)(n.code,{children:"Stats.STARTTIME-ENDTIME.psv"})," (with times as calendar dates) which contains a bit of statistics on the last 200 iterations. This one will also be uploaded to $SWIFTCONTAINER (if configured)."]}),"\n",(0,o.jsx)(n.h2,{id:"data-collection-and-dashboard",children:"Data collection and dashboard"}),"\n",(0,o.jsxs)(n.p,{children:["See ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/dashboard/README.md",children:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/dashboard/README.md"})]}),"\n",(0,o.jsx)(n.h3,{id:"telegraf",children:"telegraf"}),"\n",(0,o.jsx)(n.p,{children:"To install telegraf on Debian 12, we need to add the apt repository provided by InfluxData:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:'sudo curl -fsSL https://repos.influxdata.com/influxdata-archive_compat.key -o /etc/apt/keyrings/influxdata-archive_compat.key\necho "deb [signed-by=/etc/apt/keyrings/influxdata-archive_compat.key] https://repos.influxdata.com/debian stable main" | sudo tee /etc/apt/sources.list.d/influxdata.list\nsudo apt update\nsudo apt -y install telegraf\n'})}),"\n",(0,o.jsxs)(n.p,{children:["In the config file ",(0,o.jsx)(n.code,{children:"/etc/telegraf/telegraf.conf"}),", we enable"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'[[inputs.influxdb_listener]]\n service_address = ":8186"\n\n[[outputs.influxdb]]\n urls = ["http://127.0.0.1:8086"]\n'})}),"\n",(0,o.jsxs)(n.p,{children:["and restart the service (",(0,o.jsx)(n.code,{children:"sudo systemctl restart telegraf"}),").\nEnable it on system startup: ",(0,o.jsx)(n.code,{children:"sudo systemctl enable telegraf"}),"."]}),"\n",(0,o.jsx)(n.h3,{id:"influxdb",children:"influxdb"}),"\n",(0,o.jsx)(n.p,{children:"We proceed to influxdb:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"sudo apt-get install influxdb\n"})}),"\n",(0,o.jsxs)(n.p,{children:["In the configuration file ",(0,o.jsx)(n.code,{children:"/etc/influxdb/influxdb.conf"}),", ensure that the http interface on port 8086 is enabled."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'[http]\n enabled = true\n bind-address = ":8086"\n'})}),"\n",(0,o.jsxs)(n.p,{children:["Restart influxdb as needed with ",(0,o.jsx)(n.code,{children:"sudo systemctl restart influxdb"}),".\nAlso enable it on system startup: ",(0,o.jsx)(n.code,{children:"sudo systemctl enable influxdb"}),"."]}),"\n",(0,o.jsxs)(n.h3,{id:"add--s-cloudname-to-your-run_cloudnamesh-script",children:["Add ",(0,o.jsx)(n.code,{children:"-S CLOUDNAME"})," to your ",(0,o.jsx)(n.code,{children:"run_CLOUDNAME.sh"})," script"]}),"\n",(0,o.jsxs)(n.p,{children:["You need to tell the monitor that it should send data via telegraf to influxdb by adding the parameter ",(0,o.jsx)(n.code,{children:"-S CLOUDNAME"})," to the ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," call in ",(0,o.jsx)(n.code,{children:"run_CLOUDNAME.sh"}),". Restart it (see above) to make the change effective immediately (and not only after 200 iterations complete)."]}),"\n",(0,o.jsx)(n.h3,{id:"grafana",children:"grafana"}),"\n",(0,o.jsx)(n.h4,{id:"basic-config",children:"Basic config"}),"\n",(0,o.jsxs)(n.p,{children:["Finally grafana: We (still as root) follow ",(0,o.jsx)(n.a,{href:"https://www.server-world.info/en/note?os=Debian_12&p=grafana",children:"https://www.server-world.info/en/note?os=Debian_12&p=grafana"})]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'sudo wget -q -O /usr/share/keyrings/grafana.key https://packages.grafana.com/gpg.key\necho "deb [signed-by=/usr/share/keyrings/grafana.key] https://packages.grafana.com/oss/deb stable main" | sudo tee -a /etc/apt/sources.list.d/grafana.list\nsudo apt update\nsudo apt -y install grafana\n'})}),"\n",(0,o.jsxs)(n.p,{children:["The config file ",(0,o.jsx)(n.code,{children:"/etc/grafana/grafana.ini"})," needs some adjustments:"]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["Set the hostname in ",(0,o.jsx)(n.code,{children:"[server]"})," section: ",(0,o.jsx)(n.code,{children:"domain = health.YOURCLOUD.sovereignit.cloud"}),". Set the ",(0,o.jsx)(n.code,{children:"protocol = https"})," if not enabled by default.\nYou can use a hostname of your liking, but we will need to create TLS certificates for this host. So we should have control over DNS TXT records for this domain if we want to use Let's Encrypt with DNSAUTH. The ",(0,o.jsx)(n.code,{children:"sovereignit.cloud"})," domain is controlled by the SCS project team and has been used for a number of health mon instances.\nIn this same section, set ",(0,o.jsx)(n.code,{children:"cert_file = /etc/grafana/health-fullchain.pem"})," and ",(0,o.jsx)(n.code,{children:"cert_key = /etc/grafana/health-key.pem"}),". Ensure that both files are readable by ",(0,o.jsx)(n.code,{children:"root:grafana"})," and that the key file is ",(0,o.jsx)(n.em,{children:"not"})," world-readable."]}),"\n",(0,o.jsxs)(n.li,{children:["Configure the admin access. In section ",(0,o.jsx)(n.code,{children:"[security]"}),", set the ",(0,o.jsx)(n.code,{children:"admin_user = admin"})," and ",(0,o.jsx)(n.code,{children:"admin_password = SOME_SECRET_PASS"})," which you keep private."]}),"\n",(0,o.jsxs)(n.li,{children:["Allow local data sources (same section): ",(0,o.jsx)(n.code,{children:"data_source_proxy_whitelist = localhost:8088 localhost:8086"})]}),"\n",(0,o.jsxs)(n.li,{children:["Let's disallow user signup (in section ",(0,o.jsx)(n.code,{children:"[users]"}),"): ",(0,o.jsx)(n.code,{children:"allow_sign_up = false"})," and ",(0,o.jsx)(n.code,{children:"allow_org_create = false"}),"."]}),"\n",(0,o.jsxs)(n.li,{children:["We do the OIDC connection with ",(0,o.jsx)(n.code,{children:"[auth.github]"})," later."]}),"\n"]}),"\n",(0,o.jsxs)(n.p,{children:["We can now restart the service: ",(0,o.jsx)(n.code,{children:"sudo systemctl restart grafana-server"}),".\nBeing at it, also enable it on system startup: ",(0,o.jsx)(n.code,{children:"sudo systemctl enable grafana-server"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["You should now be able to access your dashboard on ",(0,o.jsx)(n.code,{children:"https://health.YOURCLOUD.sovereignit.de:3000"})," and log in via the configured username ",(0,o.jsx)(n.code,{children:"admin"})," and your ",(0,o.jsx)(n.code,{children:"SOME_SECRET_PASS"})," password."]}),"\n",(0,o.jsx)(n.h4,{id:"enable-influx-database-in-grafana",children:"Enable influx database in grafana"}),"\n",(0,o.jsxs)(n.p,{children:["In the dashboard, go to Home, Connections, choose InfluxDB and Add new datasource. The defaults (database name, InfluxQL query language) work. You need to explicitly set the URL to ",(0,o.jsx)(n.code,{children:"http://localhost:8086"})," (despite this being the suggestion). Set the database name to ",(0,o.jsx)(n.code,{children:"telegraf"}),". Save&test should succeed."]}),"\n",(0,o.jsx)(n.h4,{id:"importing-the-dashboard",children:"Importing the dashboard"}),"\n",(0,o.jsxs)(n.p,{children:["Go to Home, Dashboards, New, Import.\nUpload the dashboard ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/dashboard/openstack-health-dashboard.json",children:".json file"})," from the repository, user the ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/dashboard/openstack-health-dashboard-10.json",children:"Grafana-10 variant"})," if you use Grafana 10 or newer."]}),"\n",(0,o.jsx)(n.p,{children:"In the dashboard, go to the settings gear wheel, variables, mycloud and add CLOUDNAME to the list of clouds that can be displayed. (There are some existing SCS clouds in that list.)\nSave."}),"\n",(0,o.jsx)(n.p,{children:"Now choose CLOUDNAME as cloud (top of the dashboard, rightmost dropdown for the mycloud filter variable)."}),"\n",(0,o.jsx)(n.h4,{id:"no-data-displayed",children:"No data displayed?"}),"\n",(0,o.jsx)(n.p,{children:'Sometimes, you may see a panel displaying "no data" despite the fact that the first full iteration of data has been sent to influx already. This may be a strange interaction between the browser and Grafana -- we have not analyzed whether that is a bug in Grafana.'}),"\n",(0,o.jsx)(n.p,{children:"One way to work around is to go into the setting of the panel (the three dots in the upper right corner), go to edit and start changing one aspect of the query. Apply. Change it back to the original. Apply. The data will appear. Save to be sure it's conserved."}),"\n",(0,o.jsx)(n.h4,{id:"dashboard-features",children:"Dashboard features"}),"\n",(0,o.jsx)(n.p,{children:"Look at the top line filters: You can filter to only see certain API calls or certain resources; the graphs are very crowded and filtering to better see what you want to focus on is very well intended."}),"\n",(0,o.jsx)(n.p,{children:"The first row of panels give a health impression; there are absolute numbers as well as percentage numbers and the panels turn amber and red in case you have too many errors. Note that the colors on the panels with absolute numbers can not take into account whether you look at just a few hours or at weeks. Accordingly, consider the colors a reasonable hint if things are green or not when looking at a ~24 hours interval. This limitation does not affect the colors on the percentage graph, obviously."}),"\n",(0,o.jsx)(n.p,{children:"You can change the time interval and zoom in also by marking an interval with the mouse. Zooming out to a few months can be a very useful feature to see trends and watch e.g. your API performance, your resource creation times or the benchmarks change over the long term."}),"\n",(0,o.jsx)(n.h4,{id:"github-oidc-integration",children:"github OIDC integration"}),"\n",(0,o.jsxs)(n.p,{children:["The SCS providers do allow all github users that belong to the SovereignCloudStack organization to get Viewer access to the dashboards by adding a ",(0,o.jsx)(n.code,{children:"client_id"})," and ",(0,o.jsx)(n.code,{children:"client_secret"})," in the ",(0,o.jsx)(n.code,{children:"[github.auth]"})," section that you request from the SCS github admins (github's oauth auth). This allows to exchange experience and to get a feeling for the achievable stability. (Hint: A single digit number of API call fails per week and no other failures is achievable on loaded clouds.)"]}),"\n",(0,o.jsx)(n.h2,{id:"alternative-approach-to-install-and-configure-the-dashboard-behind-a-reverse-proxy",children:"Alternative approach to install and configure the dashboard behind a reverse proxy"}),"\n",(0,o.jsxs)(n.p,{children:["Install influxdb via apt: ",(0,o.jsx)(n.a,{href:"https://docs.influxdata.com/influxdb/v1/introduction/install/#installing-influxdb-oss",children:"https://docs.influxdata.com/influxdb/v1/introduction/install/#installing-influxdb-oss"}),"\nInstall telegraf (same apt repo as influxdb): ",(0,o.jsx)(n.code,{children:"sudo apt update && sudo apt install telegraf"}),"\nInstall grafana: ",(0,o.jsx)(n.a,{href:"https://grafana.com/docs/grafana/latest/setup-grafana/installation/debian/#install-from-apt-repository",children:"https://grafana.com/docs/grafana/latest/setup-grafana/installation/debian/#install-from-apt-repository"})]}),"\n",(0,o.jsx)(n.p,{children:"Prepare configuration by using the config files from the repository as an alternative to doing the changes manually (as described above):"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"sudo cp dashboard/telegraf.conf /etc/telegraf && sudo chown root:root /etc/telegraf/telegraf.conf && sudo chmod 0644 /etc/telegraf/telegraf.conf\nsudo cp dashboard/config.toml /etc/influxdb && sudo chown root:influxdb /etc/influxdb/config.toml && sudo chmod 0640 /etc/influxdb/config.toml\nsudo cp dashboard/grafana.ini /etc/grafana && sudo chown root:grafana /etc/grafana/grafana.ini && sudo chmod 0640 /etc/grafana/grafana.ini\n"})}),"\n",(0,o.jsx)(n.p,{children:"These config files should work as long as the versions of telegraf, influxdb and grafana don't evolve too far from the ones used in the repository. (Otherwise refer to above instructions how to tweak the default config files.)"}),"\n",(0,o.jsxs)(n.p,{children:["Changes to ",(0,o.jsx)(n.code,{children:"/etc/grafana/grafana.ini"})," as we do tls termination at the reverse proxy:"]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["set ",(0,o.jsx)(n.code,{children:"protocol = http"})]}),"\n",(0,o.jsxs)(n.li,{children:["comment out ",(0,o.jsx)(n.code,{children:"domain"})," option (? FIXME) or set it to the hostname"]}),"\n",(0,o.jsxs)(n.li,{children:["comment out ",(0,o.jsx)(n.code,{children:"cert_*"})," options"]}),"\n"]}),"\n",(0,o.jsxs)(n.p,{children:["Also change the admin password in ",(0,o.jsx)(n.code,{children:"grafana.ini"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["Changes to ",(0,o.jsx)(n.code,{children:"/etc/grafana/grafana.ini"})," if github auth should not be used yet:"]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["comment out whole ",(0,o.jsx)(n.code,{children:"[auth.github]"})," section for now (can be enabled later)"]}),"\n"]}),"\n",(0,o.jsxs)(n.p,{children:["Restart services: ",(0,o.jsx)(n.code,{children:"sudo systemctl restart telegraf && sudo systemctl restart influxdb && sudo systemctl restart grafana-server"})]}),"\n",(0,o.jsx)(n.p,{children:"Configuration in grafana web gui:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["Login to grafana ",(0,o.jsx)(n.code,{children:"http(s)://:3000"})," with user admin and default password from ",(0,o.jsx)(n.code,{children:"/etc/grafana/grafana.ini"})," and change password."]}),"\n",(0,o.jsxs)(n.li,{children:["Create influxdb datasource with url ",(0,o.jsx)(n.code,{children:"http://localhost:8086"})," and database name ",(0,o.jsx)(n.code,{children:"telegraf"}),"."]}),"\n",(0,o.jsxs)(n.li,{children:["Finally import dashboard ",(0,o.jsx)(n.code,{children:"dashboard/openstack-health-dashboard.json"})," to grafana."]}),"\n"]}),"\n",(0,o.jsx)(n.p,{children:"TODO:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"Reverse proxy (aka ingress) with Let's Encrypt cert"}),"\n",(0,o.jsx)(n.li,{children:"Github auth as described above"}),"\n"]}),"\n",(0,o.jsx)(n.h2,{id:"maintenance",children:"Maintenance"}),"\n",(0,o.jsx)(n.p,{children:"The driver VM is a snowflake: A manually set up system (unless you automate all the above steps, which is possible of course) that holds data and is long-lived. As such it's important to be maintained."}),"\n",(0,o.jsx)(n.h3,{id:"unattended-upgrades",children:"Unattended upgrades"}),"\n",(0,o.jsxs)(n.p,{children:["It is recommended to ensure maintenance updates are deployed automatically. These are unlikely to negatively impact the openstack-health-monitor. See ",(0,o.jsx)(n.a,{href:"https://wiki.debian.org/UnattendedUpgrades",children:"https://wiki.debian.org/UnattendedUpgrades"}),". If you decide against unattended upgrades, it is recommended to install updates manually regularly and especially watch out for issues that affect the services that are exposed to the world: sshd (port 22) and grafana (port 3000)."]}),"\n",(0,o.jsx)(n.h3,{id:"updating-openstack-health-monitor",children:"Updating openstack-health-monitor"}),"\n",(0,o.jsxs)(n.p,{children:["You can just do a ",(0,o.jsx)(n.code,{children:"git update"})," in the ",(0,o.jsx)(n.code,{children:"openstack-health-monitor"})," directory to get the latest improvements. Note that these will only become effective after the 200 iterations have completed. You can speed this up by injecting a ",(0,o.jsx)(n.code,{children:"^C"}),", see above in the restart section."]}),"\n",(0,o.jsx)(n.h3,{id:"backup",children:"Backup"}),"\n",(0,o.jsxs)(n.p,{children:["The system holds two things that you might consider valuable for long-term storage:\n(1) The log files. These are compressed and uploaded to object storage if you enable the ",(0,o.jsx)(n.code,{children:"SWIFTCONTAINER"})," setting, which probably means that these do not need any additional backing up then.\n(2) The influx time series data. Back up the data in ",(0,o.jsx)(n.code,{children:"/var/lib/influxdb"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["Obviously, if you want to recover quickly from a crash, you might consider to also back up telegraf, influx and grafana config files as well as the edited startup scripts, ",(0,o.jsx)(n.code,{children:"clouds.yaml"}),", etc. Be careful not to expose sensitive data by granting too generous access to your backed up files."]}),"\n",(0,o.jsx)(n.h2,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,o.jsx)(n.h3,{id:"debugging-issues",children:"Debugging issues"}),"\n",(0,o.jsx)(n.p,{children:"In case there is trouble with your cloud, the normal course of action to analyze is as follows:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"Look at the dashboard (see above)"}),"\n",(0,o.jsxs)(n.li,{children:["Connect to the driver VM and attach to the tmux session and look at the console output of ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})]}),"\n",(0,o.jsx)(n.li,{children:"Analyze the logfile (locally on the driver VM or grab it from the object storage)"}),"\n"]}),"\n",(0,o.jsx)(n.h3,{id:"analyzing-failures",children:"Analyzing failures"}),"\n",(0,o.jsxs)(n.p,{children:["When VM instances are created successfully, but then end up in ",(0,o.jsx)(n.code,{children:"ERROR"})," state, the ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," does an explicit ",(0,o.jsx)(n.code,{children:"openstack server show"}),", so you will find some details in the tmux session, in the alarm emails (if you use those) and in the log files."]}),"\n",(0,o.jsxs)(n.p,{children:["Sometimes the VMs end up being ",(0,o.jsx)(n.code,{children:"ACTIVE"})," as wanted but then they can't be accessed via ssh. More often than not, this is a problem with meta-data service on a compute host. Without metadata, not ssh key is injected and login will fail."]}),"\n",(0,o.jsxs)(n.p,{children:["To gather more details, you can look at the console output ",(0,o.jsx)(n.code,{children:"openstack console log show VM"})," (where ",(0,o.jsx)(n.code,{children:"VM"})," is the name of the uuid of the affected VM instance). The cloud-init output is often enough to see what has gone wrong. You can log in to the VMs: The jumphosts are directly accessible via ",(0,o.jsx)(n.code,{children:"ssh -i APIMonitor_XXXXX_JH.pem debian@FIP"}),", whereas the JumpHost does port forwarding to the other VMs that don't have their own floating IP address: ",(0,o.jsx)(n.code,{children:"ssh -i APIMonitor_XXXXX_VM.pem -p 222 debian@FIP"}),". Replace ",(0,o.jsx)(n.code,{children:"XXXXX"})," with the number in your current APIMonitor prefix, ",(0,o.jsx)(n.code,{children:"FIP"})," with the floating IP address of the responsible JumpHost and ",(0,o.jsx)(n.code,{children:"debian"})," with the user name used by the images you boot. Use ",(0,o.jsx)(n.code,{children:"223"})," to connect to the second VM in the network, ",(0,o.jsx)(n.code,{children:"224"})," the third etc."]}),"\n",(0,o.jsxs)(n.p,{children:["When logged in, look at ",(0,o.jsx)(n.code,{children:"/var/log/cloud-init-output.log"})," and ",(0,o.jsx)(n.code,{children:"/var/log/cloud-init.log"}),". You can find the metadata in ",(0,o.jsx)(n.code,{children:"/var/lib/cloud/instance/"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["You will not have much time to look around -- the still running ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," script does continue and clean things up again. So you might want to suspend it with ",(0,o.jsx)(n.code,{children:"^Z"})," (and continue it later with ",(0,o.jsx)(n.code,{children:"fg"}),"). Another option is to not stop the regular monitoring, but start a second instance manually; see above notes for running multiple instances though. If you start a second instance manually against the same project, do NOT use the ",(0,o.jsx)(n.code,{children:"run_CLOUDNAME.sh"})," script as it would do cleanup against the running instance, but rather copy the ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," command line from the bottom (without the ",(0,o.jsx)(n.code,{children:"exec"}),"), reduce the iterations to a few (unless you need a lot to trigger the issue again) and attach ",(0,o.jsx)(n.code,{children:"-w -1"})," to make the script stop its operation (and wait for Enter) once it hits an error. Of course, you still will face cleanup when the continuing main script hits its 200th iteration and you have chosen to run this second instance against the same project in the same cloud. After analyzing, do not forget to go back to the tmux window where the stopped script is running and do hit Enter, so it can continue and do its cleanup work."]}),"\n",(0,o.jsx)(n.h3,{id:"cleaning-things-up",children:"Cleaning things up"}),"\n",(0,o.jsx)(n.p,{children:"If you are unlucky, the script fails to clean something up. A volume may not have been named (because of a cinder failure) or all the logic may have gone wrong, e.g. the heuristic to avoid leaking floating IPs. You can try to clean this up using the normal openstack commands (or horizon dashboard)."}),"\n",(0,o.jsx)(n.p,{children:"There are a few things that may need support from a cloud admin:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["Volumes may end up permanently in a ",(0,o.jsx)(n.code,{children:"deleting"})," or ",(0,o.jsx)(n.code,{children:"reserved"})," state or may be ",(0,o.jsx)(n.code,{children:"in-use"}),", attached to a VM that has long gone. The admin needs to set the state to ",(0,o.jsx)(n.code,{children:"error"})," and then delete them."]}),"\n",(0,o.jsxs)(n.li,{children:["Loadbalancers may end up in a ",(0,o.jsx)(n.code,{children:"PENDING_XXX"})," state (",(0,o.jsx)(n.code,{children:"XXX"})," being ",(0,o.jsx)(n.code,{children:"CREATE"}),", ",(0,o.jsx)(n.code,{children:"UPDATE"})," or ",(0,o.jsx)(n.code,{children:"DELETE"}),") without ever changing. This also needs the cloud admin to set the status to ",(0,o.jsx)(n.code,{children:"ERROR"}),", so it can be cleaned up. amphorae are more prone to this than ovn LBs."]}),"\n"]}),"\n",(0,o.jsx)(n.p,{children:"More like these may happen, but those two are the only ones that have been observed to happen occasionally. Some services seem to be less robust than others against an event in the event queue (rabbitmq) being lost or an connection to be interrupted."}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsxs)(n.em,{children:["The source of this document can be found in the ",(0,o.jsx)(n.a,{href:"https://raw.githubusercontent.com/SovereignCloudStack/openstack-health-monitor/main/docs/Debian12-Install.md",children:"SovereignCloudStack/openstack-health-monitor"})," repository."]})}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsx)(n.em,{children:"Author: SCS Community, License: CC by Attribution 4.0 International"})})]})}function h(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(c,{...e})}):c(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>r,a:()=>a});var o=t(7294);const s={},i=o.createContext(s);function a(e){const n=o.useContext(i);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),o.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/bd92db3a.830a6441.js b/assets/js/bd92db3a.830a6441.js deleted file mode 100644 index 8051bec865..0000000000 --- a/assets/js/bd92db3a.830a6441.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkosism=self.webpackChunkosism||[]).push([[1594],{1693:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>r,toc:()=>d});var o=t(5893),s=t(1151);const i={sidebar_label:"OpenStack Health Monitor"},a="Setting up OpenStack health monitor on Debian",r={id:"guides/operations-guide/openstack/tools/openstack-health-monitor",title:"Setting up OpenStack health monitor on Debian",description:"Kurt Garloff, 2024-02-20",source:"@site/docs/guides/operations-guide/openstack/tools/openstack-health-monitor.md",sourceDirName:"guides/operations-guide/openstack/tools",slug:"/guides/operations-guide/openstack/tools/openstack-health-monitor",permalink:"/docs/guides/operations-guide/openstack/tools/openstack-health-monitor",draft:!1,unlisted:!1,editUrl:"https://github.com/osism/osism.github.io/tree/main/docs/guides/operations-guide/openstack/tools/openstack-health-monitor.md",tags:[],version:"current",frontMatter:{sidebar_label:"OpenStack Health Monitor"},sidebar:"tutorialSidebar",previous:{title:"Simple Stress",permalink:"/docs/guides/operations-guide/openstack/tools/simple-stress"},next:{title:"Cinder",permalink:"/docs/guides/operations-guide/openstack/cinder"}},l={},d=[{value:"Intro",id:"intro",level:2},{value:"Setting up the driver VM",id:"setting-up-the-driver-vm",level:2},{value:"Internal vs external monitoring",id:"internal-vs-external-monitoring",level:3},{value:"Unprivileged operation",id:"unprivileged-operation",level:3},{value:"Driver VM via openstack CLI",id:"driver-vm-via-openstack-cli",level:3},{value:"Configuring openstack CLI on the driver VM",id:"configuring-openstack-cli-on-the-driver-vm",level:3},{value:"Custom CA",id:"custom-ca",level:3},{value:"Your first api_monitor.sh iteration",id:"your-first-api_monitorsh-iteration",level:2},{value:"Resource impact and charging",id:"resource-impact-and-charging",level:3},{value:"Automating startup and cleanup",id:"automating-startup-and-cleanup",level:2},{value:"Changing parameters and restarting",id:"changing-parameters-and-restarting",level:3},{value:"Multiple instances",id:"multiple-instances",level:3},{value:"Alarming and Logs",id:"alarming-and-logs",level:2},{value:"eMail",id:"email",level:3},{value:"Log files",id:"log-files",level:3},{value:"Data collection and dashboard",id:"data-collection-and-dashboard",level:2},{value:"telegraf",id:"telegraf",level:3},{value:"influxdb",id:"influxdb",level:3},{value:"Add -S CLOUDNAME to your run_CLOUDNAME.sh script",id:"add--s-cloudname-to-your-run_cloudnamesh-script",level:3},{value:"grafana",id:"grafana",level:3},{value:"Basic config",id:"basic-config",level:4},{value:"Enable influx database in grafana",id:"enable-influx-database-in-grafana",level:4},{value:"Importing the dashboard",id:"importing-the-dashboard",level:4},{value:"No data displayed?",id:"no-data-displayed",level:4},{value:"Dashboard features",id:"dashboard-features",level:4},{value:"github OIDC integration",id:"github-oidc-integration",level:4},{value:"Alternative approach to install and configure the dashboard behind a reverse proxy",id:"alternative-approach-to-install-and-configure-the-dashboard-behind-a-reverse-proxy",level:2},{value:"Maintenance",id:"maintenance",level:2},{value:"Unattended upgrades",id:"unattended-upgrades",level:3},{value:"Updating openstack-health-monitor",id:"updating-openstack-health-monitor",level:3},{value:"Backup",id:"backup",level:3},{value:"Troubleshooting",id:"troubleshooting",level:2},{value:"Debugging issues",id:"debugging-issues",level:3},{value:"Analyzing failures",id:"analyzing-failures",level:3},{value:"Cleaning things up",id:"cleaning-things-up",level:3}];function c(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.a)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"setting-up-openstack-health-monitor-on-debian",children:"Setting up OpenStack health monitor on Debian"}),"\n",(0,o.jsx)(n.p,{children:"Kurt Garloff, 2024-02-20"}),"\n",(0,o.jsx)(n.h2,{id:"intro",children:"Intro"}),"\n",(0,o.jsxs)(n.p,{children:["The development of ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/",children:"openstack-health-monitor"})," was done on ",(0,o.jsx)(n.a,{href:"https://kfg.images.obs-website.eu-de.otc.t-systems.com/",children:"openSUSE 15.x images"}),", just because the author is very familiar with it and has some of the needed tools preinstalled. That said, the setup is not depending on anything specific from openSUSE and should work on every modern Linux distribution."]}),"\n",(0,o.jsx)(n.p,{children:"Setting it up again in a different environment using Debian 12 images avoids a few of the shortcuts that were used and thus should be very suitable instructions to get it working in general. The step by step instructions are covered here."}),"\n",(0,o.jsxs)(n.p,{children:["Note: This is a rather classical snowflake setup -- we create a VM and do some manual configuration to get everything configured. Having it well documented here should make this more replicatable, and is an important precondition for more automation, but larger steps to full automate this using ansible or helm charts (in a containerized variant) are not addressed here. As we expect a ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/scs-health-monitor",children:"successor project"})," for the increasingly hard to maintain shell code, this may not be worth the trouble."]}),"\n",(0,o.jsxs)(n.p,{children:["openstack-health-monitor implements a scripted scenario test with a large shell-script that uses the openstackclient tools to set up the scenario, test it and tear everything down again in a loop. Any errors are recorded, as well as timings and some very basic benchmarks. The script sets up some virtual network infrastructure (routers, networks, subnets, floating IPs), security groups, keypairs, volumes and finally boots some VMs. Access to these is tested (ensuring metadata injection works) and connectivity between them tested and measured. A loadbalancer (optionally) is set up with a health-monitor and access via it before and after killing some backends is tested.\nThe scenario is described in a bit more detail in the ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/README.md",children:"repository's README.md"})," file."]}),"\n",(0,o.jsxs)(n.p,{children:["The openstack-health-monitor is not the intended long-term solution for monitoring your infrastructure. The SCS project has a project underway that will create more modern, flexible, and more maintainable monitoring infrastructure; the concepts are described on the ",(0,o.jsx)(n.a,{href:"https://docs.scs.community/docs/category/monitoring",children:"monitoring section"})," of the project's documentation. The openstack-health-monitor will thus not see any significant enhancements any more; it will be maintained and kept alive as long as there are users. This guide exclusively focuses on how to set it up."]}),"\n",(0,o.jsx)(n.h2,{id:"setting-up-the-driver-vm",children:"Setting up the driver VM"}),"\n",(0,o.jsxs)(n.p,{children:["So we start a ",(0,o.jsx)(n.code,{children:"Debian 12"})," image on a cloud of our choice. This should work on any OpenStack cloud that is reasonably standard;\nthe instructions use flavor names and image names from the SCS standards.\nFor many, the simplest way may be to use the Web-UI of their cloud (e.g. horizon for OpenStack)."]}),"\n",(0,o.jsx)(n.h3,{id:"internal-vs-external-monitoring",children:"Internal vs external monitoring"}),"\n",(0,o.jsx)(n.p,{children:"There are pros and cons to run the driver VM in the same cloud that is also under test. We obviously don't test the external reachability of the cloud (more precisely its API endpoints and VMs) if we run it on the same cloud -- which may or may not be desirable. Having the tests happily continuing to collect data may actually be valuable in times when external access is barred. If the cloud goes down, we will no longer see API calls against it, although the information of them not being available does not reveal much in terms of insight into the reasons for the outage. Also, the driver VM is the only long-lived VM in the openstack-health-monitor setup, so it may be useful to have it in the same cloud to reveal any issues that do not occur on the short-lived resources created and deleted by the health-monitor."}),"\n",(0,o.jsx)(n.p,{children:"The author tends to see running it internally as advantageous -- ideally combined with a simple API reachability test from the outside that sends alarms as needed to detect any reachability problems."}),"\n",(0,o.jsx)(n.h3,{id:"unprivileged-operation",children:"Unprivileged operation"}),"\n",(0,o.jsx)(n.p,{children:"Nothing in this test requires admin privileges on the cloud where the driver runs nor on the cloud under test. We do install and configure a few software packages in the driver VM, which requires sudo power there, but the script should just run as a normal user. For the cloud under test it is recommended to use a user (or an application credential) with a normal tenant member role to access the cloud under test. If you can, give it an OpenStack project on its own."}),"\n",(0,o.jsxs)(n.p,{children:["If ",(0,o.jsx)(n.code,{children:"openstack availability zone list --compute"})," fails for you without admin rights, please fix your openstack client. (Versions 6.3.0 and 6.4.0 are broken.) Do not consider giving the OpenStack Healh-Monitor admin power. (Note: It has a workaround for the broken AZ listing using curl now.)"]}),"\n",(0,o.jsx)(n.h3,{id:"driver-vm-via-openstack-cli",children:"Driver VM via openstack CLI"}),"\n",(0,o.jsxs)(n.p,{children:["The author prefers to setup the VM via ",(0,o.jsx)(n.code,{children:"openstack"})," CLI tooling. He has working entries for all clouds he uses in his ",(0,o.jsx)(n.code,{children:"~/.config/openstack/clouds.yaml"})," and ",(0,o.jsx)(n.code,{children:"secure.yaml"})," and has exported the ",(0,o.jsx)(n.code,{children:"OS_CLOUD"})," environment variable to point to the cloud he is working on to set up the driver VM. The author uses the ",(0,o.jsx)(n.code,{children:"bash"})," shell. All of this of course could be scripted."]}),"\n",(0,o.jsx)(n.p,{children:"So here we go"}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsxs)(n.li,{children:["Create the network setup for a VM in a network ",(0,o.jsx)(n.code,{children:"oshm-network"})," with an IPv4 subnet, connected to a router that connects (and by default SNATs) to the public network."]}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"PUBLIC=$(openstack network list --external -f value -c Name)\nopenstack router create oshm-router\nopenstack router set --external-gateway $PUBLIC oshm-driver-router\nopenstack network create oshm-network\nopenstack subnet create --subnet-range 192.168.192.0/24 --network oshm-network oshm-subnet\nopenstack router add subnet oshm-router oshm-subnet\n"})}),"\n",(0,o.jsxs)(n.ol,{start:"2",children:["\n",(0,o.jsx)(n.li,{children:"Create a security group that allows ssh and ping access"}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"openstack security group create sshping\nopenstack security group rule create --ingress --ethertype ipv4 --protocol tcp --dst-port 22 sshping\nopenstack security group rule create --ingress --ethertype ipv4 --protocol icmp --icmp-type 8 sshping\n"})}),"\n",(0,o.jsxs)(n.ol,{start:"3",children:["\n",(0,o.jsx)(n.li,{children:"Being at it, we also create the security group for grafana"}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"openstack security group create grafana\nopenstack security group rule create --ingress --ethertype ipv4 --protocol tcp --dst-port 3000 grafana\n"})}),"\n",(0,o.jsxs)(n.ol,{start:"4",children:["\n",(0,o.jsx)(n.li,{children:"To connect to the VM via ssh later, we create an SSH keypair"}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"openstack keypair create --private-key ~/.ssh/oshm-key.pem oshm-key\nchmod og-r ~/.ssh/oshm-key.pem \n"})}),"\n",(0,o.jsxs)(n.p,{children:["Rather than creating a new key (and storing and protecting the private key), we could have passed ",(0,o.jsx)(n.code,{children:"--public-key"})," and used an existing keypair."]}),"\n",(0,o.jsxs)(n.ol,{start:"5",children:["\n",(0,o.jsx)(n.li,{children:"Look up Debian 12 image UUID."}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"IMGUUID=$(openstack image list --name \"Debian 12\" -f value -c ID | tr -d '\\r')\necho $IMGUUID\n"})}),"\n",(0,o.jsxs)(n.p,{children:["Sidenote: The ",(0,o.jsx)(n.code,{children:"tr"})," command is there to handle broken tooling that embeds a trailing ",(0,o.jsx)(n.code,{children:"\\r"})," in the output."]}),"\n",(0,o.jsxs)(n.ol,{start:"6",children:["\n",(0,o.jsx)(n.li,{children:"Boot the driver VM"}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"openstack server create --network oshm-network --key-name oshm-key --security-group default --security-group sshping --security-group grafana --flavor SCS-2V-4 --block-device boot_index=0,uuid=$IMGUUID,source_type=image,volume_size=10,destination_type=volume,delete_on_termination=true oshm-driver\n"})}),"\n",(0,o.jsxs)(n.p,{children:["Chose a flavor that exists on your cloud. Here we have used one without root disk and asked nova to create a volume on the fly by passing ",(0,o.jsx)(n.code,{children:"--block-device"}),". See ",(0,o.jsx)(n.a,{href:"https://scs.community/2023/08/21/diskless-flavors/",children:"diskless flavor blog article"}),". For flavors with local root disks, you could have used the ",(0,o.jsx)(n.code,{children:"--image $IMGUUID"})," parameter instead."]}),"\n",(0,o.jsxs)(n.ol,{start:"7",children:["\n",(0,o.jsxs)(n.li,{children:["Wait for it to boot (optional)\nYou can look at the boot log with ",(0,o.jsx)(n.code,{children:"openstack console log show oshm-driver"})," or connect to it via VNC at the URL given by ",(0,o.jsx)(n.code,{children:"openstack console url show oshm-driver"}),". You can of course also query openstack on the status ",(0,o.jsx)(n.code,{children:"openstack server list"})," or ",(0,o.jsx)(n.code,{children:"openstack server show oshm-driver"}),". You can also just create a simple loop:"]}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'declare -i ctr=0 RC=0\nwhile [ $ctr -le 120 ]; do\n STATUS="$(openstack server list --name oshm-driver -f value -c Status)"\n if [ "$STATUS" = "ACTIVE" ]; then echo "$STATUS"; break; fi \n if [ "$STATUS" = "ERROR" ]; then echo "$STATUS"; RC=1; break; fi\n if [ -z "$STATUS" ]; then echo "No such VM"; RC=2; break; fi\n sleep 2\n let ctr+=1\ndone\n# return $RC\nif [ $RC != 0 ]; then false; fi\n'})}),"\n",(0,o.jsxs)(n.ol,{start:"8",children:["\n",(0,o.jsx)(n.li,{children:"Attach a floating IP so it's reachable from the outside."}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'FIXEDIP=$(openstack server list --name oshm-driver -f value -c Networks | sed "s@^[^:]*:[^\']*\'\\([0-9\\.]*\\)\'.*\\$@\\1@")\nFIXEDPORT=$(openstack port list --fixed-ip ip-address=$FIXEDIP,subnet=oshm-subnet -f value -c ID)\necho $FIXEDIP $FIXEDPORT\nopenstack floating ip create --port $FIXEDPORT $PUBLIC\nFLOATINGIP=$(openstack floating ip list --fixed-ip-address $FIXEDIP -f value -c "Floating IP Address")\necho "Floating IP: $FLOATINGIP"\n'})}),"\n",(0,o.jsx)(n.p,{children:"Remember this floating IP address."}),"\n",(0,o.jsxs)(n.ol,{start:"9",children:["\n",(0,o.jsx)(n.li,{children:"Connect to it via ssh"}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"ssh -i ~/.ssh/oshm-key.pem debian@$FLOATINGIP\n"})}),"\n",(0,o.jsx)(n.p,{children:"On the first connection, you need to accept the new ssh host key. (Very careful people would compare the fingerprint with the console log output.)"}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsx)(n.strong,{children:"All the following commands are performed on the newly started driver VM."})}),"\n",(0,o.jsx)(n.h3,{id:"configuring-openstack-cli-on-the-driver-vm",children:"Configuring openstack CLI on the driver VM"}),"\n",(0,o.jsx)(n.p,{children:"We need to install the openstack client utilities."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"sudo apt-get update\nsudo apt-get install python3-openstackclient\nsudo apt-get install python3-cinderclient python3-octaviaclient python3-swiftclient python3-designateclient\n"})}),"\n",(0,o.jsxs)(n.p,{children:["Configure your cloud access in ",(0,o.jsx)(n.code,{children:"~/.config/openstack/clouds.yaml"})]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",children:"clouds:\n CLOUDNAME:\n interface: public\n identity-api-version: 3\n #region_name: REGION\n auth:\n auth_url: KEYSTONE_ENDPOINT\n project_id: PROJECT_UUID\n #alternatively project_name and project_domain_name\n user_domain_name: default\n # change to your real domain\n"})}),"\n",(0,o.jsxs)(n.p,{children:["and ",(0,o.jsx)(n.code,{children:"secure.yaml"})," (in the same directory)"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",children:"clouds:\n CLOUDNAME:\n auth:\n username: USERNAME\n password: PASSWORD\n"})}),"\n",(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.code,{children:"CLOUDNAME"})," can be freely chosen. This is the value passed to the openstack CLI with ",(0,o.jsx)(n.code,{children:"--os-cloud"})," or exported to your environment in ",(0,o.jsx)(n.code,{children:"OS_CLOUD"}),". The other uppercase words need to be adjusted to match your cloud. Hint: horizon typically lets you download a sample ",(0,o.jsx)(n.code,{children:"clouds.yaml"})," file that works (but lacks the password)."]}),"\n",(0,o.jsxs)(n.p,{children:["Protect your ",(0,o.jsx)(n.code,{children:"secure.yaml"})," from being read by others: ",(0,o.jsx)(n.code,{children:"chmod 0600 ~/.config/openstack/secure.yaml"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["If you are using application credentials instead of username, password to authenticate, you don't need to specify ",(0,o.jsx)(n.code,{children:"project_id"})," nor project's nor user's domain names in ",(0,o.jsx)(n.code,{children:"clouds.yaml"}),". Just (in ",(0,o.jsx)(n.code,{children:"secure.yaml"}),"):"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",children:'clouds:\n CLOUDNAME:\n auth_type: v3applicationcredential\n auth:\n application_credential_id: APPCRED_ID\n application_credential_secret: "APPCRED_SECRET"\n'})}),"\n",(0,o.jsx)(n.p,{children:"Configure this to be your default cloud:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"export OS_CLOUD=CLOUDNAME\n"})}),"\n",(0,o.jsxs)(n.p,{children:["You might consider adding this to your ",(0,o.jsx)(n.code,{children:"~/.bashrc"})," for convenience. Being at it, you might want to add ",(0,o.jsx)(n.code,{children:"export CLIFF_FIT_WIDTH=1"})," there as well to make openstack command output tables more readable (but sometimes less easy to cut'n'paste)."]}),"\n",(0,o.jsx)(n.p,{children:"Verify that your openstack CLI works:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"openstack catalog list\nopenstack server list\n"})}),"\n",(0,o.jsx)(n.p,{children:"You can use the same project as you use for your driver VM (and possibly other workloads). The openstack-health-monitor is carefully designed to not clean up anything that it has not created. There is however some trickiness, as not all resources have names (floating IPs for example do not) and sometimes names need to be assigned after creation of a resource (volumes of diskless flavors), so in case there are API errors, some heuristics is used to identify resources which may not be safe under all circumstances. So ideally, you have an extra project created just for the health-monitor and configure the credentials for it here, so you can not possibly hit any wrong resource in the script's extensive efforts to clean up in error cases."}),"\n",(0,o.jsx)(n.h3,{id:"custom-ca",children:"Custom CA"}),"\n",(0,o.jsxs)(n.p,{children:["If your cloud API's endpoints don't use TLS certificates that are signed by an official CA, you need to provide your CA to this VM and configure it. (On a SCS Cloud-in-a-Box system, you find it on the manager node in ",(0,o.jsx)(n.code,{children:"/etc/ssl/certs/ca-certificates.crt"}),". You may extract the last cert or just leave them all together.) Copy the CA file to your driver VM and ensure it's readable by the ",(0,o.jsx)(n.code,{children:"debian"})," user."]}),"\n",(0,o.jsxs)(n.p,{children:["Add it to your ",(0,o.jsx)(n.code,{children:"clouds.yaml"})]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"clouds:\n CLOUDNAME:\n cacert: /PATH/TO/CACERT.CRT\n [...]\n"})}),"\n",(0,o.jsxs)(n.p,{children:["If you want to allow ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," to be able to talk to the service endpoints directly to avoid getting a fresh token from keystone for each call, you also need to export it to your environment:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"export OS_CACERT=/PATH/TO/CACERT.CRT\n"})}),"\n",(0,o.jsxs)(n.p,{children:["Consider adding this to your ",(0,o.jsx)(n.code,{children:"~/.bashrc"})," as well."]}),"\n",(0,o.jsxs)(n.h2,{id:"your-first-api_monitorsh-iteration",children:["Your first ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," iteration"]}),"\n",(0,o.jsx)(n.p,{children:"Checkout openstack-health-monitor:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"sudo apt-get install git bc jq netcat-traditional tmux zstd\ngit clone https://github.com/SovereignCloudStack/openstack-health-monitor\ncd openstack-health-monitor\n"})}),"\n",(0,o.jsxs)(n.p,{children:["You may want to start a ",(0,o.jsx)(n.code,{children:"tmux"})," (or ",(0,o.jsx)(n.code,{children:"screen"}),") session now, so you can do multiple things in parallel (e.g. for debugging) and reconnect."]}),"\n",(0,o.jsxs)(n.p,{children:["The script ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," is the main worker of openstack-health-monitor and runs one to many iterations of a cycle where resources are created, tested and torn down. Its operation is described in the ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/README.md",children:"README.md"})," file."]}),"\n",(0,o.jsxs)(n.p,{children:["It is good practice to use ",(0,o.jsx)(n.code,{children:"tmux"}),". This allows you to return (reattach) to console sessions and to open new windows to investigate things. Traditional people may prefer to ",(0,o.jsx)(n.code,{children:"screen"})," over ",(0,o.jsx)(n.code,{children:"tmux"}),"."]}),"\n",(0,o.jsx)(n.p,{children:"You should be ready to run one iteration of the openstack-health-monitor now. Run it like this:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:'export IMG="Debian 12"\nexport JHIMG="Debian 12"\n./api_monitor.sh -O -C -D -n 6 -s -b -B -M -T -LL -i 1\n'})}),"\n",(0,o.jsxs)(n.p,{children:["Leave out the ",(0,o.jsx)(n.code,{children:"-LL"})," if you don't have a working loadbalancer service or replace ",(0,o.jsx)(n.code,{children:"-LL"})," with ",(0,o.jsx)(n.code,{children:"-LO"})," if you want to test the ovn loadbalancer instead of amphorae (saving quite some resources)."]}),"\n",(0,o.jsxs)(n.p,{children:["Feel free to study the meaning of all the command line parameters by looking at the ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/README.md",children:"README.md"}),". (Note: Many of the things enabled by the parameters should be default, but are not for historic reasons. This would change if we rewrite this whole thing in python.)"]}),"\n",(0,o.jsxs)(n.p,{children:["This will run for ~7 minutes, depending on the performance of your OpenStack environment. You should not get any error. (The amber-colored outputs ",(0,o.jsx)(n.code,{children:"DOWN"}),", ",(0,o.jsx)(n.code,{children:"BUILD"}),", ",(0,o.jsx)(n.code,{children:"creating"})," are not errors. Nothing in red should be displayed.) Studying the console output may be instructive to follow the script's progress. You may also open another window (remember the tmux recommendation above) and look at the resources with the usual ",(0,o.jsx)(n.code,{children:"openstack RESOURCE list"})," and ",(0,o.jsx)(n.code,{children:"openstack RESOURCE show NAME"})," and ",(0,o.jsx)(n.code,{children:"RESOURCE"})," being something like ",(0,o.jsx)(n.code,{children:"router"}),", ",(0,o.jsx)(n.code,{children:"network"}),", ",(0,o.jsx)(n.code,{children:"subnet"}),", ",(0,o.jsx)(n.code,{children:"port"}),", ",(0,o.jsx)(n.code,{children:"volume"}),", ",(0,o.jsx)(n.code,{children:"server"}),", ",(0,o.jsx)(n.code,{children:"floating ip"}),", ",(0,o.jsx)(n.code,{children:"loadbalancer"}),", ",(0,o.jsx)(n.code,{children:"loadbalancer pool"}),", ",(0,o.jsx)(n.code,{children:"loadbalancer listener"}),", ",(0,o.jsx)(n.code,{children:"security group"}),", ",(0,o.jsx)(n.code,{children:"keypair"}),", ",(0,o.jsx)(n.code,{children:"image"}),", ...)"]}),"\n",(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," uses and ",(0,o.jsx)(n.code,{children:"APIMonitor_TIMESTAMP"})," prefix for all OpenStack resource names. This allows to identify the created resources and clean them up even if things go wrong.\n",(0,o.jsx)(n.code,{children:"TIMESTAMP"})," is an integer number representing the seconds after 1970-01-01 00:00:00 UTC (Unix time)."]}),"\n",(0,o.jsxs)(n.p,{children:["This may be the time to check that you have sufficient quota to create the resources. While we only create 6+N VMs (and volumes) with the above call (N being the number of AZs), we would want to increase this number for larger clouds. For single-AZ deployments, we would want to still use 2 networks at least ",(0,o.jsx)(n.code,{children:"-N 2"})," to test the ability of the router to route traffic between networks. So expect ",(0,o.jsx)(n.code,{children:"-n 6"})," to become ",(0,o.jsx)(n.code,{children:"-N 2 -n 6"})," for a very small single-AZ cloud or ",(0,o.jsx)(n.code,{children:"-n 12"})," for a large 3 AZ cloud region. So, re-run the ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," with the target sizing."]}),"\n",(0,o.jsx)(n.h3,{id:"resource-impact-and-charging",children:"Resource impact and charging"}),"\n",(0,o.jsxs)(n.p,{children:["Note that ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," uses small flavors (",(0,o.jsx)(n.code,{children:"SCS-1V-2"})," for the N jump hosts and ",(0,o.jsx)(n.code,{children:"SCS-1L-1"})," for the other VMs) to keep the impact on your cloud (and on your invoice if you are not monitoring your own cloud) small. You can change the flavors."]}),"\n",(0,o.jsxs)(n.p,{children:["If you have to pay for this, also consider that some clouds are not charging by the minute but may count by the started hour. So when you run ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," in a loop (which you will) with say 10 VMs (e.g. ",(0,o.jsx)(n.code,{children:"-N 2 -n 8"}),") in each iteration and run this for an hour with 8 iterations, you will never have more than 10 VMs in parallel and they only are alive a bit more than half of the time, but rather than being charged for ~6 VM hours, you end up being charged for ~80 VM hours. Similar for volumes, routers, floating IPs. This makes a huge difference."]}),"\n",(0,o.jsxs)(n.p,{children:["Sometimes the cloud under test has issues. That's why we do monitoring ... One thing that might happen is that loadbalancers and volumes (and other resources, but those two are the most prone to this) end up in a broken state that can not be cleaned up by the user any more. Bad providers may charge for these anyhow, although this will never stand a legal dispute. (IANAL, but charging for providing something that is not working is not typically supported by civil law in most jurisdictions and T&Cs that would say so would not normally be legally enforceable.) If this happens, I recommend to keep records of the broken state (store the output of ",(0,o.jsx)(n.code,{children:"openstack volume list"}),", ",(0,o.jsx)(n.code,{children:"openstack volume show BROKEN_VOLUME"}),", ",(0,o.jsx)(n.code,{children:"openstack loadbalancer list"}),", ",(0,o.jsx)(n.code,{children:"openstack loadbalancer show BROKEN_LB"}),".)"]}),"\n",(0,o.jsxs)(n.p,{children:["Using ",(0,o.jsx)(n.code,{children:"-w -1"})," makes ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," wait for interactive input whenever an error occurs; this can be convenient for debugging."]}),"\n",(0,o.jsx)(n.p,{children:"Once you have single iterations working nicely, we can proceed."}),"\n",(0,o.jsx)(n.h2,{id:"automating-startup-and-cleanup",children:"Automating startup and cleanup"}),"\n",(0,o.jsxs)(n.p,{children:["Typically, we run ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," with a limited amount of iterations (200) and then restart it. For each restart, we also output some statistics, compress the log file and look at any leftovers that did not get cleaned up. The latter happens in the start script that we create here."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'#!/bin/bash\n# run_CLOUDNAME.sh\n# Do some global settings\nexport IMG="Debian 12"\nexport JHIMG="Debian 12"\n#export OS_CACERT=/home/debian/ca-certificates.pem\n# Additional settings to override flavors or to\n# configure email addresses for sending alarms can be set here\n\n# Does openstack CLI work?\nopenstack server list >/dev/null || exit 1\n# Upload log files to this swift container (which you need to create)\n#export SWIFTCONTAINER=OS-HM-Logfiles\n\n# CLEANUP\necho "Finding resources from previous runs to clean up ..."\n# Find Floating IPs\nFIPLIST=""\nFIPS=$(openstack floating ip list -f value -c ID)\nfor fip in $FIPS; do\n FIP=$(openstack floating ip show $fip | grep -o "APIMonitor_[0-9]*")\n if test -n "$FIP"; then FIPLIST="${FIPLIST}${FIP}_\n"; fi\ndone\nFIPLIST=$(echo "$FIPLIST" | grep -v \'^$\' | sort -u)\n# Cleanup previous interrupted runs\nSERVERS=$(openstack server list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nKEYPAIR=$(openstack keypair list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nVOLUMES=$(openstack volume list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nNETWORK=$(openstack network list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nLOADBAL=$(openstack loadbalancer list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nROUTERS=$(openstack router list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nSECGRPS=$(openstack security group list | grep -o "APIMonitor_[0-9]*_" | sort -u)\necho CLEANUP: FIPs $FIPLIST Servers $SERVERS Keypairs $KEYPAIR Volumes $VOLUMES Networks $NETWORK LoadBalancers $LOADBAL Routers $ROUTERS SecGrps $SECGRPS\nfor ENV in $FIPLIST; do\n echo "******************************"\n echo "CLEAN $ENV"\n bash ./api_monitor.sh -o -T -q -c CLEANUP $ENV\n echo "******************************"\ndone\nTOCLEAN=$(echo "$SERVERS\n$KEYPAIR\n$VOLUMES\n$NETWORK\n$LOADBAL\n$ROUTERS\n$SECGRPS\n" | grep -v \'^$\' | sort -u)\nfor ENV in $TOCLEAN; do\n echo "******************************"\n echo "CLEAN $ENV"\n bash ./api_monitor.sh -o -q -LL -c CLEANUP $ENV\n echo "******************************"\ndone\n\n# Now run the monitor\n#exec ./api_monitor.sh -O -C -D -N 2 -n 6 -s -M -LO -b -B -a 2 -t -T -R -S ciab "$@"\nexec ./api_monitor.sh -O -C -D -N 2 -n 6 -s -M -LO -b -B -T "$@"\n'})}),"\n",(0,o.jsxs)(n.p,{children:["Compared to the previous run, we have explicitly set two networks here ",(0,o.jsx)(n.code,{children:"-N 2"})," and rely on the iterations being passed in as command line arguments. Add parameter ",(0,o.jsx)(n.code,{children:"-t"})," if your cloud is slow to increase timeouts. We have enabled the ovtavia loadbalancer (",(0,o.jsx)(n.code,{children:"-LO"}),") in this example rather than the amphora based one (",(0,o.jsx)(n.code,{children:"-LL"}),")."]}),"\n",(0,o.jsxs)(n.p,{children:["You may use one of the existing ",(0,o.jsx)(n.code,{children:"run_XXXX.sh"})," scripts as example. Beware: eMail alerting with ",(0,o.jsx)(n.code,{children:"ALARM_EMAIL_ADDRESS"})," and ",(0,o.jsx)(n.code,{children:"NOTE_EMAIL_ADDRESS"})," (and limiting with ",(0,o.jsx)(n.code,{children:"-a"})," and ",(0,o.jsx)(n.code,{children:"-R"})," ) and reporting data to telegraf (option ",(0,o.jsx)(n.code,{children:"-S"}),") may be present in the samples. Make this script executable (",(0,o.jsx)(n.code,{children:"chmod +x run_CLOUDNAME.sh"}),")."]}),"\n",(0,o.jsxs)(n.p,{children:["We wrap a loop around this in ",(0,o.jsx)(n.code,{children:"run_in_loop.sh"}),":"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'#!/bin/bash\n# run_in_loop.sh\nrm stop-os-hm 2>/dev/null\nwhile true; do\n ./run_CLOUDNAME.sh -i 200\n if test -e stop-os-hm; then break; fi\n echo -n "Hit ^C to abort ..."\n sleep 15; echo\ndone\n'})}),"\n",(0,o.jsxs)(n.p,{children:["Also make this executable (",(0,o.jsx)(n.code,{children:"chmod +x run_in_loop.sh"}),").\nTo run this automatically in a tmux window whenever the system starts, we follow the steps in the ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/startup/README.md",children:"startup README.md"})]}),"\n",(0,o.jsxs)(n.p,{children:["Change ",(0,o.jsx)(n.code,{children:"OS_CLOUD"})," in ",(0,o.jsx)(n.code,{children:"startup/run-apimon-in-tmux.sh"}),". (If you need to set ",(0,o.jsx)(n.code,{children:"OS_CACERT"}),", also add it in this file and pass it into the windows.)"]}),"\n",(0,o.jsx)(n.p,{children:"Activate everything:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"mkdir -p ~/.config/systemd/user/\ncp -p startup/apimon.service ~/.config/systemd/user/\nsystemctl --user enable apimon\nsystemctl --user start apimon\nsudo loginctl enable-linger debian\ntmux attach oshealthmon\n"})}),"\n",(0,o.jsxs)(n.p,{children:["This assumes that you are using the user ",(0,o.jsx)(n.code,{children:"debian"})," for this monitoring and have checked out the repository at ",(0,o.jsx)(n.code,{children:"~/openstack-health-monitor/"}),". Adjust the paths and user name otherwise. (If for whatever reason you have chosen to install things as root, you will have to install the systemd service unit in the system paths and ensure it's not started too early in the boot process.)"]}),"\n",(0,o.jsx)(n.h3,{id:"changing-parameters-and-restarting",children:"Changing parameters and restarting"}),"\n",(0,o.jsxs)(n.p,{children:["If you want to change the parameters passed to ",(0,o.jsx)(n.code,{children:"api_monitor.sh"}),", you best do this by editing ",(0,o.jsx)(n.code,{children:"run_CLOUDNAME.sh"}),", potentially after testing it with one iteration before."]}),"\n",(0,o.jsxs)(n.p,{children:["To make the change effective, you can wait until the current 200 iterations are completed and the ",(0,o.jsx)(n.code,{children:"run_in_loop.sh"})," calls ",(0,o.jsx)(n.code,{children:"run_CLOUDNAME.sh"})," again. You can also hit ",(0,o.jsx)(n.code,{children:"^C"})," in the tmux window that has",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," running. The script will then exit after the current iteration. Note that sending this interrupt is handled by the script, so it does still continue the current iteration and do all the cleanup work. However, you may interrupt an API call and thus cause a spurious error (which may in the worst case lead to a couple more spurious errors). If you want to avoid this, hit ",(0,o.jsx)(n.code,{children:"^C"})," during the wait/sleep phases of the script (after having done all the tests or after having completed the iteration). If you hit ",(0,o.jsx)(n.code,{children:"^C"})," twice, it will abort the the current iteration, but still try to clean up. Then the outer script will also exit and you have to restart by manually calling ",(0,o.jsx)(n.code,{children:"./run_in_loop.sh"})," again."]}),"\n",(0,o.jsxs)(n.p,{children:["You can also issue the ",(0,o.jsx)(n.code,{children:"systemctl --user stop apimon"})," command; it will basically do the same thing: Send ",(0,o.jsx)(n.code,{children:"^C"})," and then wait for everything to be completed and tear down the tmux session.\nAfter waiting for that to complete, you can start it again with ",(0,o.jsx)(n.code,{children:"systemctl --user start apimon"}),"."]}),"\n",(0,o.jsx)(n.h3,{id:"multiple-instances",children:"Multiple instances"}),"\n",(0,o.jsxs)(n.p,{children:["You can run multiple instances of ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," on the same driver VM. In this case, you should rename ",(0,o.jsx)(n.code,{children:"run_in_loop.sh"})," to e.g. ",(0,o.jsx)(n.code,{children:"run_in_loop_CLOUDNAME1.sh"})," and call ",(0,o.jsx)(n.code,{children:"run_CLOUDNAME1.sh"})," from there. Don't forget to adjust ",(0,o.jsx)(n.code,{children:"startup/run-apimon-in-tmux.sh"})," and ",(0,o.jsx)(n.code,{children:"startup/kill-apimon-in-tmux.sh"})," to start more windows."]}),"\n",(0,o.jsxs)(n.p,{children:["It is not recommended to run multiple instances against the same OpenStack project however. While the ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," script carefully keeps track of its own resources and avoids to delete things it has not created, this is not the case for the ",(0,o.jsx)(n.code,{children:"run_CLOUDNAME.sh"})," script, which is explicitly meant to identify anything in the target project that was created by a health monitor and clean it up. If it hits the resources that are currently in use by another health mon instance, this will create spurious errors. This will happen every ~200 iterations, so you could still have some short-term coexistence when you are performing debug operations."]}),"\n",(0,o.jsx)(n.h2,{id:"alarming-and-logs",children:"Alarming and Logs"}),"\n",(0,o.jsx)(n.h3,{id:"email",children:"eMail"}),"\n",(0,o.jsxs)(n.p,{children:["If wanted, the ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," can send statistics and error messages via email, so operator personnel is informed about the state of the monitoring. This email notification service potentially results in many emails; one error may produce several mails. So in case of a systematic problem, expect to receive dozens of mails per hour. This can be reduced a bit using the ",(0,o.jsx)(n.code,{children:"-a N"})," and ",(0,o.jsx)(n.code,{children:"-R"})," options. In order to enable sending emails from the driver VM, it needs to have ",(0,o.jsx)(n.code,{children:"postfix"})," (or another MTA) installed and configured and outgoing connections for eMail need to be allowed. Note that many operators prefer not to use the eMail notifications but rather rely on looking at the dashboards (see further down) regularly."]}),"\n",(0,o.jsxs)(n.p,{children:["Once you have configured ",(0,o.jsx)(n.code,{children:"postfix"}),", you can enable eMail notifications using the option ",(0,o.jsx)(n.code,{children:"-e"}),". Using it twice allows you to differentiate between notes (statistical summaries) and errors. If you want to send mails to more than one recipient, you can do so by passing ",(0,o.jsx)(n.code,{children:"ALARM_EMAIL_ADDRESSES"})," and ",(0,o.jsx)(n.code,{children:"NOTE_EMAIL_ADDRESSES"})," environment variables to ",(0,o.jsx)(n.code,{children:"api_monitor.sh"}),", e.g. by setting it in the ",(0,o.jsx)(n.code,{children:"run_CLOUDNAME.sh"}),"."]}),"\n",(0,o.jsx)(n.h3,{id:"log-files",children:"Log files"}),"\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.code,{children:"api_monitor.sh"})," writes a log file with the name ",(0,o.jsx)(n.code,{children:"APIMonitor_TIMESTAMP.log"}),". It contains a bit of information to see the progress of the script; more importantly, it logs every single openstack CLI call along with parameters and results. (",(0,o.jsx)(n.code,{children:"TIMESTAMP"})," is the Unix time, i.e. seconds since 1970-01-01 00:00:00 UTC.)"]}),"\n",(0,o.jsxs)(n.p,{children:["Note that ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," does take some care not to expose secrets -- since v1.99, it does also redact issued tokens (which would otherwise give you up to 24hrs of access). But the Log files still may contain moderately sensitive information, so we suggest to not share it with untrusted parties."]}),"\n",(0,o.jsxs)(n.p,{children:["The log file is written to the file system. After finishing the 200 iterations, the log file is compressed. If the environment variable ",(0,o.jsx)(n.code,{children:"SWIFTCONTAINER"})," has been set (in ",(0,o.jsx)(n.code,{children:"run_COULDNAME.sh"}),") when starting ",(0,o.jsx)(n.code,{children:"api_monitor.sh"}),". the log file will be uploaded to a container with that name if it exists and if the swift object storage service is supported by the cloud. So create the container (a bucket in S3 speak) before if you want to use this: ",(0,o.jsx)(n.code,{children:"export SWIFTCONTAINER=OSHM_Logs; openstack container create $SWIFTCONTAINER"})]}),"\n",(0,o.jsxs)(n.p,{children:["After the 200 iterations, a ",(0,o.jsx)(n.code,{children:".psv"})," file (pipe-separated values) is created ",(0,o.jsx)(n.code,{children:"Stats.STARTTIME-ENDTIME.psv"})," (with times as calendar dates) which contains a bit of statistics on the last 200 iterations. This one will also be uploaded to $SWIFTCONTAINER (if configured)."]}),"\n",(0,o.jsx)(n.h2,{id:"data-collection-and-dashboard",children:"Data collection and dashboard"}),"\n",(0,o.jsxs)(n.p,{children:["See ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/dashboard/README.md",children:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/dashboard/README.md"})]}),"\n",(0,o.jsx)(n.h3,{id:"telegraf",children:"telegraf"}),"\n",(0,o.jsx)(n.p,{children:"To install telegraf on Debian 12, we need to add the apt repository provided by InfluxData:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:'sudo curl -fsSL https://repos.influxdata.com/influxdata-archive_compat.key -o /etc/apt/keyrings/influxdata-archive_compat.key\necho "deb [signed-by=/etc/apt/keyrings/influxdata-archive_compat.key] https://repos.influxdata.com/debian stable main" | sudo tee /etc/apt/sources.list.d/influxdata.list\nsudo apt update\nsudo apt -y install telegraf\n'})}),"\n",(0,o.jsxs)(n.p,{children:["In the config file ",(0,o.jsx)(n.code,{children:"/etc/telegraf/telegraf.conf"}),", we enable"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'[[inputs.influxdb_listener]]\n service_address = ":8186"\n\n[[outputs.influxdb]]\n urls = ["http://127.0.0.1:8086"]\n'})}),"\n",(0,o.jsxs)(n.p,{children:["and restart the service (",(0,o.jsx)(n.code,{children:"sudo systemctl restart telegraf"}),").\nEnable it on system startup: ",(0,o.jsx)(n.code,{children:"sudo systemctl enable telegraf"}),"."]}),"\n",(0,o.jsx)(n.h3,{id:"influxdb",children:"influxdb"}),"\n",(0,o.jsx)(n.p,{children:"We proceed to influxdb:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"sudo apt-get install influxdb\n"})}),"\n",(0,o.jsxs)(n.p,{children:["In the configuration file ",(0,o.jsx)(n.code,{children:"/etc/influxdb/influxdb.conf"}),", ensure that the http interface on port 8086 is enabled."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'[http]\n enabled = true\n bind-address = ":8086"\n'})}),"\n",(0,o.jsxs)(n.p,{children:["Restart influxdb as needed with ",(0,o.jsx)(n.code,{children:"sudo systemctl restart influxdb"}),".\nAlso enable it on system startup: ",(0,o.jsx)(n.code,{children:"sudo systemctl enable influxdb"}),"."]}),"\n",(0,o.jsxs)(n.h3,{id:"add--s-cloudname-to-your-run_cloudnamesh-script",children:["Add ",(0,o.jsx)(n.code,{children:"-S CLOUDNAME"})," to your ",(0,o.jsx)(n.code,{children:"run_CLOUDNAME.sh"})," script"]}),"\n",(0,o.jsxs)(n.p,{children:["You need to tell the monitor that it should send data via telegraf to influxdb by adding the parameter ",(0,o.jsx)(n.code,{children:"-S CLOUDNAME"})," to the ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," call in ",(0,o.jsx)(n.code,{children:"run_CLOUDNAME.sh"}),". Restart it (see above) to make the change effective immediately (and not only after 200 iterations complete)."]}),"\n",(0,o.jsx)(n.h3,{id:"grafana",children:"grafana"}),"\n",(0,o.jsx)(n.h4,{id:"basic-config",children:"Basic config"}),"\n",(0,o.jsxs)(n.p,{children:["Finally grafana: We (still as root) follow ",(0,o.jsx)(n.a,{href:"https://www.server-world.info/en/note?os=Debian_12&p=grafana",children:"https://www.server-world.info/en/note?os=Debian_12&p=grafana"})]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'sudo wget -q -O /usr/share/keyrings/grafana.key https://packages.grafana.com/gpg.key\necho "deb [signed-by=/usr/share/keyrings/grafana.key] https://packages.grafana.com/oss/deb stable main" | sudo tee -a /etc/apt/sources.list.d/grafana.list\nsudo apt update\nsudo apt -y install grafana\n'})}),"\n",(0,o.jsxs)(n.p,{children:["The config file ",(0,o.jsx)(n.code,{children:"/etc/grafana/grafana.ini"})," needs some adjustments:"]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["Set the hostname in ",(0,o.jsx)(n.code,{children:"[server]"})," section: ",(0,o.jsx)(n.code,{children:"domain = health.YOURCLOUD.sovereignit.cloud"}),". Set the ",(0,o.jsx)(n.code,{children:"protocol = https"})," if not enabled by default.\nYou can use a hostname of your liking, but we will need to create TLS certificates for this host. So we should have control over DNS TXT records for this domain if we want to use Let's Encrypt with DNSAUTH. The ",(0,o.jsx)(n.code,{children:"sovereignit.cloud"})," domain is controlled by the SCS project team and has been used for a number of health mon instances.\nIn this same section, set ",(0,o.jsx)(n.code,{children:"cert_file = /etc/grafana/health-fullchain.pem"})," and ",(0,o.jsx)(n.code,{children:"cert_key = /etc/grafana/health-key.pem"}),". Ensure that both files are readable by ",(0,o.jsx)(n.code,{children:"root:grafana"})," and that the key file is ",(0,o.jsx)(n.em,{children:"not"})," world-readable."]}),"\n",(0,o.jsxs)(n.li,{children:["Configure the admin access. In section ",(0,o.jsx)(n.code,{children:"[security]"}),", set the ",(0,o.jsx)(n.code,{children:"admin_user = admin"})," and ",(0,o.jsx)(n.code,{children:"admin_password = SOME_SECRET_PASS"})," which you keep private."]}),"\n",(0,o.jsxs)(n.li,{children:["Allow local data sources (same section): ",(0,o.jsx)(n.code,{children:"data_source_proxy_whitelist = localhost:8088 localhost:8086"})]}),"\n",(0,o.jsxs)(n.li,{children:["Let's disallow user signup (in section ",(0,o.jsx)(n.code,{children:"[users]"}),"): ",(0,o.jsx)(n.code,{children:"allow_sign_up = false"})," and ",(0,o.jsx)(n.code,{children:"allow_org_create = false"}),"."]}),"\n",(0,o.jsxs)(n.li,{children:["We do the OIDC connection with ",(0,o.jsx)(n.code,{children:"[auth.github]"})," later."]}),"\n"]}),"\n",(0,o.jsxs)(n.p,{children:["We can now restart the service: ",(0,o.jsx)(n.code,{children:"sudo systemctl restart grafana-server"}),".\nBeing at it, also enable it on system startup: ",(0,o.jsx)(n.code,{children:"sudo systemctl enable grafana-server"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["You should now be able to access your dashboard on ",(0,o.jsx)(n.code,{children:"https://health.YOURCLOUD.sovereignit.de:3000"})," and log in via the configured username ",(0,o.jsx)(n.code,{children:"admin"})," and your ",(0,o.jsx)(n.code,{children:"SOME_SECRET_PASS"})," password."]}),"\n",(0,o.jsx)(n.h4,{id:"enable-influx-database-in-grafana",children:"Enable influx database in grafana"}),"\n",(0,o.jsxs)(n.p,{children:["In the dashboard, go to Home, Connections, choose InfluxDB and Add new datasource. The defaults (database name, InfluxQL query language) work. You need to explicitly set the URL to ",(0,o.jsx)(n.code,{children:"http://localhost:8086"})," (despite this being the suggestion). Set the database name to ",(0,o.jsx)(n.code,{children:"telegraf"}),". Save&test should succeed."]}),"\n",(0,o.jsx)(n.h4,{id:"importing-the-dashboard",children:"Importing the dashboard"}),"\n",(0,o.jsxs)(n.p,{children:["Go to Home, Dashboards, New, Import.\nUpload the dashboard ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/dashboard/openstack-health-dashboard.json",children:".json file"})," from the repository, user the ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/dashboard/openstack-health-dashboard-10.json",children:"Grafana-10 variant"})," if you use Grafana 10 or newer."]}),"\n",(0,o.jsx)(n.p,{children:"In the dashboard, go to the settings gear wheel, variables, mycloud and add CLOUDNAME to the list of clouds that can be displayed. (There are some existing SCS clouds in that list.)\nSave."}),"\n",(0,o.jsx)(n.p,{children:"Now choose CLOUDNAME as cloud (top of the dashboard, rightmost dropdown for the mycloud filter variable)."}),"\n",(0,o.jsx)(n.h4,{id:"no-data-displayed",children:"No data displayed?"}),"\n",(0,o.jsx)(n.p,{children:'Sometimes, you may see a panel displaying "no data" despite the fact that the first full iteration of data has been sent to influx already. This may be a strange interaction between the browser and Grafana -- we have not analyzed whether that is a bug in Grafana.'}),"\n",(0,o.jsx)(n.p,{children:"One way to work around is to go into the setting of the panel (the three dots in the upper right corner), go to edit and start changing one aspect of the query. Apply. Change it back to the original. Apply. The data will appear. Save to be sure it's conserved."}),"\n",(0,o.jsx)(n.h4,{id:"dashboard-features",children:"Dashboard features"}),"\n",(0,o.jsx)(n.p,{children:"Look at the top line filters: You can filter to only see certain API calls or certain resources; the graphs are very crowded and filtering to better see what you want to focus on is very well intended."}),"\n",(0,o.jsx)(n.p,{children:"The first row of panels give a health impression; there are absolute numbers as well as percentage numbers and the panels turn amber and red in case you have too many errors. Note that the colors on the panels with absolute numbers can not take into account whether you look at just a few hours or at weeks. Accordingly, consider the colors a reasonable hint if things are green or not when looking at a ~24 hours interval. This limitation does not affect the colors on the percentage graph, obviously."}),"\n",(0,o.jsx)(n.p,{children:"You can change the time interval and zoom in also by marking an interval with the mouse. Zooming out to a few months can be a very useful feature to see trends and watch e.g. your API performance, your resource creation times or the benchmarks change over the long term."}),"\n",(0,o.jsx)(n.h4,{id:"github-oidc-integration",children:"github OIDC integration"}),"\n",(0,o.jsxs)(n.p,{children:["The SCS providers do allow all github users that belong to the SovereignCloudStack organization to get Viewer access to the dashboards by adding a ",(0,o.jsx)(n.code,{children:"client_id"})," and ",(0,o.jsx)(n.code,{children:"client_secret"})," in the ",(0,o.jsx)(n.code,{children:"[github.auth]"})," section that you request from the SCS github admins (github's oauth auth). This allows to exchange experience and to get a feeling for the achievable stability. (Hint: A single digit number of API call fails per week and no other failures is achievable on loaded clouds.)"]}),"\n",(0,o.jsx)(n.h2,{id:"alternative-approach-to-install-and-configure-the-dashboard-behind-a-reverse-proxy",children:"Alternative approach to install and configure the dashboard behind a reverse proxy"}),"\n",(0,o.jsxs)(n.p,{children:["Install influxdb via apt: ",(0,o.jsx)(n.a,{href:"https://docs.influxdata.com/influxdb/v1/introduction/install/#installing-influxdb-oss",children:"https://docs.influxdata.com/influxdb/v1/introduction/install/#installing-influxdb-oss"}),"\nInstall telegraf (same apt repo as influxdb): ",(0,o.jsx)(n.code,{children:"sudo apt update && sudo apt install telegraf"}),"\nInstall grafana: ",(0,o.jsx)(n.a,{href:"https://grafana.com/docs/grafana/latest/setup-grafana/installation/debian/#install-from-apt-repository",children:"https://grafana.com/docs/grafana/latest/setup-grafana/installation/debian/#install-from-apt-repository"})]}),"\n",(0,o.jsx)(n.p,{children:"Prepare configuration by using the config files from the repository as an alternative to doing the changes manually (as described above):"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"sudo cp dashboard/telegraf.conf /etc/telegraf && sudo chown root:root /etc/telegraf/telegraf.conf && sudo chmod 0644 /etc/telegraf/telegraf.conf\nsudo cp dashboard/config.toml /etc/influxdb && sudo chown root:influxdb /etc/influxdb/config.toml && sudo chmod 0640 /etc/influxdb/config.toml\nsudo cp dashboard/grafana.ini /etc/grafana && sudo chown root:grafana /etc/grafana/grafana.ini && sudo chmod 0640 /etc/grafana/grafana.ini\n"})}),"\n",(0,o.jsx)(n.p,{children:"These config files should work as long as the versions of telegraf, influxdb and grafana don't evolve too far from the ones used in the repository. (Otherwise refer to above instructions how to tweak the default config files.)"}),"\n",(0,o.jsxs)(n.p,{children:["Changes to ",(0,o.jsx)(n.code,{children:"/etc/grafana/grafana.ini"})," as we do tls termination at the reverse proxy:"]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["set ",(0,o.jsx)(n.code,{children:"protocol = http"})]}),"\n",(0,o.jsxs)(n.li,{children:["comment out ",(0,o.jsx)(n.code,{children:"domain"})," option (? FIXME) or set it to the hostname"]}),"\n",(0,o.jsxs)(n.li,{children:["comment out ",(0,o.jsx)(n.code,{children:"cert_*"})," options"]}),"\n"]}),"\n",(0,o.jsxs)(n.p,{children:["Also change the admin password in ",(0,o.jsx)(n.code,{children:"grafana.ini"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["Changes to ",(0,o.jsx)(n.code,{children:"/etc/grafana/grafana.ini"})," if github auth should not be used yet:"]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["comment out whole ",(0,o.jsx)(n.code,{children:"[auth.github]"})," section for now (can be enabled later)"]}),"\n"]}),"\n",(0,o.jsxs)(n.p,{children:["Restart services: ",(0,o.jsx)(n.code,{children:"sudo systemctl restart telegraf && sudo systemctl restart influxdb && sudo systemctl restart grafana-server"})]}),"\n",(0,o.jsx)(n.p,{children:"Configuration in grafana web gui:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["Login to grafana ",(0,o.jsx)(n.code,{children:"http(s)://:3000"})," with user admin and default password from ",(0,o.jsx)(n.code,{children:"/etc/grafana/grafana.ini"})," and change password."]}),"\n",(0,o.jsxs)(n.li,{children:["Create influxdb datasource with url ",(0,o.jsx)(n.code,{children:"http://localhost:8086"})," and database name ",(0,o.jsx)(n.code,{children:"telegraf"}),"."]}),"\n",(0,o.jsxs)(n.li,{children:["Finally import dashboard ",(0,o.jsx)(n.code,{children:"dashboard/openstack-health-dashboard.json"})," to grafana."]}),"\n"]}),"\n",(0,o.jsx)(n.p,{children:"TODO:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"Reverse proxy (aka ingress) with Let's Encrypt cert"}),"\n",(0,o.jsx)(n.li,{children:"Github auth as described above"}),"\n"]}),"\n",(0,o.jsx)(n.h2,{id:"maintenance",children:"Maintenance"}),"\n",(0,o.jsx)(n.p,{children:"The driver VM is a snowflake: A manually set up system (unless you automate all the above steps, which is possible of course) that holds data and is long-lived. As such it's important to be maintained."}),"\n",(0,o.jsx)(n.h3,{id:"unattended-upgrades",children:"Unattended upgrades"}),"\n",(0,o.jsxs)(n.p,{children:["It is recommended to ensure maintenance updates are deployed automatically. These are unlikely to negatively impact the openstack-health-monitor. See ",(0,o.jsx)(n.a,{href:"https://wiki.debian.org/UnattendedUpgrades",children:"https://wiki.debian.org/UnattendedUpgrades"}),". If you decide against unattended upgrades, it is recommended to install updates manually regularly and especially watch out for issues that affect the services that are exposed to the world: sshd (port 22) and grafana (port 3000)."]}),"\n",(0,o.jsx)(n.h3,{id:"updating-openstack-health-monitor",children:"Updating openstack-health-monitor"}),"\n",(0,o.jsxs)(n.p,{children:["You can just do a ",(0,o.jsx)(n.code,{children:"git update"})," in the ",(0,o.jsx)(n.code,{children:"openstack-health-monitor"})," directory to get the latest improvements. Note that these will only become effective after the 200 iterations have completed. You can speed this up by injecting a ",(0,o.jsx)(n.code,{children:"^C"}),", see above in the restart section."]}),"\n",(0,o.jsx)(n.h3,{id:"backup",children:"Backup"}),"\n",(0,o.jsxs)(n.p,{children:["The system holds two things that you might consider valuable for long-term storage:\n(1) The log files. These are compressed and uploaded to object storage if you enable the ",(0,o.jsx)(n.code,{children:"SWIFTCONTAINER"})," setting, which probably means that these do not need any additional backing up then.\n(2) The influx time series data. Back up the data in ",(0,o.jsx)(n.code,{children:"/var/lib/influxdb"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["Obviously, if you want to recover quickly from a crash, you might consider to also back up telegraf, influx and grafana config files as well as the edited startup scripts, ",(0,o.jsx)(n.code,{children:"clouds.yaml"}),", etc. Be careful not to expose sensitive data by granting too generous access to your backed up files."]}),"\n",(0,o.jsx)(n.h2,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,o.jsx)(n.h3,{id:"debugging-issues",children:"Debugging issues"}),"\n",(0,o.jsx)(n.p,{children:"In case there is trouble with your cloud, the normal course of action to analyze is as follows:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"Look at the dashboard (see above)"}),"\n",(0,o.jsxs)(n.li,{children:["Connect to the driver VM and attach to the tmux session and look at the console output of ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})]}),"\n",(0,o.jsx)(n.li,{children:"Analyze the logfile (locally on the driver VM or grab it from the object storage)"}),"\n"]}),"\n",(0,o.jsx)(n.h3,{id:"analyzing-failures",children:"Analyzing failures"}),"\n",(0,o.jsxs)(n.p,{children:["When VM instances are created successfully, but then end up in ",(0,o.jsx)(n.code,{children:"ERROR"})," state, the ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," does an explicit ",(0,o.jsx)(n.code,{children:"openstack server show"}),", so you will find some details in the tmux session, in the alarm emails (if you use those) and in the log files."]}),"\n",(0,o.jsxs)(n.p,{children:["Sometimes the VMs end up being ",(0,o.jsx)(n.code,{children:"ACTIVE"})," as wanted but then they can't be accessed via ssh. More often than not, this is a problem with meta-data service on a compute host. Without metadata, not ssh key is injected and login will fail."]}),"\n",(0,o.jsxs)(n.p,{children:["To gather more details, you can look at the console output ",(0,o.jsx)(n.code,{children:"openstack console log show VM"})," (where ",(0,o.jsx)(n.code,{children:"VM"})," is the name of the uuid of the affected VM instance). The cloud-init output is often enough to see what has gone wrong. You can log in to the VMs: The jumphosts are directly accessible via ",(0,o.jsx)(n.code,{children:"ssh -i APIMonitor_XXXXX_JH.pem debian@FIP"}),", whereas the JumpHost does port forwarding to the other VMs that don't have their own floating IP address: ",(0,o.jsx)(n.code,{children:"ssh -i APIMonitor_XXXXX_VM.pem -p 222 debian@FIP"}),". Replace ",(0,o.jsx)(n.code,{children:"XXXXX"})," with the number in your current APIMonitor prefix, ",(0,o.jsx)(n.code,{children:"FIP"})," with the floating IP address of the responsible JumpHost and ",(0,o.jsx)(n.code,{children:"debian"})," with the user name used by the images you boot. Use ",(0,o.jsx)(n.code,{children:"223"})," to connect to the second VM in the network, ",(0,o.jsx)(n.code,{children:"224"})," the third etc."]}),"\n",(0,o.jsxs)(n.p,{children:["When logged in, look at ",(0,o.jsx)(n.code,{children:"/var/log/cloud-init-output.log"})," and ",(0,o.jsx)(n.code,{children:"/var/log/cloud-init.log"}),". You can find the metadata in ",(0,o.jsx)(n.code,{children:"/var/lib/cloud/instance/"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["You will not have much time to look around -- the still running ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," script does continue and clean things up again. So you might want to suspend it with ",(0,o.jsx)(n.code,{children:"^Z"})," (and continue it later with ",(0,o.jsx)(n.code,{children:"fg"}),"). Another option is to not stop the regular monitoring, but start a second instance manually; see above notes for running multiple instances though. If you start a second instance manually against the same project, do NOT use the ",(0,o.jsx)(n.code,{children:"run_CLOUDNAME.sh"})," script as it would do cleanup against the running instance, but rather copy the ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," command line from the bottom (without the ",(0,o.jsx)(n.code,{children:"exec"}),"), reduce the iterations to a few (unless you need a lot to trigger the issue again) and attach ",(0,o.jsx)(n.code,{children:"-w -1"})," to make the script stop its operation (and wait for Enter) once it hits an error. Of course, you still will face cleanup when the continuing main script hits its 200th iteration and you have chosen to run this second instance against the same project in the same cloud. After analyzing, do not forget to go back to the tmux window where the stopped script is running and do hit Enter, so it can continue and do its cleanup work."]}),"\n",(0,o.jsx)(n.h3,{id:"cleaning-things-up",children:"Cleaning things up"}),"\n",(0,o.jsx)(n.p,{children:"If you are unlucky, the script fails to clean something up. A volume may not have been named (because of a cinder failure) or all the logic may have gone wrong, e.g. the heuristic to avoid leaking floating IPs. You can try to clean this up using the normal openstack commands (or horizon dashboard)."}),"\n",(0,o.jsx)(n.p,{children:"There are a few things that may need support from a cloud admin:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["Volumes may end up permanently in a ",(0,o.jsx)(n.code,{children:"deleting"})," or ",(0,o.jsx)(n.code,{children:"reserved"})," state or may be ",(0,o.jsx)(n.code,{children:"in-use"}),", attached to a VM that has long gone. The admin needs to set the state to ",(0,o.jsx)(n.code,{children:"error"})," and then delete them."]}),"\n",(0,o.jsxs)(n.li,{children:["Loadbalancers may end up in a ",(0,o.jsx)(n.code,{children:"PENDING_XXX"})," state (",(0,o.jsx)(n.code,{children:"XXX"})," being ",(0,o.jsx)(n.code,{children:"CREATE"}),", ",(0,o.jsx)(n.code,{children:"UPDATE"})," or ",(0,o.jsx)(n.code,{children:"DELETE"}),") without ever changing. This also needs the cloud admin to set the status to ",(0,o.jsx)(n.code,{children:"ERROR"}),", so it can be cleaned up. amphorae are more prone to this than ovn LBs."]}),"\n"]}),"\n",(0,o.jsx)(n.p,{children:"More like these may happen, but those two are the only ones that have been observed to happen occasionally. Some services seem to be less robust than others against an event in the event queue (rabbitmq) being lost or an connection to be interrupted."}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsxs)(n.em,{children:["The source of this document can be found in the ",(0,o.jsx)(n.a,{href:"https://raw.githubusercontent.com/SovereignCloudStack/openstack-health-monitor/main/docs/Debian12-Install.md",children:"SovereignCloudStack/openstack-health-monitor"})," repository."]})}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsx)(n.em,{children:"Author: SCS Community, License: CC by Attribution 4.0 International"})})]})}function h(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(c,{...e})}):c(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>r,a:()=>a});var o=t(7294);const s={},i=o.createContext(s);function a(e){const n=o.useContext(i);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),o.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/dbb7d2f3.85855b7a.js b/assets/js/dbb7d2f3.85855b7a.js deleted file mode 100644 index 989d6e8842..0000000000 --- a/assets/js/dbb7d2f3.85855b7a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkosism=self.webpackChunkosism||[]).push([[5378],{9488:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>d,contentTitle:()=>l,default:()=>u,frontMatter:()=>o,metadata:()=>c,toc:()=>h});var s=r(5893),t=r(1151),i=r(4866),a=r(5162);const o={sidebar_label:"Ceph",sidebar_position:50},l="Ceph",c={id:"guides/deploy-guide/services/ceph",title:"Ceph",description:"In OSISM it is also possible to integrate and use existing Ceph clusters. It",source:"@site/docs/guides/deploy-guide/services/ceph.mdx",sourceDirName:"guides/deploy-guide/services",slug:"/guides/deploy-guide/services/ceph",permalink:"/docs/guides/deploy-guide/services/ceph",draft:!1,unlisted:!1,editUrl:"https://github.com/osism/osism.github.io/tree/main/docs/guides/deploy-guide/services/ceph.mdx",tags:[],version:"current",sidebarPosition:50,frontMatter:{sidebar_label:"Ceph",sidebar_position:50},sidebar:"tutorialSidebar",previous:{title:"Logging & Monitoring",permalink:"/docs/guides/deploy-guide/services/logging-monitoring"},next:{title:"OpenStack",permalink:"/docs/guides/deploy-guide/services/openstack"}},d={},h=[{value:"RGW service",id:"rgw-service",level:2},{value:"Avoiding service restarts",id:"avoiding-service-restarts",level:2},{value:"Throttling service restarts",id:"throttling-service-restarts",level:2}];function p(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,t.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"ceph",children:"Ceph"}),"\n",(0,s.jsxs)(n.p,{children:["In OSISM it is also possible to integrate and use existing Ceph clusters. It\nis not necessary to deploy Ceph with OSISM. If Ceph is deployed with OSISM, it\nshould be noted that OSISM does not claim to provide all possible features of Ceph.\nCeph provided with OSISM is intended to provide the storage for Glance, Nova, Cinder\nand Manila. In a specific way that has been implemented by OSISM for years. It\nshould be checked in advance whether the way in OSISM the Ceph deployment and the\nprovided features are sufficient. If this is not the case, it is recommended to\ndeploy Ceph in a different way directly and independently of OSISM. For possible\nopen source projects, please refer to\n",(0,s.jsx)(n.a,{href:"https://docs.ceph.com/en/latest/cephadm/index.html",children:"cephadm"})," and\n",(0,s.jsx)(n.a,{href:"https://rook.io",children:"Rook"}),"."]}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsxs)(n.p,{children:["Before starting the Ceph deployment, the configuration and preparation of the\nOSD devices must be completed. The steps that are required for this can be found in the\n",(0,s.jsx)(n.a,{href:"/docs/guides/configuration-guide/ceph#osd-devices",children:"Ceph Configuration Guide"}),"."]})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Deploy services."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Deploy ",(0,s.jsx)(n.a,{href:"https://docs.ceph.com/en/quincy/man/8/ceph-mon/",children:"ceph-mon"})," services"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply ceph-mons\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Deploy ceph-mgr services"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply ceph-mgrs\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Deploy ",(0,s.jsx)(n.a,{href:"https://docs.ceph.com/en/quincy/man/8/ceph-osd/",children:"ceph-osd"})," services"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply ceph-osds\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Generate pools and keys. This step is only necessary for OSISM >= 7.0.0."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply ceph-pools\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Deploy ceph-crash services"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply ceph-crash\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.admonition,{type:"info",children:[(0,s.jsx)(n.p,{children:"It's all done step by step here. It is also possible to do this in a single step.\nThis speeds up the entire process and avoids unnecessary restarts of individual\nservices."}),(0,s.jsxs)(i.Z,{children:[(0,s.jsxs)(a.Z,{value:"osism-7",label:"OSISM >= 7.0.0",children:[(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply ceph\n"})}),(0,s.jsx)(n.p,{children:"Generate pools and keys."}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply ceph-pools\n"})})]}),(0,s.jsx)(a.Z,{value:"osism-6",label:"OSISM < 7.0.0",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply ceph-base\n"})})})]})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Get ceph keys. This places the necessary keys in ",(0,s.jsx)(n.code,{children:"/opt/configuration"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply copy-ceph-keys\n"})}),"\n",(0,s.jsx)(n.p,{children:"After run, these keys must be permanently added to the configuration repository\nvia Git."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"environments/infrastructure/files/ceph/ceph.client.admin.keyring\nenvironments/kolla/files/overlays/gnocchi/ceph.client.gnocchi.keyring\nenvironments/kolla/files/overlays/nova/ceph.client.cinder.keyring\nenvironments/kolla/files/overlays/nova/ceph.client.nova.keyring\nenvironments/kolla/files/overlays/cinder/cinder-backup/ceph.client.cinder.keyring\nenvironments/kolla/files/overlays/cinder/cinder-backup/ceph.client.cinder-backup.keyring\nenvironments/kolla/files/overlays/cinder/cinder-volume/ceph.client.cinder.keyring\nenvironments/kolla/files/overlays/manila/ceph.client.manila.keyring\nenvironments/kolla/files/overlays/glance/ceph.client.glance.keyring\n"})}),"\n",(0,s.jsxs)(n.p,{children:["If the ",(0,s.jsx)(n.code,{children:"osism apply copy-ceph-keys"})," fails because the keys are not found in the ",(0,s.jsx)(n.code,{children:"/share"}),"\ndirectory, this can be ignored. The keys of the predefined keys (e.g. for Manila) were\nthen not created as they are not used. If you only use Ceph and do not need the predefined\nkeys for OpenStack at all, you can also overwrite the ",(0,s.jsx)(n.code,{children:"ceph_kolla_keys"})," parameter to skip\nthese keys."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/ceph/configuration.yml"',children:"ceph_kolla_keys: []\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"After the Ceph keys have been persisted in the configuration repository, the Ceph\nclient can be deployed."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply cephclient\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Enable and prepare the use of the Ceph dashboard."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply ceph-bootstrap-dashboard\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"rgw-service",children:"RGW service"}),"\n",(0,s.jsx)(n.p,{children:"Deployment of the Ceph RGW Service is optional. How the Ceph RGW service can be deployed\nand integrated into OpenStack is described here."}),"\n",(0,s.jsxs)(n.admonition,{type:"info",children:[(0,s.jsxs)(n.p,{children:["If an initial deployment is performed and Ceph RGW is not added to an existing deployment,\nsteps 4 and 5 are ",(0,s.jsx)(n.strong,{children:"not"})," required."]}),(0,s.jsxs)(n.p,{children:["Step 3 is then performed ",(0,s.jsx)(n.strong,{children:"later after"})," the OpenStack Keystone service has been deployed."]})]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/docs/guides/configuration-guide/ceph#rgw-service",children:"Configure the RGW service"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Apply role ",(0,s.jsx)(n.code,{children:"ceph-rgws"})," to deploy the Ceph RGW services."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply ceph-rgws\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Apply role ",(0,s.jsx)(n.code,{children:"kolla-ceph-rgw"})," to add the OpenStack endpoint.\nIf an initial deployment is performed and Ceph RGW is not added\nto an existing deployment run this step later after the OpenStack\nKeystone service has been deployed."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply kolla-ceph-rgw\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Apply role ",(0,s.jsx)(n.code,{children:"loadbalancer"})," to add the HAProxy backend and frontend."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply loadbalancer\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Apply role ",(0,s.jsx)(n.code,{children:"horizon"})," to enable the Swift dashboard."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply horizon\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"avoiding-service-restarts",children:"Avoiding service restarts"}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsx)(n.p,{children:"Usable from OSISM 7.0.3 onwards."})}),"\n",(0,s.jsx)(n.p,{children:"If Ceph services are deployed sequentially, this can lead to unwanted service restarts.\nThis can also happen if, for example, new OSDs are added later or a new control node is\nadded."}),"\n",(0,s.jsx)(n.p,{children:"The Ceph RGW services are deployed here without restarting the Ceph OSD services."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply ceph-rgws -e ceph_handler_osds_restart=False\n"})}),"\n",(0,s.jsx)(n.p,{children:"The following parameters are available. Any number of parameters can be used with a single command."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"ceph_handler_crash_restart\nceph_handler_mdss_restart\nceph_handler_mgrs_restart\nceph_handler_mons_restart\nceph_handler_osds_restart\nceph_handler_rbdmirrors_restart\nceph_handler_rgws_restart\n"})}),"\n",(0,s.jsx)(n.h2,{id:"throttling-service-restarts",children:"Throttling service restarts"}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsx)(n.p,{children:"Usable from OSISM 7.0.3 onwards."})}),"\n",(0,s.jsx)(n.p,{children:"Sometimes service restarts are required. For example, if the configuration has changed\nor if new OSDs have been added. It may be necessary and useful to only restart the\nservices on a specific number of nodes at a specific time."}),"\n",(0,s.jsxs)(n.p,{children:["Further information on throttling can be found in the\n",(0,s.jsx)(n.a,{href:"https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_strategies.html#restricting-execution-with-throttle",children:"Ansible documentation"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"The Ceph OSD services are deployed here. If there is a restart required of other OSDs\nthat are already running, these restarts are executed on a maximum of 2 nodes at the\nsame time. The OSD services themselves on a node are always restarted one after the other\nand never all at the same time."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply ceph-osds -e ceph_handler_osds_restart_throttle=2\n"})}),"\n",(0,s.jsxs)(n.p,{children:["If the nodes are to be processed one after the other, ",(0,s.jsx)(n.code,{children:"ceph_handler_osds_restart_throttle=1"}),"\ncan be used."]}),"\n",(0,s.jsx)(n.p,{children:"The following parameters are available. Any number of parameters can be used with a single command."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"ceph_handler_crash_restart_throttle\nceph_handler_mdss_restart_throttle\nceph_handler_mgrs_restart_throttle\nceph_handler_mons_restart_throttle\nceph_handler_osds_restart_throttle\nceph_handler_rbdmirrors_restart_throttle\nceph_handler_rgws_restart_throttle\n"})})]})}function u(e={}){const{wrapper:n}={...(0,t.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(p,{...e})}):p(e)}},5162:(e,n,r)=>{r.d(n,{Z:()=>a});r(7294);var s=r(6905);const t={tabItem:"tabItem_Ymn6"};var i=r(5893);function a(e){let{children:n,hidden:r,className:a}=e;return(0,i.jsx)("div",{role:"tabpanel",className:(0,s.Z)(t.tabItem,a),hidden:r,children:n})}},4866:(e,n,r)=>{r.d(n,{Z:()=>_});var s=r(7294),t=r(6905),i=r(2466),a=r(6550),o=r(469),l=r(1980),c=r(7392),d=r(812);function h(e){return s.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,s.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function p(e){const{values:n,children:r}=e;return(0,s.useMemo)((()=>{const e=n??function(e){return h(e).map((e=>{let{props:{value:n,label:r,attributes:s,default:t}}=e;return{value:n,label:r,attributes:s,default:t}}))}(r);return function(e){const n=(0,c.l)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[n,r])}function u(e){let{value:n,tabValues:r}=e;return r.some((e=>e.value===n))}function m(e){let{queryString:n=!1,groupId:r}=e;const t=(0,a.k6)(),i=function(e){let{queryString:n=!1,groupId:r}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!r)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return r??null}({queryString:n,groupId:r});return[(0,l._X)(i),(0,s.useCallback)((e=>{if(!i)return;const n=new URLSearchParams(t.location.search);n.set(i,e),t.replace({...t.location,search:n.toString()})}),[i,t])]}function f(e){const{defaultValue:n,queryString:r=!1,groupId:t}=e,i=p(e),[a,l]=(0,s.useState)((()=>function(e){let{defaultValue:n,tabValues:r}=e;if(0===r.length)throw new Error("Docusaurus error: the component requires at least one children component");if(n){if(!u({value:n,tabValues:r}))throw new Error(`Docusaurus error: The has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${r.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const s=r.find((e=>e.default))??r[0];if(!s)throw new Error("Unexpected error: 0 tabValues");return s.value}({defaultValue:n,tabValues:i}))),[c,h]=m({queryString:r,groupId:t}),[f,x]=function(e){let{groupId:n}=e;const r=function(e){return e?`docusaurus.tab.${e}`:null}(n),[t,i]=(0,d.Nk)(r);return[t,(0,s.useCallback)((e=>{r&&i.set(e)}),[r,i])]}({groupId:t}),y=(()=>{const e=c??f;return u({value:e,tabValues:i})?e:null})();(0,o.Z)((()=>{y&&l(y)}),[y]);return{selectedValue:a,selectValue:(0,s.useCallback)((e=>{if(!u({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);l(e),h(e),x(e)}),[h,x,i]),tabValues:i}}var x=r(2389);const y={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var v=r(5893);function g(e){let{className:n,block:r,selectedValue:s,selectValue:a,tabValues:o}=e;const l=[],{blockElementScrollPositionUntilNextRender:c}=(0,i.o5)(),d=e=>{const n=e.currentTarget,r=l.indexOf(n),t=o[r].value;t!==s&&(c(n),a(t))},h=e=>{let n=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const r=l.indexOf(e.currentTarget)+1;n=l[r]??l[0];break}case"ArrowLeft":{const r=l.indexOf(e.currentTarget)-1;n=l[r]??l[l.length-1];break}}n?.focus()};return(0,v.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,t.Z)("tabs",{"tabs--block":r},n),children:o.map((e=>{let{value:n,label:r,attributes:i}=e;return(0,v.jsx)("li",{role:"tab",tabIndex:s===n?0:-1,"aria-selected":s===n,ref:e=>l.push(e),onKeyDown:h,onClick:d,...i,className:(0,t.Z)("tabs__item",y.tabItem,i?.className,{"tabs__item--active":s===n}),children:r??n},n)}))})}function j(e){let{lazy:n,children:r,selectedValue:t}=e;const i=(Array.isArray(r)?r:[r]).filter(Boolean);if(n){const e=i.find((e=>e.props.value===t));return e?(0,s.cloneElement)(e,{className:"margin-top--md"}):null}return(0,v.jsx)("div",{className:"margin-top--md",children:i.map(((e,n)=>(0,s.cloneElement)(e,{key:n,hidden:e.props.value!==t})))})}function b(e){const n=f(e);return(0,v.jsxs)("div",{className:(0,t.Z)("tabs-container",y.tabList),children:[(0,v.jsx)(g,{...n,...e}),(0,v.jsx)(j,{...n,...e})]})}function _(e){const n=(0,x.Z)();return(0,v.jsx)(b,{...e,children:h(e.children)},String(n))}},1151:(e,n,r)=>{r.d(n,{Z:()=>o,a:()=>a});var s=r(7294);const t={},i=s.createContext(t);function a(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:a(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/dbb7d2f3.b783db9c.js b/assets/js/dbb7d2f3.b783db9c.js new file mode 100644 index 0000000000..843b8c3894 --- /dev/null +++ b/assets/js/dbb7d2f3.b783db9c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkosism=self.webpackChunkosism||[]).push([[5378],{9488:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>d,contentTitle:()=>l,default:()=>u,frontMatter:()=>o,metadata:()=>c,toc:()=>h});var s=r(5893),t=r(1151),i=r(4866),a=r(5162);const o={sidebar_label:"Ceph",sidebar_position:50},l="Ceph",c={id:"guides/deploy-guide/services/ceph",title:"Ceph",description:"In OSISM it is also possible to integrate and use existing Ceph clusters. It",source:"@site/docs/guides/deploy-guide/services/ceph.mdx",sourceDirName:"guides/deploy-guide/services",slug:"/guides/deploy-guide/services/ceph",permalink:"/docs/guides/deploy-guide/services/ceph",draft:!1,unlisted:!1,editUrl:"https://github.com/osism/osism.github.io/tree/main/docs/guides/deploy-guide/services/ceph.mdx",tags:[],version:"current",sidebarPosition:50,frontMatter:{sidebar_label:"Ceph",sidebar_position:50},sidebar:"tutorialSidebar",previous:{title:"Logging & Monitoring",permalink:"/docs/guides/deploy-guide/services/logging-monitoring"},next:{title:"Ceph via Rook (technical preview)",permalink:"/docs/guides/deploy-guide/services/rook"}},d={},h=[{value:"RGW service",id:"rgw-service",level:2},{value:"Avoiding service restarts",id:"avoiding-service-restarts",level:2},{value:"Throttling service restarts",id:"throttling-service-restarts",level:2}];function p(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,t.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"ceph",children:"Ceph"}),"\n",(0,s.jsxs)(n.p,{children:["In OSISM it is also possible to integrate and use existing Ceph clusters. It\nis not necessary to deploy Ceph with OSISM. If Ceph is deployed with OSISM, it\nshould be noted that OSISM does not claim to provide all possible features of Ceph.\nCeph provided with OSISM is intended to provide the storage for Glance, Nova, Cinder\nand Manila. In a specific way that has been implemented by OSISM for years. It\nshould be checked in advance whether the way in OSISM the Ceph deployment and the\nprovided features are sufficient. If this is not the case, it is recommended to\ndeploy Ceph in a different way directly and independently of OSISM. For possible\nopen source projects, please refer to\n",(0,s.jsx)(n.a,{href:"https://docs.ceph.com/en/latest/cephadm/index.html",children:"cephadm"})," and\n",(0,s.jsx)(n.a,{href:"https://rook.io",children:"Rook"}),"."]}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsxs)(n.p,{children:["Before starting the Ceph deployment, the configuration and preparation of the\nOSD devices must be completed. The steps that are required for this can be found in the\n",(0,s.jsx)(n.a,{href:"/docs/guides/configuration-guide/ceph#osd-devices",children:"Ceph Configuration Guide"}),"."]})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Deploy services."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Deploy ",(0,s.jsx)(n.a,{href:"https://docs.ceph.com/en/quincy/man/8/ceph-mon/",children:"ceph-mon"})," services"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply ceph-mons\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Deploy ceph-mgr services"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply ceph-mgrs\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Deploy ",(0,s.jsx)(n.a,{href:"https://docs.ceph.com/en/quincy/man/8/ceph-osd/",children:"ceph-osd"})," services"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply ceph-osds\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Generate pools and keys. This step is only necessary for OSISM >= 7.0.0."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply ceph-pools\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Deploy ceph-crash services"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply ceph-crash\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.admonition,{type:"info",children:[(0,s.jsx)(n.p,{children:"It's all done step by step here. It is also possible to do this in a single step.\nThis speeds up the entire process and avoids unnecessary restarts of individual\nservices."}),(0,s.jsxs)(i.Z,{children:[(0,s.jsxs)(a.Z,{value:"osism-7",label:"OSISM >= 7.0.0",children:[(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply ceph\n"})}),(0,s.jsx)(n.p,{children:"Generate pools and keys."}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply ceph-pools\n"})})]}),(0,s.jsx)(a.Z,{value:"osism-6",label:"OSISM < 7.0.0",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply ceph-base\n"})})})]})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Get ceph keys. This places the necessary keys in ",(0,s.jsx)(n.code,{children:"/opt/configuration"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply copy-ceph-keys\n"})}),"\n",(0,s.jsx)(n.p,{children:"After run, these keys must be permanently added to the configuration repository\nvia Git."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"environments/infrastructure/files/ceph/ceph.client.admin.keyring\nenvironments/kolla/files/overlays/gnocchi/ceph.client.gnocchi.keyring\nenvironments/kolla/files/overlays/nova/ceph.client.cinder.keyring\nenvironments/kolla/files/overlays/nova/ceph.client.nova.keyring\nenvironments/kolla/files/overlays/cinder/cinder-backup/ceph.client.cinder.keyring\nenvironments/kolla/files/overlays/cinder/cinder-backup/ceph.client.cinder-backup.keyring\nenvironments/kolla/files/overlays/cinder/cinder-volume/ceph.client.cinder.keyring\nenvironments/kolla/files/overlays/manila/ceph.client.manila.keyring\nenvironments/kolla/files/overlays/glance/ceph.client.glance.keyring\n"})}),"\n",(0,s.jsxs)(n.p,{children:["If the ",(0,s.jsx)(n.code,{children:"osism apply copy-ceph-keys"})," fails because the keys are not found in the ",(0,s.jsx)(n.code,{children:"/share"}),"\ndirectory, this can be ignored. The keys of the predefined keys (e.g. for Manila) were\nthen not created as they are not used. If you only use Ceph and do not need the predefined\nkeys for OpenStack at all, you can also overwrite the ",(0,s.jsx)(n.code,{children:"ceph_kolla_keys"})," parameter to skip\nthese keys."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/ceph/configuration.yml"',children:"ceph_kolla_keys: []\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"After the Ceph keys have been persisted in the configuration repository, the Ceph\nclient can be deployed."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply cephclient\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Enable and prepare the use of the Ceph dashboard."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply ceph-bootstrap-dashboard\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"rgw-service",children:"RGW service"}),"\n",(0,s.jsx)(n.p,{children:"Deployment of the Ceph RGW Service is optional. How the Ceph RGW service can be deployed\nand integrated into OpenStack is described here."}),"\n",(0,s.jsxs)(n.admonition,{type:"info",children:[(0,s.jsxs)(n.p,{children:["If an initial deployment is performed and Ceph RGW is not added to an existing deployment,\nsteps 4 and 5 are ",(0,s.jsx)(n.strong,{children:"not"})," required."]}),(0,s.jsxs)(n.p,{children:["Step 3 is then performed ",(0,s.jsx)(n.strong,{children:"later after"})," the OpenStack Keystone service has been deployed."]})]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/docs/guides/configuration-guide/ceph#rgw-service",children:"Configure the RGW service"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Apply role ",(0,s.jsx)(n.code,{children:"ceph-rgws"})," to deploy the Ceph RGW services."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply ceph-rgws\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Apply role ",(0,s.jsx)(n.code,{children:"kolla-ceph-rgw"})," to add the OpenStack endpoint.\nIf an initial deployment is performed and Ceph RGW is not added\nto an existing deployment run this step later after the OpenStack\nKeystone service has been deployed."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply kolla-ceph-rgw\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Apply role ",(0,s.jsx)(n.code,{children:"loadbalancer"})," to add the HAProxy backend and frontend."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply loadbalancer\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Apply role ",(0,s.jsx)(n.code,{children:"horizon"})," to enable the Swift dashboard."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply horizon\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"avoiding-service-restarts",children:"Avoiding service restarts"}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsx)(n.p,{children:"Usable from OSISM 7.0.3 onwards."})}),"\n",(0,s.jsx)(n.p,{children:"If Ceph services are deployed sequentially, this can lead to unwanted service restarts.\nThis can also happen if, for example, new OSDs are added later or a new control node is\nadded."}),"\n",(0,s.jsx)(n.p,{children:"The Ceph RGW services are deployed here without restarting the Ceph OSD services."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply ceph-rgws -e ceph_handler_osds_restart=False\n"})}),"\n",(0,s.jsx)(n.p,{children:"The following parameters are available. Any number of parameters can be used with a single command."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"ceph_handler_crash_restart\nceph_handler_mdss_restart\nceph_handler_mgrs_restart\nceph_handler_mons_restart\nceph_handler_osds_restart\nceph_handler_rbdmirrors_restart\nceph_handler_rgws_restart\n"})}),"\n",(0,s.jsx)(n.h2,{id:"throttling-service-restarts",children:"Throttling service restarts"}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsx)(n.p,{children:"Usable from OSISM 7.0.3 onwards."})}),"\n",(0,s.jsx)(n.p,{children:"Sometimes service restarts are required. For example, if the configuration has changed\nor if new OSDs have been added. It may be necessary and useful to only restart the\nservices on a specific number of nodes at a specific time."}),"\n",(0,s.jsxs)(n.p,{children:["Further information on throttling can be found in the\n",(0,s.jsx)(n.a,{href:"https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_strategies.html#restricting-execution-with-throttle",children:"Ansible documentation"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"The Ceph OSD services are deployed here. If there is a restart required of other OSDs\nthat are already running, these restarts are executed on a maximum of 2 nodes at the\nsame time. The OSD services themselves on a node are always restarted one after the other\nand never all at the same time."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply ceph-osds -e ceph_handler_osds_restart_throttle=2\n"})}),"\n",(0,s.jsxs)(n.p,{children:["If the nodes are to be processed one after the other, ",(0,s.jsx)(n.code,{children:"ceph_handler_osds_restart_throttle=1"}),"\ncan be used."]}),"\n",(0,s.jsx)(n.p,{children:"The following parameters are available. Any number of parameters can be used with a single command."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"ceph_handler_crash_restart_throttle\nceph_handler_mdss_restart_throttle\nceph_handler_mgrs_restart_throttle\nceph_handler_mons_restart_throttle\nceph_handler_osds_restart_throttle\nceph_handler_rbdmirrors_restart_throttle\nceph_handler_rgws_restart_throttle\n"})})]})}function u(e={}){const{wrapper:n}={...(0,t.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(p,{...e})}):p(e)}},5162:(e,n,r)=>{r.d(n,{Z:()=>a});r(7294);var s=r(6905);const t={tabItem:"tabItem_Ymn6"};var i=r(5893);function a(e){let{children:n,hidden:r,className:a}=e;return(0,i.jsx)("div",{role:"tabpanel",className:(0,s.Z)(t.tabItem,a),hidden:r,children:n})}},4866:(e,n,r)=>{r.d(n,{Z:()=>_});var s=r(7294),t=r(6905),i=r(2466),a=r(6550),o=r(469),l=r(1980),c=r(7392),d=r(812);function h(e){return s.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,s.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function p(e){const{values:n,children:r}=e;return(0,s.useMemo)((()=>{const e=n??function(e){return h(e).map((e=>{let{props:{value:n,label:r,attributes:s,default:t}}=e;return{value:n,label:r,attributes:s,default:t}}))}(r);return function(e){const n=(0,c.l)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[n,r])}function u(e){let{value:n,tabValues:r}=e;return r.some((e=>e.value===n))}function m(e){let{queryString:n=!1,groupId:r}=e;const t=(0,a.k6)(),i=function(e){let{queryString:n=!1,groupId:r}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!r)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return r??null}({queryString:n,groupId:r});return[(0,l._X)(i),(0,s.useCallback)((e=>{if(!i)return;const n=new URLSearchParams(t.location.search);n.set(i,e),t.replace({...t.location,search:n.toString()})}),[i,t])]}function f(e){const{defaultValue:n,queryString:r=!1,groupId:t}=e,i=p(e),[a,l]=(0,s.useState)((()=>function(e){let{defaultValue:n,tabValues:r}=e;if(0===r.length)throw new Error("Docusaurus error: the component requires at least one children component");if(n){if(!u({value:n,tabValues:r}))throw new Error(`Docusaurus error: The has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${r.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const s=r.find((e=>e.default))??r[0];if(!s)throw new Error("Unexpected error: 0 tabValues");return s.value}({defaultValue:n,tabValues:i}))),[c,h]=m({queryString:r,groupId:t}),[f,x]=function(e){let{groupId:n}=e;const r=function(e){return e?`docusaurus.tab.${e}`:null}(n),[t,i]=(0,d.Nk)(r);return[t,(0,s.useCallback)((e=>{r&&i.set(e)}),[r,i])]}({groupId:t}),y=(()=>{const e=c??f;return u({value:e,tabValues:i})?e:null})();(0,o.Z)((()=>{y&&l(y)}),[y]);return{selectedValue:a,selectValue:(0,s.useCallback)((e=>{if(!u({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);l(e),h(e),x(e)}),[h,x,i]),tabValues:i}}var x=r(2389);const y={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var v=r(5893);function g(e){let{className:n,block:r,selectedValue:s,selectValue:a,tabValues:o}=e;const l=[],{blockElementScrollPositionUntilNextRender:c}=(0,i.o5)(),d=e=>{const n=e.currentTarget,r=l.indexOf(n),t=o[r].value;t!==s&&(c(n),a(t))},h=e=>{let n=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const r=l.indexOf(e.currentTarget)+1;n=l[r]??l[0];break}case"ArrowLeft":{const r=l.indexOf(e.currentTarget)-1;n=l[r]??l[l.length-1];break}}n?.focus()};return(0,v.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,t.Z)("tabs",{"tabs--block":r},n),children:o.map((e=>{let{value:n,label:r,attributes:i}=e;return(0,v.jsx)("li",{role:"tab",tabIndex:s===n?0:-1,"aria-selected":s===n,ref:e=>l.push(e),onKeyDown:h,onClick:d,...i,className:(0,t.Z)("tabs__item",y.tabItem,i?.className,{"tabs__item--active":s===n}),children:r??n},n)}))})}function j(e){let{lazy:n,children:r,selectedValue:t}=e;const i=(Array.isArray(r)?r:[r]).filter(Boolean);if(n){const e=i.find((e=>e.props.value===t));return e?(0,s.cloneElement)(e,{className:"margin-top--md"}):null}return(0,v.jsx)("div",{className:"margin-top--md",children:i.map(((e,n)=>(0,s.cloneElement)(e,{key:n,hidden:e.props.value!==t})))})}function b(e){const n=f(e);return(0,v.jsxs)("div",{className:(0,t.Z)("tabs-container",y.tabList),children:[(0,v.jsx)(g,{...n,...e}),(0,v.jsx)(j,{...n,...e})]})}function _(e){const n=(0,x.Z)();return(0,v.jsx)(b,{...e,children:h(e.children)},String(n))}},1151:(e,n,r)=>{r.d(n,{Z:()=>o,a:()=>a});var s=r(7294);const t={},i=s.createContext(t);function a(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:a(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/dbe528c9.5621f50f.js b/assets/js/dbe528c9.5621f50f.js deleted file mode 100644 index bf0c4cd6f7..0000000000 --- a/assets/js/dbe528c9.5621f50f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkosism=self.webpackChunkosism||[]).push([[6330],{7752:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>r,contentTitle:()=>c,default:()=>p,frontMatter:()=>t,metadata:()=>a,toc:()=>l});var i=s(5893),o=s(1151);const t={sidebar_label:"OpenStack",sidebar_position:60},c="OpenStack",a={id:"guides/deploy-guide/services/openstack",title:"OpenStack",description:"Common issues with deploying OpenStack services are documented in the",source:"@site/docs/guides/deploy-guide/services/openstack.md",sourceDirName:"guides/deploy-guide/services",slug:"/guides/deploy-guide/services/openstack",permalink:"/docs/guides/deploy-guide/services/openstack",draft:!1,unlisted:!1,editUrl:"https://github.com/osism/osism.github.io/tree/main/docs/guides/deploy-guide/services/openstack.md",tags:[],version:"current",sidebarPosition:60,frontMatter:{sidebar_label:"OpenStack",sidebar_position:60},sidebar:"tutorialSidebar",previous:{title:"Ceph",permalink:"/docs/guides/deploy-guide/services/ceph"},next:{title:"Examples",permalink:"/docs/guides/deploy-guide/examples/"}},r={},l=[];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",li:"li",ol:"ol",p:"p",pre:"pre",...(0,o.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"openstack",children:"OpenStack"}),"\n",(0,i.jsxs)(n.p,{children:["Common issues with deploying OpenStack services are documented in the\n",(0,i.jsx)(n.a,{href:"/docs/guides/troubleshooting-guide/openstack",children:"OpenStack Troubleshooting Guide"}),"."]}),"\n",(0,i.jsx)(n.admonition,{type:"info",children:(0,i.jsxs)(n.p,{children:["An OpenStack deployment contains a number of components providing APIs to access infrastructure resources.\nThe ",(0,i.jsx)(n.a,{href:"https://www.openstack.org/software/project-navigator/openstack-components#openstack-services",children:"OpenStack Components"}),"\npage lists the various services that can be deployed to provide such resources to cloud end users.\nUnfortunately, not all of the OpenStack projects listed there are still active.\nNot all of the services listed there are supported by OSISM."]})}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"OpenStack client"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply openstackclient\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Keystone"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull keystone\nosism apply keystone\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Glance"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull glance\nosism apply glance\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Designate"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull designate\nosism apply designate\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Placement"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull placement\nosism apply placement\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Cinder"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull cinder\nosism apply cinder\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Neutron"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull neutron\nosism apply neutron\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Nova"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull nova\nosism apply nova\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Octavia"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull octavia\nosism apply octavia\n"})}),"\n",(0,i.jsx)(n.p,{children:"9.1. Manage amphora image"}),"\n",(0,i.jsx)(n.p,{children:"This step is only necessary if the Amphora Driver is used. If OVN is used as the driver,\nthis step is not necessary."}),"\n",(0,i.jsxs)(n.p,{children:["We provide regularly updated images for Octavia in\n",(0,i.jsx)(n.a,{href:"https://github.com/osism/openstack-octavia-amphora-image",children:"osism/openstack-octavia/amphora-image"}),".\nThe OSISM CLI can be used to upload the correct image depending on the OpenStack release\nused."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism manage image octavia\n"})}),"\n",(0,i.jsxs)(n.p,{children:["For the command to be usable, a cloud profile for octavia must currently be added in the\nclouds.yml file of the OpenStack environment. The ",(0,i.jsx)(n.code,{children:"auth_url"})," is changed accordingly."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/openstack/clouds.yml"',children:"clouds:\n [...]\n octavia:\n auth:\n username: octavia\n project_name: service\n auth_url: https://api.testbed.osism.xyz:5000/v3\n project_domain_name: default\n user_domain_name: default\n cacert: /etc/ssl/certs/ca-certificates.crt\n identity_api_version: 3\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The secret is added to the secure.yml file. The password is set in the parameter\n",(0,i.jsx)(n.code,{children:"octavia_keystone_password"})," in the file ",(0,i.jsx)(n.code,{children:"environments/kolla/secrets.yml"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/openstack/secure.yml"',children:"clouds:\n [...]\n octavia:\n auth:\n password: VALUE_OF_octavia_keystone_password\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Horizon"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull horizon\nosism apply horizon\n"})}),"\n"]}),"\n"]})]})}function p(e={}){const{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},1151:(e,n,s)=>{s.d(n,{Z:()=>a,a:()=>c});var i=s(7294);const o={},t=i.createContext(o);function c(e){const n=i.useContext(t);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),i.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/dbe528c9.dcae05da.js b/assets/js/dbe528c9.dcae05da.js new file mode 100644 index 0000000000..e972db63ef --- /dev/null +++ b/assets/js/dbe528c9.dcae05da.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkosism=self.webpackChunkosism||[]).push([[6330],{7752:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>r,contentTitle:()=>c,default:()=>p,frontMatter:()=>t,metadata:()=>a,toc:()=>l});var i=s(5893),o=s(1151);const t={sidebar_label:"OpenStack",sidebar_position:60},c="OpenStack",a={id:"guides/deploy-guide/services/openstack",title:"OpenStack",description:"Common issues with deploying OpenStack services are documented in the",source:"@site/docs/guides/deploy-guide/services/openstack.md",sourceDirName:"guides/deploy-guide/services",slug:"/guides/deploy-guide/services/openstack",permalink:"/docs/guides/deploy-guide/services/openstack",draft:!1,unlisted:!1,editUrl:"https://github.com/osism/osism.github.io/tree/main/docs/guides/deploy-guide/services/openstack.md",tags:[],version:"current",sidebarPosition:60,frontMatter:{sidebar_label:"OpenStack",sidebar_position:60},sidebar:"tutorialSidebar",previous:{title:"Ceph via Rook (technical preview)",permalink:"/docs/guides/deploy-guide/services/rook"},next:{title:"Examples",permalink:"/docs/guides/deploy-guide/examples/"}},r={},l=[];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",li:"li",ol:"ol",p:"p",pre:"pre",...(0,o.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"openstack",children:"OpenStack"}),"\n",(0,i.jsxs)(n.p,{children:["Common issues with deploying OpenStack services are documented in the\n",(0,i.jsx)(n.a,{href:"/docs/guides/troubleshooting-guide/openstack",children:"OpenStack Troubleshooting Guide"}),"."]}),"\n",(0,i.jsx)(n.admonition,{type:"info",children:(0,i.jsxs)(n.p,{children:["An OpenStack deployment contains a number of components providing APIs to access infrastructure resources.\nThe ",(0,i.jsx)(n.a,{href:"https://www.openstack.org/software/project-navigator/openstack-components#openstack-services",children:"OpenStack Components"}),"\npage lists the various services that can be deployed to provide such resources to cloud end users.\nUnfortunately, not all of the OpenStack projects listed there are still active.\nNot all of the services listed there are supported by OSISM."]})}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"OpenStack client"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply openstackclient\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Keystone"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull keystone\nosism apply keystone\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Glance"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull glance\nosism apply glance\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Designate"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull designate\nosism apply designate\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Placement"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull placement\nosism apply placement\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Cinder"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull cinder\nosism apply cinder\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Neutron"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull neutron\nosism apply neutron\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Nova"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull nova\nosism apply nova\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Octavia"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull octavia\nosism apply octavia\n"})}),"\n",(0,i.jsx)(n.p,{children:"9.1. Manage amphora image"}),"\n",(0,i.jsx)(n.p,{children:"This step is only necessary if the Amphora Driver is used. If OVN is used as the driver,\nthis step is not necessary."}),"\n",(0,i.jsxs)(n.p,{children:["We provide regularly updated images for Octavia in\n",(0,i.jsx)(n.a,{href:"https://github.com/osism/openstack-octavia-amphora-image",children:"osism/openstack-octavia/amphora-image"}),".\nThe OSISM CLI can be used to upload the correct image depending on the OpenStack release\nused."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism manage image octavia\n"})}),"\n",(0,i.jsxs)(n.p,{children:["For the command to be usable, a cloud profile for octavia must currently be added in the\nclouds.yml file of the OpenStack environment. The ",(0,i.jsx)(n.code,{children:"auth_url"})," is changed accordingly."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/openstack/clouds.yml"',children:"clouds:\n [...]\n octavia:\n auth:\n username: octavia\n project_name: service\n auth_url: https://api.testbed.osism.xyz:5000/v3\n project_domain_name: default\n user_domain_name: default\n cacert: /etc/ssl/certs/ca-certificates.crt\n identity_api_version: 3\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The secret is added to the secure.yml file. The password is set in the parameter\n",(0,i.jsx)(n.code,{children:"octavia_keystone_password"})," in the file ",(0,i.jsx)(n.code,{children:"environments/kolla/secrets.yml"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/openstack/secure.yml"',children:"clouds:\n [...]\n octavia:\n auth:\n password: VALUE_OF_octavia_keystone_password\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Horizon"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull horizon\nosism apply horizon\n"})}),"\n"]}),"\n"]})]})}function p(e={}){const{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},1151:(e,n,s)=>{s.d(n,{Z:()=>a,a:()=>c});var i=s(7294);const o={},t=i.createContext(o);function c(e){const n=i.useContext(t);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),i.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e0698a94.01224bf7.js b/assets/js/e0698a94.0903da87.js similarity index 69% rename from assets/js/e0698a94.01224bf7.js rename to assets/js/e0698a94.0903da87.js index ebc40a9005..30e5379f22 100644 --- a/assets/js/e0698a94.01224bf7.js +++ b/assets/js/e0698a94.0903da87.js @@ -1 +1 @@ -"use strict";(self.webpackChunkosism=self.webpackChunkosism||[]).push([[8157],{9177:(e,i,s)=>{s.r(i),s.d(i,{assets:()=>c,contentTitle:()=>n,default:()=>a,frontMatter:()=>t,metadata:()=>d,toc:()=>u});var r=s(5893),o=s(1151);const t={sidebar_label:"Services",sidebar_position:100},n="Services",d={id:"guides/deploy-guide/services/index",title:"Services",description:"The prerequisite for depoying the services of a cluster is the bootstrap of",source:"@site/docs/guides/deploy-guide/services/index.md",sourceDirName:"guides/deploy-guide/services",slug:"/guides/deploy-guide/services/",permalink:"/docs/guides/deploy-guide/services/",draft:!1,unlisted:!1,editUrl:"https://github.com/osism/osism.github.io/tree/main/docs/guides/deploy-guide/services/index.md",tags:[],version:"current",sidebarPosition:100,frontMatter:{sidebar_label:"Services",sidebar_position:100},sidebar:"tutorialSidebar",previous:{title:"Bootstrap",permalink:"/docs/guides/deploy-guide/bootstrap"},next:{title:"Infrastructure",permalink:"/docs/guides/deploy-guide/services/infrastructure"}},c={},u=[];function l(e){const i={a:"a",admonition:"admonition",h1:"h1",li:"li",ol:"ol",p:"p",...(0,o.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(i.h1,{id:"services",children:"Services"}),"\n",(0,r.jsx)(i.admonition,{type:"info",children:(0,r.jsxs)(i.p,{children:["The prerequisite for depoying the services of a cluster is the bootstrap of\nthe nodes. How to bootstrap the nodes is documented in the\n",(0,r.jsx)(i.a,{href:"/docs/guides/deploy-guide/bootstrap",children:"Bootstrap chapter of the Deploy Guide"}),"."]})}),"\n",(0,r.jsx)(i.p,{children:"When setting up a new cluster, the services are deployed in a specific order."}),"\n",(0,r.jsxs)(i.ol,{children:["\n",(0,r.jsx)(i.li,{children:(0,r.jsx)(i.a,{href:"/docs/guides/deploy-guide/services/infrastructure",children:"Infrastructure"})}),"\n",(0,r.jsx)(i.li,{children:(0,r.jsx)(i.a,{href:"/docs/guides/deploy-guide/services/network",children:"Network"})}),"\n",(0,r.jsx)(i.li,{children:(0,r.jsx)(i.a,{href:"/docs/guides/deploy-guide/services/logging-monitoring",children:"Logging & Monitoring"})}),"\n",(0,r.jsx)(i.li,{children:(0,r.jsx)(i.a,{href:"/docs/guides/deploy-guide/services/ceph",children:"Ceph"})}),"\n",(0,r.jsx)(i.li,{children:(0,r.jsx)(i.a,{href:"/docs/guides/deploy-guide/services/openstack",children:"OpenStack"})}),"\n"]})]})}function a(e={}){const{wrapper:i}={...(0,o.a)(),...e.components};return i?(0,r.jsx)(i,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},1151:(e,i,s)=>{s.d(i,{Z:()=>d,a:()=>n});var r=s(7294);const o={},t=r.createContext(o);function n(e){const i=r.useContext(t);return r.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function d(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:n(e.components),r.createElement(t.Provider,{value:i},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkosism=self.webpackChunkosism||[]).push([[8157],{9177:(e,i,s)=>{s.r(i),s.d(i,{assets:()=>c,contentTitle:()=>n,default:()=>a,frontMatter:()=>t,metadata:()=>d,toc:()=>u});var r=s(5893),o=s(1151);const t={sidebar_label:"Services",sidebar_position:100},n="Services",d={id:"guides/deploy-guide/services/index",title:"Services",description:"The prerequisite for depoying the services of a cluster is the bootstrap of",source:"@site/docs/guides/deploy-guide/services/index.md",sourceDirName:"guides/deploy-guide/services",slug:"/guides/deploy-guide/services/",permalink:"/docs/guides/deploy-guide/services/",draft:!1,unlisted:!1,editUrl:"https://github.com/osism/osism.github.io/tree/main/docs/guides/deploy-guide/services/index.md",tags:[],version:"current",sidebarPosition:100,frontMatter:{sidebar_label:"Services",sidebar_position:100},sidebar:"tutorialSidebar",previous:{title:"Bootstrap",permalink:"/docs/guides/deploy-guide/bootstrap"},next:{title:"Infrastructure",permalink:"/docs/guides/deploy-guide/services/infrastructure"}},c={},u=[];function l(e){const i={a:"a",admonition:"admonition",h1:"h1",li:"li",ol:"ol",p:"p",...(0,o.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(i.h1,{id:"services",children:"Services"}),"\n",(0,r.jsx)(i.admonition,{type:"info",children:(0,r.jsxs)(i.p,{children:["The prerequisite for depoying the services of a cluster is the bootstrap of\nthe nodes. How to bootstrap the nodes is documented in the\n",(0,r.jsx)(i.a,{href:"/docs/guides/deploy-guide/bootstrap",children:"Bootstrap chapter of the Deploy Guide"}),"."]})}),"\n",(0,r.jsx)(i.p,{children:"When setting up a new cluster, the services are deployed in a specific order."}),"\n",(0,r.jsxs)(i.ol,{children:["\n",(0,r.jsx)(i.li,{children:(0,r.jsx)(i.a,{href:"/docs/guides/deploy-guide/services/infrastructure",children:"Infrastructure"})}),"\n",(0,r.jsx)(i.li,{children:(0,r.jsx)(i.a,{href:"/docs/guides/deploy-guide/services/network",children:"Network"})}),"\n",(0,r.jsx)(i.li,{children:(0,r.jsx)(i.a,{href:"/docs/guides/deploy-guide/services/logging-monitoring",children:"Logging & Monitoring"})}),"\n",(0,r.jsxs)(i.li,{children:[(0,r.jsx)(i.a,{href:"/docs/guides/deploy-guide/services/ceph",children:"Ceph"})," or ",(0,r.jsx)(i.a,{href:"/docs/guides/deploy-guide/services/rook",children:"Ceph via Rook (technical preview)"})]}),"\n",(0,r.jsx)(i.li,{children:(0,r.jsx)(i.a,{href:"/docs/guides/deploy-guide/services/openstack",children:"OpenStack"})}),"\n"]})]})}function a(e={}){const{wrapper:i}={...(0,o.a)(),...e.components};return i?(0,r.jsx)(i,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},1151:(e,i,s)=>{s.d(i,{Z:()=>d,a:()=>n});var r=s(7294);const o={},t=r.createContext(o);function n(e){const i=r.useContext(t);return r.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function d(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:n(e.components),r.createElement(t.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/fac2b365.8ae758ab.js b/assets/js/fac2b365.8ae758ab.js new file mode 100644 index 0000000000..a1ffef67a7 --- /dev/null +++ b/assets/js/fac2b365.8ae758ab.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkosism=self.webpackChunkosism||[]).push([[9377],{2201:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>o,default:()=>h,frontMatter:()=>s,metadata:()=>l,toc:()=>c});var i=t(5893),r=t(1151);const s={sidebar_label:"Configuration repository",sidebar_position:10},o="Configuration Repository",l={id:"guides/configuration-guide/configuration-repository",title:"Configuration Repository",description:"The configuration required for an OSISM managed cluster is stored in a single Git",source:"@site/docs/guides/configuration-guide/configuration-repository.md",sourceDirName:"guides/configuration-guide",slug:"/guides/configuration-guide/configuration-repository",permalink:"/docs/guides/configuration-guide/configuration-repository",draft:!1,unlisted:!1,editUrl:"https://github.com/osism/osism.github.io/tree/main/docs/guides/configuration-guide/configuration-repository.md",tags:[],version:"current",sidebarPosition:10,frontMatter:{sidebar_label:"Configuration repository",sidebar_position:10},sidebar:"tutorialSidebar",previous:{title:"Configuration Guide",permalink:"/docs/guides/configuration-guide/"},next:{title:"Inventory",permalink:"/docs/guides/configuration-guide/inventory"}},d={},c=[{value:"Creating a new configuration repository",id:"creating-a-new-configuration-repository",level:2},{value:"Step 1: Preparation",id:"step-1-preparation",level:3},{value:"Step 2: Run Cookiecutter",id:"step-2-run-cookiecutter",level:3},{value:"Step 3: Upload the new configuration to the remote git repository",id:"step-3-upload-the-new-configuration-to-the-remote-git-repository",level:3},{value:"Step 4: Post-processing of the generated configuration",id:"step-4-post-processing-of-the-generated-configuration",level:3},{value:"Secrets",id:"secrets",level:4},{value:"Manager inventory",id:"manager-inventory",level:4},{value:"Global inventory",id:"global-inventory",level:4},{value:"DNS servers",id:"dns-servers",level:4},{value:"NTP servers",id:"ntp-servers",level:4},{value:"Certificates",id:"certificates",level:4},{value:"Using latest",id:"using-latest",level:2},{value:"Parameter reference",id:"parameter-reference",level:2},{value:"Configuration repository layout",id:"configuration-repository-layout",level:2},{value:"Synchronising the configuration repository",id:"synchronising-the-configuration-repository",level:2},{value:"Locks",id:"locks",level:2},{value:"Working with encrypted files",id:"working-with-encrypted-files",level:2}];function a(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"configuration-repository",children:"Configuration Repository"}),"\n",(0,i.jsx)(n.p,{children:"The configuration required for an OSISM managed cluster is stored in a single Git\nmonorepo, the configuration repository."}),"\n",(0,i.jsx)(n.h2,{id:"creating-a-new-configuration-repository",children:"Creating a new configuration repository"}),"\n",(0,i.jsxs)(n.p,{children:["The initial content for this configuration repository is generated using the\n",(0,i.jsx)(n.a,{href:"https://github.com/osism/cfg-cookiecutter",children:"Cookiecutter"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"Cookiecutter generates a simple initial configuration for your new cluster by prompting\nyou for the basic details of the new cluster."}),"\n",(0,i.jsxs)(n.p,{children:["The configuration repository is not created on the future Manager node. It is created on a\nlocal workstation. If the local workstation cannot be used for this purpose, a dedicated\nvirtual system can be used. For more information on this topic, refer to the\n",(0,i.jsx)(n.a,{href:"/docs/guides/deploy-guide/seed",children:"Seed Deploy Guide"}),"."]}),"\n",(0,i.jsx)(n.h3,{id:"step-1-preparation",children:"Step 1: Preparation"}),"\n",(0,i.jsxs)(n.p,{children:["First decide where to store your Git repository The content generated by the cookiecutter in\nthe ",(0,i.jsx)(n.code,{children:"output/configuration"})," directory is committed to a new Git repository. By default, the\nconfiguration repository is assumed to be on GitHub. This can also be GitLab or an internal\nGit service as well."]}),"\n",(0,i.jsxs)(n.p,{children:["Host and path to the Git repository are specified by the ",(0,i.jsx)(n.code,{children:"git_"})," parameters. These are\nrequested in step 2. The ",(0,i.jsx)(n.code,{children:"git_"})," parameters do not specify the path to the cookiecutter\nto use."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:" [8/20] git_host (github.com):\n [9/20] git_port (22):\n [10/20] git_repository (YOUR_ORG/YOUR_NEW_CONFIGURATION_REPOSITORY): regiocloud/configuration\n [11/20] git_username (git):\n [12/20] git_version (main):\n"})}),"\n",(0,i.jsxs)(n.p,{children:["In this case, the generated configuration in the ",(0,i.jsx)(n.code,{children:"output/configuration"})," directory is\nstored on GitHub in the ",(0,i.jsx)(n.code,{children:"regiocloud/configuration"})," repository."]}),"\n",(0,i.jsxs)(n.p,{children:["See the ",(0,i.jsx)(n.a,{href:"#parameter-reference",children:"parameter reference"})," for more details. The parameters\nlisted there will be queried during the execution of Cookiecutter."]}),"\n",(0,i.jsx)(n.h3,{id:"step-2-run-cookiecutter",children:"Step 2: Run Cookiecutter"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["The directory ",(0,i.jsx)(n.code,{children:"output"})," is created and used as output volume. It is only necessary to create the empty\ndirectory here."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"mkdir output\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["The Cookiecutter runs inside a container. ",(0,i.jsx)(n.a,{href:"https://docs.docker.com/engine/install/",children:"Docker must be usable on the system"}),"\nwhere the Cookiecutter will be used. It should also work with Podman."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:'docker run \\\n -e TARGET_UID="$(id -u)" \\\n -e TARGET_GID="$(id -g)" \\\n -v $(pwd)/output:/output \\\n --rm -it quay.io/osism/cookiecutter\n'})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["A few parameters are requested. The parameters are documented in detail in the ",(0,i.jsx)(n.a,{href:"#parameter-reference",children:"parameter reference"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["If you want to use the ",(0,i.jsx)(n.code,{children:"latest"})," version, this is done using the ",(0,i.jsx)(n.code,{children:"manager_version"})," parameter. By default,\nthis is always set to the latest stable version."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"manager_version [7.0.4]: latest\n"})}),"\n",(0,i.jsxs)(n.p,{children:["If the ",(0,i.jsx)(n.code,{children:"manager_version"})," parameter is set to ",(0,i.jsx)(n.code,{children:"latest"})," it is also possible to explicitly\nset the ",(0,i.jsx)(n.code,{children:"openstack_version"})," and the ",(0,i.jsx)(n.code,{children:"ceph_version"})," explicitly."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"[1/19] with_ceph (1):\n[2/19] with_keycloak (0):\n[3/19] ceph_network(192.168.16.0/20):\n[4/19] ceph_version (quincy):\n[5/19] domain (osism.xyz):\n[6/19] fqdn_external (api.osism.xyz):\n[7/19] fqdn_internal (api-int.osism.xyz):\n[8/19] git_host (github.com):\n[9/19] git_port (22):\n[10/19] git_repository (YOUR_ORG/YOUR_NEW_CONFIGURATION_REPOSITORY):\n[11/19] git_username (git):\n[12/19] git_version (main):\n[13/19] ip_external (192.168.16.254):\n[14/19] ip_internal (192.168.16.9):\n[15/19] manager_version (7.0.4):\n[16/19] name_server (149.112.112.112):\n[17/19] ntp_server (de.pool.ntp.org):\n[18/19] openstack_version (2023.2):\n[19/19] project_name (configuration):\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"step-3-upload-the-new-configuration-to-the-remote-git-repository",children:"Step 3: Upload the new configuration to the remote git repository"}),"\n",(0,i.jsxs)(n.p,{children:["Add the initial configuration state to the repository. How to add a deploy key on GitHub is documented in\n",(0,i.jsx)(n.a,{href:"https://docs.github.com/en/authentication/connecting-to-github-with-ssh/managing-deploy-keys",children:"Managing deploy keys"}),".\nRead permissions are sufficient."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:'$ git clone git@github.com:YOUR_ORG/YOUR_NEW_CONFIGURATION_REPOSITORY.git YOUR_NEW_CONFIGURATION_REPOSITORY\n$ cp -r output/configuration/{*,.gitignore} YOUR_NEW_CONFIGURATION_REPOSITORY\n$ cd YOUR_NEW_CONFIGURATION_REPOSITORY\n$ git add -A .\n$ git commit -m "Initial commit after bootstrap"\n$ git push\n'})}),"\n",(0,i.jsx)(n.p,{children:"The content is now committed to the Git repository that was created earlier in the process."}),"\n",(0,i.jsxs)(n.admonition,{type:"warning",children:[(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"secrets"})," directory is not stored in the Git repository. Its contents can be\nstored in a trusted location."]}),(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"secrets"})," directory contains an SSH key pair which is used as the deploy key to\nmake the configuration repository available on the manager node later. Write access\nis not required. The public SSH key is stored in the ",(0,i.jsx)(n.code,{children:"secrets/id_rsa.configuration.pub"})," file."]})]}),"\n",(0,i.jsx)(n.h3,{id:"step-4-post-processing-of-the-generated-configuration",children:"Step 4: Post-processing of the generated configuration"}),"\n",(0,i.jsxs)(n.p,{children:["The configuration repository that is initially created with the Cookiecutter is not immediately usable.\nFor example, the inventory needs to be built. All other information can be found in the\n",(0,i.jsx)(n.a,{href:"../configuration-guide/",children:"Configuration Guide"}),". Use ",(0,i.jsx)(n.code,{children:"git"})," to version all your configuration changes."]}),"\n",(0,i.jsx)(n.p,{children:"The following 6 points must be changed after the initial creation of the configuration repository."}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#secrets",children:"Secrets"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#manager-inventory",children:"Manager inventory"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#global-inventory",children:"Global inventory"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#dns-servers",children:"DNS servers"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#ntp-servers",children:"NTP servers"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#certificates",children:"Certificates"})}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"secrets",children:"Secrets"}),"\n",(0,i.jsxs)(n.p,{children:["The password for Ansible Vault encrypted files, is stored in ",(0,i.jsx)(n.code,{children:"secrets/vaultpass"}),". Since the ",(0,i.jsx)(n.code,{children:"secrets"})," directory\nis not added to the configuration repository, it is important to store it in a password vault of your choice."]}),"\n",(0,i.jsxs)(n.p,{children:["The password of the generated Keepass file is ",(0,i.jsx)(n.code,{children:"password"}),". This should be changed when using the Keepass file.\nIf possible, an existing password vault should be used."]}),"\n",(0,i.jsx)(n.h4,{id:"manager-inventory",children:"Manager inventory"}),"\n",(0,i.jsx)(n.p,{children:"The information required to perform the initial bootstrap of the manager node and the initial\ndeployment of the manager service from the seed Node is provided in the inventory of the manager\nenvironment."}),"\n",(0,i.jsxs)(n.p,{children:["In the Cookiecutter, a node ",(0,i.jsx)(n.code,{children:"node01"})," is defined as an example in the manager inventory as well as\nin the global inventory. The name of this node must be changed to match the name of the node used\nas manager in your own cluster."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Roles"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Manager role"}),"\n",(0,i.jsxs)(n.p,{children:["The name of the node on which the manager service is to be deployed is\nadded to inventory group ",(0,i.jsx)(n.code,{children:"manager"})," in file ",(0,i.jsx)(n.code,{children:"environments/manager/hosts"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["Only the ",(0,i.jsx)(n.code,{children:"manager"})," inventory group is available in ",(0,i.jsx)(n.code,{children:"environments/manager/hosts"}),". There are no\nother groups there."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ini",metastring:'title="environments/manager/hosts"',children:"[manager]\nnode01\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Host vars"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Ansible section"}),"\n",(0,i.jsx)(n.p,{children:"The IP address where the node can be reached via SSH from the manager node. If DHCP is used after the\ninitial provisioning to assign an initial IP address to the nodes, the address assigned via DHCP is\ninitially used here and later changed to the static IP address."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/manager/host_vars/node01.yml"',children:"ansible_host: 192.168.16.10\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Generic section"}),"\n",(0,i.jsx)(n.p,{children:"The network interface on which the internal communication of the cluster will take place. If the\ninternal interface does not yet exist at the time the configuration is created, e.g. because it is a\nbond interface or VLAN interface that is only created by the static network configuration, it can be\nalready used here."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/manager/host_vars/node01.yml"',children:"internal_interface: eno1\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Network section"}),"\n",(0,i.jsxs)(n.p,{children:["The static and complete network configuration of the node. Further details on creating the\nnetwork configuration in the ",(0,i.jsx)(n.a,{href:"../configuration-guide/network",children:"network configuration guide"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/manager/host_vars/node01.yml"',children:'network_ethernets:\n eno1:\n addresses:\n - "192.168.16.10/20"\n gateway4: "192.168.16.1"\n mtu: 1500\n'})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"global-inventory",children:"Global inventory"}),"\n",(0,i.jsxs)(n.p,{children:["In the Cookiecutter, a node ",(0,i.jsx)(n.code,{children:"node01"})," is defined as an example in the manager inventory as well as\nin the global inventory. The name of this node must be changed to match the name of the node used\nas manager in your own cluster."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Roles"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Generic role"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ini",metastring:'title="inventory/20-roles"',children:'# The "all" group is not used in OSISM. Therefore it is important\n# that all nodes are explicitly listed here.\n[generic]\nnode01\n'})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Manager role"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ini",metastring:'title="inventory/20-roles"',children:"# Nodes that act as manager (sometimes called deployment node)\n# are included in this group.\n[manager]\nnode01\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Monitoring role"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ini",metastring:'title="inventory/20-roles"',children:"# Nodes which are intended for monitoring services belong to\n# this group\n[monitoring]\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Control role"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ini",metastring:'title="inventory/20-roles"',children:"# Nodes that serve as controllers, so things like scheduler,\n# API or database run there, of the environment.\n[control]\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Compute role"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ini",metastring:'title="inventory/20-roles"',children:"# Virtual systems managed by OpenStack Nova are placed on\n# nodes in this group.\n[compute]\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Network role"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ini",metastring:'title="inventory/20-roles"',children:"# Network resources managed by OpenStack Neutron, such as\n# L3 routers, are placed on these nodes. This group has nothing\n# to do with the general network configuration.\n[network]\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Ceph control role"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ini",metastring:'title="inventory/20-roles"',children:"# Nodes that serve as controllers for Ceph, so things like the\n# Ceph Monitor service run here.\n[ceph-control]\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Ceph resource role"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ini",metastring:'title="inventory/20-roles"',children:"# The storage available in these systems is provided in the\n# form of OSDs for Ceph.\n[ceph-resource]\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Ceph rgw role"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ini",metastring:'title="inventory/20-roles"',children:"[ceph-rgw:children]\nceph-control\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Host vars"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Ansible section"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="inventory/host_vars/node01.yml"',children:"# NOTE: Address where the node can be reached via SSH.\nansible_host: 192.168.16.10\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Generic section"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="inventory/host_vars/node01.yml"',children:"internal_interface: eno1\n\n# NOTE: The address of the internal interface.\ninternal_address: 192.168.16.10\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Netdata section"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="inventory/host_vars/node01.yml"',children:"netdata_host_type: client\n\n# NOTE: Uncomment this when this node should be a Netdata server.\n# netdata_host_type: server\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Network section"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="inventory/host_vars/node01.yml"',children:'# NOTE: This is the initial management interface. Further interfaces can be added.\n# DOCS: https://osism.tech/docs/guides/configuration-guide/network\n\nnetwork_ethernets:\n eno1:\n addresses:\n - "192.168.16.10/20"\n gateway4: "192.168.16.1"\n mtu: 1500\n'})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Kolla section"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="inventory/host_vars/node01.yml"',children:"network_interface: eno1\n\n# api_interface:\n# bifrost_network_interface:\n# dns_interface:\n# kolla_external_vip_interface:\n# migration_interface:\n# neutron_external_interface:\n# octavia_network_interface:\n# storage_interface:\n# tunnel_interface:\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Ceph section"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="inventory/host_vars/node01.yml"',children:"# NOTE: Uncomment this when this node is a part of the Ceph cluster.\n# monitor_address:\n# radosgw_address:\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="inventory/host_vars/node01.yml"',children:"# NOTE: Uncomment this when this node should be a OSD node.\n# DOCS: https://osism.tech/docs/guides/configuration-guide/ceph#lvm-devices\n\n# ceph_osd_devices:\n# sdb:\n# sdc:\n# sdd:\n# sde:\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"dns-servers",children:"DNS servers"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/configuration.yml"',children:"resolvconf_nameserver:\n - 8.8.8.8\n - 9.9.9.9\n"})}),"\n",(0,i.jsx)(n.h4,{id:"ntp-servers",children:"NTP servers"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/configuration.yml"',children:"chrony_servers:\n - 1.de.pool.ntp.org\n - 2.de.pool.ntp.org\n - 3.de.pool.ntp.org\n - 4.de.pool.ntp.org\n"})}),"\n",(0,i.jsx)(n.h4,{id:"certificates",children:"Certificates"}),"\n",(0,i.jsxs)(n.p,{children:["The certificates must be created and added in the configuration repository in the files\n",(0,i.jsx)(n.code,{children:"environments/kolla/certificates/haproxy.pem"})," and ",(0,i.jsx)(n.code,{children:"environments/kolla/certificates/haproxy-internal.pem"}),". Further information in the ",(0,i.jsx)(n.a,{href:"/docs/guides/configuration-guide/loadbalancer",children:"Loadbalancer Configuration Guide"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"If no certificates are to be used, the encryption must be deactivated. This is not\nrecommended."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/kolla/configuration.yml"',children:'kolla_enable_tls_external: "yes"\nkolla_enable_tls_internal: "yes"\n'})}),"\n",(0,i.jsx)(n.h2,{id:"using-latest",children:"Using latest"}),"\n",(0,i.jsxs)(n.p,{children:["If you want to use the latest version, this is done using the ",(0,i.jsx)(n.code,{children:"manager_version"})," parameter. By default,\nthis is always set to the latest stable version."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"manager_version [7.0.0]: latest\n"})}),"\n",(0,i.jsxs)(n.p,{children:["If the ",(0,i.jsx)(n.code,{children:"manager_version"})," parameter is set to ",(0,i.jsx)(n.code,{children:"latest"})," it is also possible to explicitly\nset the ",(0,i.jsx)(n.code,{children:"openstack_version"})," and the ",(0,i.jsx)(n.code,{children:"ceph_version"})," explicitly."]}),"\n",(0,i.jsx)(n.h2,{id:"parameter-reference",children:"Parameter reference"}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Parameter"}),(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Description"}),(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Default"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"ceph_network"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Address range for Ceph's network"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"192.168.16.0/20"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"ceph_version"})}),(0,i.jsxs)(n.td,{style:{textAlign:"left"},children:["The version of Ceph. When using a stable OSISM release (",(0,i.jsx)(n.code,{children:"manager_version != latest"}),"), this value is ignored"]}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"quincy"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"domain"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"The domain used by hostnames"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"osism.xyz"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"fqdn_external"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"External API FQDN"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"api.osism.xyz"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"fqdn_internal"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Internal API FQDN"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"api-int.osism.xyz"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"git_host"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Address of the used Git server"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"github.com"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"git_port"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Port of the used Git server"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"22"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"git_repository"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Path to the git configuration repository"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"YOUR_ORG/YOUR_CONFIGURATION_REPOSITORY"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"git_username"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Username of the git repository"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"git"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"git_version"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Git branch name"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"main"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"ip_external"})}),(0,i.jsxs)(n.td,{style:{textAlign:"left"},children:["The external IP address of the API (resolves to ",(0,i.jsx)(n.code,{children:"fqdn_external"}),")"]}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"192.168.16.254"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"ip_internal"})}),(0,i.jsxs)(n.td,{style:{textAlign:"left"},children:["The internal IP address of the API (resolves to ",(0,i.jsx)(n.code,{children:"fqdn_internal"}),")"]}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"192.168.16.9"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"manager_version"})}),(0,i.jsxs)(n.td,{style:{textAlign:"left"},children:["The version of OSISM. An overview of available OSISM releases can be found ",(0,i.jsx)(n.a,{href:"https://osism.tech/docs/release-notes/",children:"here"})]}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"7.0.4"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"name_server"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Nameserver. Only one nameserver is set here because the query of multiple values in Cookiecutter is weird. Add more nameservers afterward."}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"149.112.112.112"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"ntp_server"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"NTP server. Only one NTP server is set here because the query of multiple values in Cookiecutter is weird. Add more NTP servers afterward."}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"de.pool.ntp.org"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"openstack_version"})}),(0,i.jsxs)(n.td,{style:{textAlign:"left"},children:["The version of OpenStack. When using a stable OSISM release (",(0,i.jsx)(n.code,{children:"manager_version != latest"}),"), this value is ignored"]}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"2023.2"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"project_name"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Name of the configuration repository directory"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"configuration"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"with_ceph"})}),(0,i.jsxs)(n.td,{style:{textAlign:"left"},children:[(0,i.jsx)(n.code,{children:"1"})," to use Ceph, ",(0,i.jsx)(n.code,{children:"0"})," to not use Ceph"]}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"1"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"with_keycloak"})}),(0,i.jsxs)(n.td,{style:{textAlign:"left"},children:[(0,i.jsx)(n.code,{children:"1"})," to prepare Keycloak integration , ",(0,i.jsx)(n.code,{children:"0"})," to not prepare Keycloak integration"]}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"0"})})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"configuration-repository-layout",children:"Configuration repository layout"}),"\n",(0,i.jsxs)(n.p,{children:["A configuration repository always has the same layout. This section describes\nthe content available in a configuration repository. In the section\n",(0,i.jsx)(n.a,{href:"#creating-a-new-configuration-repository",children:"Creating a new configuration repository"})," is the creation\nof a new configuration repository documented."]}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Directory/File"}),(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Description"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"environments"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"inventory"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"netbox"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"optional"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"requirements.txt"})}),(0,i.jsxs)(n.td,{style:{textAlign:"left"},children:["In the ",(0,i.jsx)(n.code,{children:"requirements.txt"})," the necessary dependencies are listed to be able to execute Gilt."]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"gilt.yml"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"Makefile"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"gilt.yaml"})}),(0,i.jsxs)(n.td,{style:{textAlign:"left"},children:[(0,i.jsx)(n.a,{href:"https://gilt.readthedocs.io",children:"Gilt"})," is a Git layering tool. We use Gilt to maintain the image versions, Ansible configuration and scripts within the ",(0,i.jsx)(n.code,{children:"environments/manager"})," directory."]})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"synchronising-the-configuration-repository",children:"Synchronising the configuration repository"}),"\n",(0,i.jsxs)(n.p,{children:["Once the manager has been deployed and the configuration repository has been initially\ntransferred to the manager node, the configuration repository can be updated using\n",(0,i.jsx)(n.code,{children:"osism apply configuration"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"If local changes were made directly in the configuration repository on the manager node,\nthese are overwritten."}),"\n",(0,i.jsx)(n.h2,{id:"locks",children:"Locks"}),"\n",(0,i.jsx)(n.p,{children:"It is possible to lock parts of the configuration repository or the complete configuration\nrepository. It is then no longer possible to execute plays assigned to these parts in the\nlocked parts. This makes it possible to prevent the execution of plays in specific areas."}),"\n",(0,i.jsxs)(n.p,{children:["To lock an environment, a .lock file is created in the corresponding directory of the environment.\nFor example, the file ",(0,i.jsx)(n.code,{children:"environments/kolla/.lock"})," locks the Kolla environment."]}),"\n",(0,i.jsx)(n.p,{children:"If you try to execute a play in the Kolla environment, an error message is displayed."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ osism apply common\n2024-06-02 10:52:44 | INFO | Task 2f25f55f-96ae-4a6c-aeb4-c1c01e716d91 (common) was prepared for execution.\n2024-06-02 10:52:44 | INFO | It takes a moment until task 2f25f55f-96ae-4a6c-aeb4-c1c01e716d91 (common) has been started and output is visible here.\nERROR: The environment kolla is locked via the configuration repository.\n"})}),"\n",(0,i.jsxs)(n.p,{children:["File ",(0,i.jsx)(n.code,{children:"environments/.lock"})," is created to lock everything."]}),"\n",(0,i.jsx)(n.p,{children:"If you try to execute a play, an error message is displayed."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ osism apply facts\n2024-06-02 10:53:08 | INFO | Task 6ac9a526-f88d-4756-bf46-2179636dfb42 (facts) was prepared for execution.\n2024-06-02 10:53:08 | INFO | It takes a moment until task 6ac9a526-f88d-4756-bf46-2179636dfb42 (facts) has been started and output is visible here.\nERROR: The configuration repository is locked.\n"})}),"\n",(0,i.jsx)(n.h2,{id:"working-with-encrypted-files",children:"Working with encrypted files"}),"\n",(0,i.jsx)(n.p,{children:"To make it easier to work with encrypted files, the configuration repository has several make\ntargets that can be used to view encrypted files and to edit encrypted files."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Show secrets in all encrypted files."}),"\n",(0,i.jsxs)(n.p,{children:["This opens a pager, e.g. less, and you can search with ",(0,i.jsx)(n.code,{children:"/"})," for specific files, keys and passwords."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"make ansible_vault_show\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Change or add secrets in an encrypted file with the editor set in ",(0,i.jsx)(n.code,{children:" $EDITOR"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"make ansible_vault_edit FILE=environments/secrets.yml EDITOR=nano\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Re-encrypt all encrypted files with a new key."}),"\n",(0,i.jsxs)(n.p,{children:["This creates a new ",(0,i.jsx)(n.code,{children:"secrets/vaultpass"})," and creates backups of the old to\n",(0,i.jsx)(n.code,{children:"secrets/vaultpass_backup_"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"make ansible_vault_rekey\n"})}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(a,{...e})}):a(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>l,a:()=>o});var i=t(7294);const r={},s=i.createContext(r);function o(e){const n=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/fac2b365.e7b74d5c.js b/assets/js/fac2b365.e7b74d5c.js deleted file mode 100644 index 858a3599c8..0000000000 --- a/assets/js/fac2b365.e7b74d5c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkosism=self.webpackChunkosism||[]).push([[9377],{2201:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>o,default:()=>h,frontMatter:()=>s,metadata:()=>l,toc:()=>c});var i=t(5893),r=t(1151);const s={sidebar_label:"Configuration repository",sidebar_position:10},o="Configuration Repository",l={id:"guides/configuration-guide/configuration-repository",title:"Configuration Repository",description:"The configuration required for an OSISM managed cluster is stored in a single Git",source:"@site/docs/guides/configuration-guide/configuration-repository.md",sourceDirName:"guides/configuration-guide",slug:"/guides/configuration-guide/configuration-repository",permalink:"/docs/guides/configuration-guide/configuration-repository",draft:!1,unlisted:!1,editUrl:"https://github.com/osism/osism.github.io/tree/main/docs/guides/configuration-guide/configuration-repository.md",tags:[],version:"current",sidebarPosition:10,frontMatter:{sidebar_label:"Configuration repository",sidebar_position:10},sidebar:"tutorialSidebar",previous:{title:"Configuration Guide",permalink:"/docs/guides/configuration-guide/"},next:{title:"Inventory",permalink:"/docs/guides/configuration-guide/inventory"}},d={},c=[{value:"Creating a new configuration repository",id:"creating-a-new-configuration-repository",level:2},{value:"Step 1: Preparation",id:"step-1-preparation",level:3},{value:"Step 2: Run Cookiecutter",id:"step-2-run-cookiecutter",level:3},{value:"Step 3: Upload the new configuration to the remote git repository",id:"step-3-upload-the-new-configuration-to-the-remote-git-repository",level:3},{value:"Step 4: Post-processing of the generated configuration",id:"step-4-post-processing-of-the-generated-configuration",level:3},{value:"Secrets",id:"secrets",level:4},{value:"Manager inventory",id:"manager-inventory",level:4},{value:"Global inventory",id:"global-inventory",level:4},{value:"DNS servers",id:"dns-servers",level:4},{value:"NTP servers",id:"ntp-servers",level:4},{value:"Certificates",id:"certificates",level:4},{value:"Using latest",id:"using-latest",level:2},{value:"Parameter reference",id:"parameter-reference",level:2},{value:"Configuration repository layout",id:"configuration-repository-layout",level:2},{value:"Synchronising the configuration repository",id:"synchronising-the-configuration-repository",level:2},{value:"Locks",id:"locks",level:2},{value:"Working with encrypted files",id:"working-with-encrypted-files",level:2}];function a(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"configuration-repository",children:"Configuration Repository"}),"\n",(0,i.jsx)(n.p,{children:"The configuration required for an OSISM managed cluster is stored in a single Git\nmonorepo, the configuration repository."}),"\n",(0,i.jsx)(n.h2,{id:"creating-a-new-configuration-repository",children:"Creating a new configuration repository"}),"\n",(0,i.jsxs)(n.p,{children:["The initial content for this configuration repository is generated using the\n",(0,i.jsx)(n.a,{href:"https://github.com/osism/cfg-cookiecutter",children:"Cookiecutter"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"Cookiecutter generates a simple initial configuration for your new cluster by prompting\nyou for the basic details of the new cluster."}),"\n",(0,i.jsxs)(n.p,{children:["The configuration repository is not created on the future Manager node. It is created on a\nlocal workstation. If the local workstation cannot be used for this purpose, a dedicated\nvirtual system can be used. For more information on this topic, refer to the\n",(0,i.jsx)(n.a,{href:"/docs/guides/deploy-guide/seed",children:"Seed Deploy Guide"}),"."]}),"\n",(0,i.jsx)(n.h3,{id:"step-1-preparation",children:"Step 1: Preparation"}),"\n",(0,i.jsxs)(n.p,{children:["First decide where to store your Git repository The content generated by the cookiecutter in\nthe ",(0,i.jsx)(n.code,{children:"output/configuration"})," directory is committed to a new Git repository. By default, the\nconfiguration repository is assumed to be on GitHub. This can also be GitLab or an internal\nGit service as well."]}),"\n",(0,i.jsxs)(n.p,{children:["Host and path to the Git repository are specified by the ",(0,i.jsx)(n.code,{children:"git_"})," parameters. These are\nrequested in step 2. The ",(0,i.jsx)(n.code,{children:"git_"})," parameters do not specify the path to the cookiecutter\nto use."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:" [8/20] git_host (github.com):\n [9/20] git_port (22):\n [10/20] git_repository (YOUR_ORG/YOUR_NEW_CONFIGURATION_REPOSITORY): regiocloud/configuration\n [11/20] git_username (git):\n [12/20] git_version (main):\n"})}),"\n",(0,i.jsxs)(n.p,{children:["In this case, the generated configuration in the ",(0,i.jsx)(n.code,{children:"output/configuration"})," directory is\nstored on GitHub in the ",(0,i.jsx)(n.code,{children:"regiocloud/configuration"})," repository."]}),"\n",(0,i.jsxs)(n.p,{children:["See the ",(0,i.jsx)(n.a,{href:"#parameter-reference",children:"parameter reference"})," for more details. The parameters\nlisted there will be queried during the execution of Cookiecutter."]}),"\n",(0,i.jsx)(n.h3,{id:"step-2-run-cookiecutter",children:"Step 2: Run Cookiecutter"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["The directory ",(0,i.jsx)(n.code,{children:"output"})," is created and used as output volume. It is only necessary to create the empty\ndirectory here."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"mkdir output\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["The Cookiecutter runs inside a container. ",(0,i.jsx)(n.a,{href:"https://docs.docker.com/engine/install/",children:"Docker must be usable on the system"}),"\nwhere the Cookiecutter will be used. It should also work with Podman."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:'docker run \\\n -e TARGET_UID="$(id -u)" \\\n -e TARGET_GID="$(id -g)" \\\n -v $(pwd)/output:/output \\\n --rm -it quay.io/osism/cookiecutter\n'})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["A few parameters are requested. The parameters are documented in detail in the ",(0,i.jsx)(n.a,{href:"#parameter-reference",children:"parameter reference"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["If you want to use the ",(0,i.jsx)(n.code,{children:"latest"})," version, this is done using the ",(0,i.jsx)(n.code,{children:"manager_version"})," parameter. By default,\nthis is always set to the latest stable version."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"manager_version [7.0.4]: latest\n"})}),"\n",(0,i.jsxs)(n.p,{children:["If the ",(0,i.jsx)(n.code,{children:"manager_version"})," parameter is set to ",(0,i.jsx)(n.code,{children:"latest"})," it is also possible to explicitly\nset the ",(0,i.jsx)(n.code,{children:"openstack_version"})," and the ",(0,i.jsx)(n.code,{children:"ceph_version"})," explicitly."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"[1/19] with_ceph (1):\n[2/19] with_keycloak (0):\n[3/19] ceph_network(192.168.64.0/19):\n[4/19] ceph_version (quincy):\n[5/19] domain (osism.xyz):\n[6/19] fqdn_external (api.osism.xyz):\n[7/19] fqdn_internal (api-int.osism.xyz):\n[8/19] git_host (github.com):\n[9/19] git_port (22):\n[10/19] git_repository (YOUR_ORG/YOUR_NEW_CONFIGURATION_REPOSITORY):\n[11/19] git_username (git):\n[12/19] git_version (main):\n[13/19] ip_external (192.168.96.9):\n[14/19] ip_internal (192.168.32.9):\n[15/19] manager_version (7.0.4):\n[16/19] name_server (149.112.112.112):\n[17/19] ntp_server (de.pool.ntp.org):\n[18/19] openstack_version (2023.2):\n[19/19] project_name (configuration):\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"step-3-upload-the-new-configuration-to-the-remote-git-repository",children:"Step 3: Upload the new configuration to the remote git repository"}),"\n",(0,i.jsxs)(n.p,{children:["Add the initial configuration state to the repository. How to add a deploy key on GitHub is documented in\n",(0,i.jsx)(n.a,{href:"https://docs.github.com/en/authentication/connecting-to-github-with-ssh/managing-deploy-keys",children:"Managing deploy keys"}),".\nRead permissions are sufficient."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:'$ git clone git@github.com:YOUR_ORG/YOUR_NEW_CONFIGURATION_REPOSITORY.git YOUR_NEW_CONFIGURATION_REPOSITORY\n$ cp -r output/configuration/{*,.gitignore} YOUR_NEW_CONFIGURATION_REPOSITORY\n$ cd YOUR_NEW_CONFIGURATION_REPOSITORY\n$ git add -A .\n$ git commit -m "Initial commit after bootstrap"\n$ git push\n'})}),"\n",(0,i.jsx)(n.p,{children:"The content is now committed to the Git repository that was created earlier in the process."}),"\n",(0,i.jsxs)(n.admonition,{type:"warning",children:[(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"secrets"})," directory is not stored in the Git repository. Its contents can be\nstored in a trusted location."]}),(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"secrets"})," directory contains an SSH key pair which is used as the deploy key to\nmake the configuration repository available on the manager node later. Write access\nis not required. The public SSH key is stored in the ",(0,i.jsx)(n.code,{children:"secrets/id_rsa.configuration.pub"})," file."]})]}),"\n",(0,i.jsx)(n.h3,{id:"step-4-post-processing-of-the-generated-configuration",children:"Step 4: Post-processing of the generated configuration"}),"\n",(0,i.jsxs)(n.p,{children:["The configuration repository that is initially created with the Cookiecutter is not immediately usable.\nFor example, the inventory needs to be built. All other information can be found in the\n",(0,i.jsx)(n.a,{href:"../configuration-guide/",children:"Configuration Guide"}),". Use ",(0,i.jsx)(n.code,{children:"git"})," to version all your configuration changes."]}),"\n",(0,i.jsx)(n.p,{children:"The following 6 points must be changed after the initial creation of the configuration repository."}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#secrets",children:"Secrets"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#manager-inventory",children:"Manager inventory"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#global-inventory",children:"Global inventory"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#dns-servers",children:"DNS servers"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#ntp-servers",children:"NTP servers"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#certificates",children:"Certificates"})}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"secrets",children:"Secrets"}),"\n",(0,i.jsxs)(n.p,{children:["The password for Ansible Vault encrypted files, is stored in ",(0,i.jsx)(n.code,{children:"secrets/vaultpass"}),". Since the ",(0,i.jsx)(n.code,{children:"secrets"})," directory\nis not added to the configuration repository, it is important to store it in a password vault of your choice."]}),"\n",(0,i.jsxs)(n.p,{children:["The password of the generated Keepass file is ",(0,i.jsx)(n.code,{children:"password"}),". This should be changed when using the Keepass file.\nIf possible, an existing password vault should be used."]}),"\n",(0,i.jsx)(n.h4,{id:"manager-inventory",children:"Manager inventory"}),"\n",(0,i.jsx)(n.p,{children:"The information required to perform the initial bootstrap of the manager node and the initial\ndeployment of the manager service from the seed Node is provided in the inventory of the manager\nenvironment."}),"\n",(0,i.jsxs)(n.p,{children:["In the Cookiecutter, a node ",(0,i.jsx)(n.code,{children:"node01"})," is defined as an example in the manager inventory as well as\nin the global inventory. The name of this node must be changed to match the name of the node used\nas manager in your own cluster."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Roles"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Manager role"}),"\n",(0,i.jsxs)(n.p,{children:["The name of the node on which the manager service is to be deployed is\nadded to inventory group ",(0,i.jsx)(n.code,{children:"manager"})," in file ",(0,i.jsx)(n.code,{children:"environments/manager/hosts"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["Only the ",(0,i.jsx)(n.code,{children:"manager"})," inventory group is available in ",(0,i.jsx)(n.code,{children:"environments/manager/hosts"}),". There are no\nother groups there."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ini",metastring:'title="environments/manager/hosts"',children:"[manager]\nnode01\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Host vars"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Ansible section"}),"\n",(0,i.jsx)(n.p,{children:"The IP address where the node can be reached via SSH from the manager node. If DHCP is used after the\ninitial provisioning to assign an initial IP address to the nodes, the address assigned via DHCP is\ninitially used here and later changed to the static IP address."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/manager/host_vars/node01.yml"',children:"ansible_host: 192.168.16.10\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Generic section"}),"\n",(0,i.jsx)(n.p,{children:"The network interface on which the internal communication of the cluster will take place. If the\ninternal interface does not yet exist at the time the configuration is created, e.g. because it is a\nbond interface or VLAN interface that is only created by the static network configuration, it can be\nalready used here."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/manager/host_vars/node01.yml"',children:"internal_interface: eno1\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Network section"}),"\n",(0,i.jsxs)(n.p,{children:["The static and complete network configuration of the node. Further details on creating the\nnetwork configuration in the ",(0,i.jsx)(n.a,{href:"../configuration-guide/network",children:"network configuration guide"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/manager/host_vars/node01.yml"',children:'network_ethernets:\n eno1:\n addresses:\n - "192.168.16.10/20"\n gateway4: "192.168.16.1"\n mtu: 1500\n'})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"global-inventory",children:"Global inventory"}),"\n",(0,i.jsxs)(n.p,{children:["In the Cookiecutter, a node ",(0,i.jsx)(n.code,{children:"node01"})," is defined as an example in the manager inventory as well as\nin the global inventory. The name of this node must be changed to match the name of the node used\nas manager in your own cluster."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Roles"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Generic role"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ini",metastring:'title="inventory/20-roles"',children:'# The "all" group is not used in OSISM. Therefore it is important\n# that all nodes are explicitly listed here.\n[generic]\nnode01\n'})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Manager role"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ini",metastring:'title="inventory/20-roles"',children:"# Nodes that act as manager (sometimes called deployment node)\n# are included in this group.\n[manager]\nnode01\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Monitoring role"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ini",metastring:'title="inventory/20-roles"',children:"# Nodes which are intended for monitoring services belong to\n# this group\n[monitoring]\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Control role"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ini",metastring:'title="inventory/20-roles"',children:"# Nodes that serve as controllers, so things like scheduler,\n# API or database run there, of the environment.\n[control]\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Compute role"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ini",metastring:'title="inventory/20-roles"',children:"# Virtual systems managed by OpenStack Nova are placed on\n# nodes in this group.\n[compute]\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Network role"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ini",metastring:'title="inventory/20-roles"',children:"# Network resources managed by OpenStack Neutron, such as\n# L3 routers, are placed on these nodes. This group has nothing\n# to do with the general network configuration.\n[network]\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Ceph control role"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ini",metastring:'title="inventory/20-roles"',children:"# Nodes that serve as controllers for Ceph, so things like the\n# Ceph Monitor service run here.\n[ceph-control]\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Ceph resource role"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ini",metastring:'title="inventory/20-roles"',children:"# The storage available in these systems is provided in the\n# form of OSDs for Ceph.\n[ceph-resource]\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Ceph rgw role"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ini",metastring:'title="inventory/20-roles"',children:"[ceph-rgw:children]\nceph-control\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Host vars"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Ansible section"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="inventory/host_vars/node01.yml"',children:"# NOTE: Address where the node can be reached via SSH.\nansible_host: 192.168.16.10\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Generic section"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="inventory/host_vars/node01.yml"',children:"internal_interface: eno1\n\n# NOTE: The address of the internal interface.\ninternal_address: 192.168.16.10\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Netdata section"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="inventory/host_vars/node01.yml"',children:"netdata_host_type: client\n\n# NOTE: Uncomment this when this node should be a Netdata server.\n# netdata_host_type: server\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Network section"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="inventory/host_vars/node01.yml"',children:'# NOTE: This is the initial management interface. Further interfaces can be added.\n# DOCS: https://osism.tech/docs/guides/configuration-guide/network\n\nnetwork_ethernets:\n eno1:\n addresses:\n - "192.168.16.10/20"\n gateway4: "192.168.16.1"\n mtu: 1500\n'})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Kolla section"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="inventory/host_vars/node01.yml"',children:"network_interface: eno1\n\n# api_interface:\n# bifrost_network_interface:\n# dns_interface:\n# kolla_external_vip_interface:\n# migration_interface:\n# neutron_external_interface:\n# octavia_network_interface:\n# storage_interface:\n# tunnel_interface:\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Ceph section"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="inventory/host_vars/node01.yml"',children:"# NOTE: Uncomment this when this node is a part of the Ceph cluster.\n# monitor_address:\n# radosgw_address:\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="inventory/host_vars/node01.yml"',children:"# NOTE: Uncomment this when this node should be a OSD node.\n# DOCS: https://osism.tech/docs/guides/configuration-guide/ceph#lvm-devices\n\n# ceph_osd_devices:\n# sdb:\n# sdc:\n# sdd:\n# sde:\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"dns-servers",children:"DNS servers"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/configuration.yml"',children:"resolvconf_nameserver:\n - 8.8.8.8\n - 9.9.9.9\n"})}),"\n",(0,i.jsx)(n.h4,{id:"ntp-servers",children:"NTP servers"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/configuration.yml"',children:"chrony_servers:\n - 1.de.pool.ntp.org\n - 2.de.pool.ntp.org\n - 3.de.pool.ntp.org\n - 4.de.pool.ntp.org\n"})}),"\n",(0,i.jsx)(n.h4,{id:"certificates",children:"Certificates"}),"\n",(0,i.jsxs)(n.p,{children:["The certificates must be created and added in the configuration repository in the files\n",(0,i.jsx)(n.code,{children:"environments/kolla/certificates/haproxy.pem"})," and ",(0,i.jsx)(n.code,{children:"environments/kolla/certificates/haproxy-internal.pem"}),". Further information in the ",(0,i.jsx)(n.a,{href:"/docs/guides/configuration-guide/loadbalancer",children:"Loadbalancer Configuration Guide"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"If no certificates are to be used, the encryption must be deactivated. This is not\nrecommended."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/kolla/configuration.yml"',children:'kolla_enable_tls_external: "yes"\nkolla_enable_tls_internal: "yes"\n'})}),"\n",(0,i.jsx)(n.h2,{id:"using-latest",children:"Using latest"}),"\n",(0,i.jsxs)(n.p,{children:["If you want to use the latest version, this is done using the ",(0,i.jsx)(n.code,{children:"manager_version"})," parameter. By default,\nthis is always set to the latest stable version."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"manager_version [7.0.0]: latest\n"})}),"\n",(0,i.jsxs)(n.p,{children:["If the ",(0,i.jsx)(n.code,{children:"manager_version"})," parameter is set to ",(0,i.jsx)(n.code,{children:"latest"})," it is also possible to explicitly\nset the ",(0,i.jsx)(n.code,{children:"openstack_version"})," and the ",(0,i.jsx)(n.code,{children:"ceph_version"})," explicitly."]}),"\n",(0,i.jsx)(n.h2,{id:"parameter-reference",children:"Parameter reference"}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Parameter"}),(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Description"}),(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Default"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"ceph_network"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Address range for Ceph's network"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"192.168.64.0/20"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"ceph_version"})}),(0,i.jsxs)(n.td,{style:{textAlign:"left"},children:["The version of Ceph. When using a stable OSISM release (",(0,i.jsx)(n.code,{children:"manager_version != latest"}),"), this value is ignored"]}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"quincy"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"domain"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"The domain used by hostnames"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"osism.xyz"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"fqdn_external"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"External API FQDN"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"api.osism.xyz"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"fqdn_internal"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Internal API FQDN"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"api-int.osism.xyz"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"git_host"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Address of the used Git server"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"github.com"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"git_port"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Port of the used Git server"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"22"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"git_repository"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Path to the git configuration repository"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"YOUR_ORG/YOUR_CONFIGURATION_REPOSITORY"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"git_username"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Username of the git repository"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"git"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"git_version"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Git branch name"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"main"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"ip_external"})}),(0,i.jsxs)(n.td,{style:{textAlign:"left"},children:["The external IP address of the API (resolves to ",(0,i.jsx)(n.code,{children:"fqdn_external"}),")"]}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"192.168.96.9"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"ip_internal"})}),(0,i.jsxs)(n.td,{style:{textAlign:"left"},children:["The internal IP address of the API (resolves to ",(0,i.jsx)(n.code,{children:"fqdn_internal"}),")"]}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"192.168.32.9"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"manager_version"})}),(0,i.jsxs)(n.td,{style:{textAlign:"left"},children:["The version of OSISM. An overview of available OSISM releases can be found ",(0,i.jsx)(n.a,{href:"https://osism.tech/docs/release-notes/",children:"here"})]}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"7.0.4"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"name_server"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Nameserver. Only one nameserver is set here because the query of multiple values in Cookiecutter is weird. Add more nameservers afterward."}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"149.112.112.112"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"ntp_server"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"NTP server. Only one NTP server is set here because the query of multiple values in Cookiecutter is weird. Add more NTP servers afterward."}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"de.pool.ntp.org"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"openstack_version"})}),(0,i.jsxs)(n.td,{style:{textAlign:"left"},children:["The version of OpenStack. When using a stable OSISM release (",(0,i.jsx)(n.code,{children:"manager_version != latest"}),"), this value is ignored"]}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"2023.2"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"project_name"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Name of the configuration repository directory"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"configuration"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"with_ceph"})}),(0,i.jsxs)(n.td,{style:{textAlign:"left"},children:[(0,i.jsx)(n.code,{children:"1"})," to use Ceph, ",(0,i.jsx)(n.code,{children:"0"})," to not use Ceph"]}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"1"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"with_keycloak"})}),(0,i.jsxs)(n.td,{style:{textAlign:"left"},children:[(0,i.jsx)(n.code,{children:"1"})," to prepare Keycloak integration , ",(0,i.jsx)(n.code,{children:"0"})," to not prepare Keycloak integration"]}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"0"})})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"configuration-repository-layout",children:"Configuration repository layout"}),"\n",(0,i.jsxs)(n.p,{children:["A configuration repository always has the same layout. This section describes\nthe content available in a configuration repository. In the section\n",(0,i.jsx)(n.a,{href:"#creating-a-new-configuration-repository",children:"Creating a new configuration repository"})," is the creation\nof a new configuration repository documented."]}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Directory/File"}),(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Description"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"environments"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"inventory"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"netbox"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"optional"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"requirements.txt"})}),(0,i.jsxs)(n.td,{style:{textAlign:"left"},children:["In the ",(0,i.jsx)(n.code,{children:"requirements.txt"})," the necessary dependencies are listed to be able to execute Gilt."]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"gilt.yml"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"Makefile"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"gilt.yaml"})}),(0,i.jsxs)(n.td,{style:{textAlign:"left"},children:[(0,i.jsx)(n.a,{href:"https://gilt.readthedocs.io",children:"Gilt"})," is a Git layering tool. We use Gilt to maintain the image versions, Ansible configuration and scripts within the ",(0,i.jsx)(n.code,{children:"environments/manager"})," directory."]})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"synchronising-the-configuration-repository",children:"Synchronising the configuration repository"}),"\n",(0,i.jsxs)(n.p,{children:["Once the manager has been deployed and the configuration repository has been initially\ntransferred to the manager node, the configuration repository can be updated using\n",(0,i.jsx)(n.code,{children:"osism apply configuration"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"If local changes were made directly in the configuration repository on the manager node,\nthese are overwritten."}),"\n",(0,i.jsx)(n.h2,{id:"locks",children:"Locks"}),"\n",(0,i.jsx)(n.p,{children:"It is possible to lock parts of the configuration repository or the complete configuration\nrepository. It is then no longer possible to execute plays assigned to these parts in the\nlocked parts. This makes it possible to prevent the execution of plays in specific areas."}),"\n",(0,i.jsxs)(n.p,{children:["To lock an environment, a .lock file is created in the corresponding directory of the environment.\nFor example, the file ",(0,i.jsx)(n.code,{children:"environments/kolla/.lock"})," locks the Kolla environment."]}),"\n",(0,i.jsx)(n.p,{children:"If you try to execute a play in the Kolla environment, an error message is displayed."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ osism apply common\n2024-06-02 10:52:44 | INFO | Task 2f25f55f-96ae-4a6c-aeb4-c1c01e716d91 (common) was prepared for execution.\n2024-06-02 10:52:44 | INFO | It takes a moment until task 2f25f55f-96ae-4a6c-aeb4-c1c01e716d91 (common) has been started and output is visible here.\nERROR: The environment kolla is locked via the configuration repository.\n"})}),"\n",(0,i.jsxs)(n.p,{children:["File ",(0,i.jsx)(n.code,{children:"environments/.lock"})," is created to lock everything."]}),"\n",(0,i.jsx)(n.p,{children:"If you try to execute a play, an error message is displayed."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ osism apply facts\n2024-06-02 10:53:08 | INFO | Task 6ac9a526-f88d-4756-bf46-2179636dfb42 (facts) was prepared for execution.\n2024-06-02 10:53:08 | INFO | It takes a moment until task 6ac9a526-f88d-4756-bf46-2179636dfb42 (facts) has been started and output is visible here.\nERROR: The configuration repository is locked.\n"})}),"\n",(0,i.jsx)(n.h2,{id:"working-with-encrypted-files",children:"Working with encrypted files"}),"\n",(0,i.jsx)(n.p,{children:"To make it easier to work with encrypted files, the configuration repository has several make\ntargets that can be used to view encrypted files and to edit encrypted files."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Show secrets in all encrypted files."}),"\n",(0,i.jsxs)(n.p,{children:["This opens a pager, e.g. less, and you can search with ",(0,i.jsx)(n.code,{children:"/"})," for specific files, keys and passwords."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"make ansible_vault_show\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Change or add secrets in an encrypted file with the editor set in ",(0,i.jsx)(n.code,{children:" $EDITOR"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"make ansible_vault_edit FILE=environments/secrets.yml EDITOR=nano\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Re-encrypt all encrypted files with a new key."}),"\n",(0,i.jsxs)(n.p,{children:["This creates a new ",(0,i.jsx)(n.code,{children:"secrets/vaultpass"})," and creates backups of the old to\n",(0,i.jsx)(n.code,{children:"secrets/vaultpass_backup_"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"make ansible_vault_rekey\n"})}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(a,{...e})}):a(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>l,a:()=>o});var i=t(7294);const r={},s=i.createContext(r);function o(e){const n=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/main.46b39d4c.js b/assets/js/main.46b39d4c.js deleted file mode 100644 index 92e12642be..0000000000 --- a/assets/js/main.46b39d4c.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! For license information please see main.46b39d4c.js.LICENSE.txt */ -(self.webpackChunkosism=self.webpackChunkosism||[]).push([[179],{723:(e,t,n)=>{"use strict";n.d(t,{Z:()=>p});n(7294);var r=n(8356),o=n.n(r),i=n(6887);const a={"0058b4c6":[()=>n.e(4088).then(n.t.bind(n,6462,19)),"@generated/docusaurus-plugin-content-docs/default/p/docs-175.json",6462],"0152cb28":[()=>n.e(6838).then(n.bind(n,3330)),"@site/docs/guides/troubleshooting-guide/ceph.md",3330],"01a85c17":[()=>Promise.all([n.e(532),n.e(4013)]).then(n.bind(n,1223)),"@theme/BlogTagsListPage",1223],"02385e42":[()=>n.e(7147).then(n.bind(n,9723)),"@site/docs/guides/operations-guide/manager/get.md",9723],"02601e42":[()=>n.e(6236).then(n.bind(n,5259)),"@site/docs/guides/upgrade-guide/index.md",5259],"04276aea":[()=>n.e(9863).then(n.bind(n,3142)),"@site/docs/guides/operations-guide/openstack/tools/resource-manager.md",3142],"06fc275a":[()=>n.e(6759).then(n.bind(n,6428)),"@site/docs/guides/configuration-guide/openstack/skyline.md",6428],"076173c3":[()=>n.e(7471).then(n.bind(n,4128)),"@site/docs/guides/concept-guide/components/teleport.md",4128],"07742d97":[()=>n.e(6876).then(n.bind(n,9725)),"@site/docs/references/index.md",9725],"07d5b948":[()=>n.e(6299).then(n.bind(n,9270)),"@site/docs/guides/configuration-guide/openstack/keystone.md",9270],"08ca43f3":[()=>n.e(5655).then(n.bind(n,5965)),"@site/docs/guides/operations-guide/ceph.md",5965],"08d2a106":[()=>n.e(7559).then(n.bind(n,4967)),"@site/blog/2024-03-04-show-versions-used-on-the-manager.md?truncated=true",4967],"096c7093":[()=>n.e(5834).then(n.bind(n,9980)),"@site/docs/guides/configuration-guide/commons/sshconfig.md",9980],"09a97616":[()=>n.e(8367).then(n.bind(n,7490)),"@site/docs/guides/upgrade-guide/logging-monitoring.md",7490],"09ec98ee":[()=>n.e(6454).then(n.bind(n,7033)),"@site/docs/guides/upgrade-guide/docker.md",7033],"0a3aead7":[()=>n.e(5571).then(n.bind(n,4908)),"@site/docs/guides/concept-guide/components/proxmox.md",4908],"0c9d79ac":[()=>n.e(1527).then(n.bind(n,5859)),"@site/docs/guides/concept-guide/components/ironic.md",5859],"0dedd17d":[()=>n.e(8059).then(n.bind(n,6207)),"@site/blog/2024-01-11-kubernetes-service-deployments.md",6207],"0e2caa6c":[()=>n.e(2175).then(n.bind(n,9732)),"@site/docs/guides/user-guide/openstack/index.md",9732],"0f52743c":[()=>n.e(6891).then(n.bind(n,8064)),"@site/docs/guides/troubleshooting-guide/index.md",8064],"0fd4c4b6":[()=>n.e(2309).then(n.bind(n,5901)),"@site/docs/appendix/index.md",5901],"122bda60":[()=>n.e(2827).then(n.bind(n,9449)),"@site/users/index.md",9449],"138e0e15":[()=>n.e(9524).then(n.t.bind(n,536,19)),"@generated/@easyops-cn/docusaurus-search-local/default/__plugin.json",536],"1541925c":[()=>n.e(8470).then(n.bind(n,1263)),"@site/docs/guides/configuration-guide/commons/certificates.md",1263],"15cba8f7":[()=>n.e(8019).then(n.bind(n,1082)),"@site/docs/guides/upgrade-guide/ceph.md",1082],"1660505f":[()=>n.e(1021).then(n.bind(n,4137)),"@site/docs/guides/deploy-guide/services/kubernetes.md",4137],17896441:[()=>Promise.all([n.e(532),n.e(2802),n.e(7918)]).then(n.bind(n,7362)),"@theme/DocItem",7362],"1a4e3797":[()=>Promise.all([n.e(532),n.e(7920)]).then(n.bind(n,1473)),"@theme/SearchPage",1473],"1e083c96":[()=>n.e(2346).then(n.bind(n,4663)),"@site/docs/guides/configuration-guide/openstack/cinder.md",4663],"1e80d022":[()=>n.e(3713).then(n.bind(n,8897)),"@site/docs/guides/upgrade-guide/infrastructure.md",8897],"1f001b6c":[()=>n.e(6881).then(n.bind(n,6961)),"@site/docs/guides/concept-guide/hardware-bom.md",6961],"1f2df234":[()=>n.e(784).then(n.bind(n,7225)),"@site/docs/guides/concept-guide/components/sonic.md",7225],"1f391b9e":[()=>Promise.all([n.e(532),n.e(2802),n.e(3085)]).then(n.bind(n,4247)),"@theme/MDXPage",4247],"23082d39":[()=>n.e(7927).then(n.bind(n,6134)),"@site/docs/guides/user-guide/index.md",6134],"23ead882":[()=>n.e(9619).then(n.bind(n,8966)),"@site/docs/guides/concept-guide/nodes.md",8966],"25d1f3de":[()=>n.e(9684).then(n.t.bind(n,9638,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-tags-kubernetes-bf9.json",9638],"29cf976d":[()=>n.e(2840).then(n.bind(n,391)),"@site/docs/release-notes/index.md",391],"2b48164f":[()=>n.e(5348).then(n.bind(n,2737)),"@site/docs/guides/other-guides/developer-guide/zuul.md",2737],"2b5b0fc4":[()=>n.e(2753).then(n.bind(n,5853)),"@site/docs/guides/deploy-guide/services/network.md",5853],"2c0b3ec5":[()=>n.e(9372).then(n.bind(n,8304)),"@site/docs/guides/configuration-guide/openstack/index.md",8304],"2c0fb91b":[()=>n.e(8129).then(n.bind(n,4133)),"@site/docs/guides/configuration-guide/openstack/ceilometer.md",4133],"2c9eb223":[()=>n.e(4596).then(n.t.bind(n,8006,19)),"@generated/docusaurus-plugin-content-docs/users/p/users-f19.json",8006],"30678d1f":[()=>n.e(5429).then(n.bind(n,6705)),"@site/docs/guides/concept-guide/components/k3s.md",6705],"31da1720":[()=>n.e(7720).then(n.bind(n,6777)),"@site/docs/guides/configuration-guide/commons/sysctl.md",6777],"31f6c2ce":[()=>n.e(1296).then(n.bind(n,1888)),"@site/docs/guides/operations-guide/infrastructure.md",1888],"326f19e1":[()=>n.e(9183).then(n.bind(n,7868)),"@site/docs/guides/operations-guide/manager/task.md",7868],"32b5e35d":[()=>n.e(543).then(n.t.bind(n,7852,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-tags-machine-room-a61.json",7852],"36994c47":[()=>n.e(9208).then(n.t.bind(n,4468,19)),"@generated/docusaurus-plugin-content-blog/default/__plugin.json",4468],"3a24b32a":[()=>n.e(1033).then(n.bind(n,5683)),"@site/docs/guides/deploy-guide/examples/cloud-in-a-box.md",5683],"3a2db09e":[()=>n.e(9361).then(n.t.bind(n,7588,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-tags-df9.json",7588],"3e0c15c2":[()=>n.e(3422).then(n.bind(n,2914)),"@site/docs/guides/configuration-guide/services/tuned.md",2914],"3e23a1eb":[()=>n.e(6018).then(n.bind(n,2210)),"@site/docs/guides/operations-guide/openstack/tools/image-manager/update.md",2210],"3eec1f83":[()=>n.e(6315).then(n.bind(n,6603)),"@site/docs/references/parameters.md",6603],"3f74a1dc":[()=>n.e(770).then(n.bind(n,6985)),"@site/docs/guides/deploy-guide/examples/index.md",6985],"40dee973":[()=>n.e(7383).then(n.bind(n,2149)),"@site/docs/guides/configuration-guide/openstack/nova.md",2149],41052329:[()=>n.e(3736).then(n.bind(n,6740)),"@site/docs/guides/user-guide/openstack/security-groups.md",6740],"42bbc814":[()=>n.e(8730).then(n.bind(n,6579)),"@site/docs/guides/deploy-guide/index.md",6579],"445e7840":[()=>n.e(719).then(n.bind(n,4922)),"@site/src/pages/terms.md",4922],"456706c7":[()=>n.e(9174).then(n.bind(n,2087)),"@site/docs/references/cli.md",2087],"45fcaf07":[()=>n.e(8527).then(n.bind(n,6079)),"@site/docs/guides/other-guides/developer-guide/releases.md",6079],"4632ab68":[()=>n.e(8521).then(n.bind(n,6422)),"@site/docs/guides/operations-guide/manager/log.md",6422],"49278f49":[()=>n.e(7485).then(n.bind(n,516)),"@site/docs/guides/deploy-guide/examples/testbed.md",516],"4e4d7fb4":[()=>n.e(6785).then(n.bind(n,8030)),"@site/docs/guides/configuration-guide/openstack/octavia.md",8030],"4f033264":[()=>n.e(8449).then(n.t.bind(n,2494,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-tags-news-c62.json",2494],"4f960b61":[()=>n.e(7129).then(n.bind(n,8941)),"@site/blog/2024-01-14-use-of-the-clustershell.md?truncated=true",8941],"5334e6e2":[()=>n.e(2959).then(n.bind(n,328)),"@site/docs/guides/concept-guide/components/gardener.md",328],"53e951cd":[()=>n.e(3619).then(n.bind(n,6860)),"@site/blog/2024-01-11-kubernetes-service-deployments.md?truncated=true",6860],"540b269b":[()=>n.e(741).then(n.bind(n,7744)),"@site/docs/appendix/networks.md",7744],"555bfc08":[()=>n.e(2421).then(n.bind(n,6114)),"@site/docs/guides/operations-guide/openstack/tools/simple-stress.md",6114],"558d4eb6":[()=>n.e(3586).then(n.bind(n,8949)),"@site/docs/guides/concept-guide/index.md",8949],"56285d35":[()=>n.e(324).then(n.bind(n,6529)),"@site/docs/guides/configuration-guide/openstack/ironic.md",6529],"56c0df94":[()=>n.e(3674).then(n.bind(n,6366)),"@site/docs/guides/configuration-guide/commons/resolvconf.md",6366],"56dcce74":[()=>n.e(1008).then(n.bind(n,1185)),"@site/docs/guides/configuration-guide/openstack/glance.md",1185],"5845507f":[()=>n.e(4022).then(n.bind(n,8981)),"@site/docs/guides/other-guides/developer-guide/index.md",8981],"58ecd069":[()=>n.e(3360).then(n.bind(n,9150)),"@site/docs/guides/other-guides/cloud-in-a-box.md",9150],"596b1512":[()=>n.e(3724).then(n.bind(n,2404)),"@site/docs/guides/troubleshooting-guide/manager.md",2404],"59e4bf9a":[()=>n.e(4118).then(n.bind(n,4110)),"@site/docs/guides/configuration-guide/commons/services.md",4110],"5e95c892":[()=>n.e(9661).then(n.bind(n,1892)),"@theme/DocsRoot",1892],"5e9f5e1a":[()=>Promise.resolve().then(n.bind(n,6809)),"@generated/docusaurus.config",6809],"5f732743":[()=>n.e(6899).then(n.bind(n,7046)),"@site/docs/guides/operations-guide/openstack/tools/index.md",7046],"6235e5b8":[()=>Promise.all([n.e(532),n.e(9705)]).then(n.bind(n,5675)),"@site/docs/guides/other-guides/testbed.mdx",5675],"6875c492":[()=>Promise.all([n.e(532),n.e(2802),n.e(7534),n.e(8610)]).then(n.bind(n,1714)),"@theme/BlogTagsPostsPage",1714],"6a128ecd":[()=>n.e(332).then(n.bind(n,4046)),"@site/blog/2024-01-16-use-of-the-container-shell.md",4046],"6a4596fc":[()=>n.e(7958).then(n.bind(n,3491)),"@site/docs/guides/configuration-guide/loadbalancer.md",3491],"6a846528":[()=>n.e(8567).then(n.bind(n,8438)),"@site/docs/guides/operations-guide/openstack/nova.md",8438],"6c4a3323":[()=>n.e(2517).then(n.bind(n,5263)),"@site/docs/guides/user-guide/openstack/openstackclient.md",5263],"6f6bf91f":[()=>n.e(9654).then(n.bind(n,9192)),"@site/docs/guides/troubleshooting-guide/openstack.md",9192],"6fb2b956":[()=>n.e(3216).then(n.bind(n,675)),"@site/docs/guides/configuration-guide/openstack/horizon.md",675],"72d2a3c8":[()=>n.e(968).then(n.bind(n,4414)),"@site/docs/guides/concept-guide/design.md",4414],"7373ea57":[()=>n.e(9606).then(n.bind(n,1299)),"@site/docs/guides/configuration-guide/openstack/barbican.md",1299],"74b846e2":[()=>n.e(7155).then(n.bind(n,4300)),"@site/docs/guides/operations-guide/manager/index.md",4300],"762b083e":[()=>n.e(4931).then(n.bind(n,3343)),"@site/docs/guides/operations-guide/openstack/cinder.md",3343],"76993c56":[()=>Promise.all([n.e(532),n.e(2810)]).then(n.bind(n,4898)),"@site/docs/guides/configuration-guide/manager.mdx",4898],"78b4ae99":[()=>n.e(2681).then(n.bind(n,3112)),"@site/docs/guides/operations-guide/openstack/octavia.md",3112],"7b04d9ab":[()=>n.e(9691).then(n.bind(n,922)),"@site/docs/guides/concept-guide/components/ceph.md",922],"7c20fa24":[()=>n.e(7140).then(n.bind(n,5606)),"@site/blog/2024-03-04-show-versions-used-on-the-manager.md",5606],"7c2d5d83":[()=>n.e(4905).then(n.bind(n,8407)),"@site/docs/guides/other-guides/index.md",8407],"7c8812f6":[()=>n.e(2253).then(n.bind(n,3534)),"@site/docs/guides/configuration-guide/openstack/manila.md",3534],"7d4b540d":[()=>n.e(8321).then(n.bind(n,908)),"@site/blog/2024-01-12-restart-of-a-container-on-a-specific-node.md?truncated=true",908],"7ff15f27":[()=>n.e(4032).then(n.bind(n,8713)),"@site/blog/2024-01-12-restart-of-a-container-on-a-specific-node.md",8713],"807e695f":[()=>n.e(1628).then(n.bind(n,2630)),"@site/docs/guides/deploy-guide/services/logging-monitoring.md",2630],"810171c5":[()=>n.e(1674).then(n.bind(n,754)),"@site/docs/guides/operations-guide/openstack/neutron.md",754],"814f3328":[()=>n.e(2535).then(n.t.bind(n,5641,19)),"~blog/default/blog-post-list-prop-default.json",5641],"8352bc95":[()=>n.e(3980).then(n.bind(n,450)),"@site/docs/guides/configuration-guide/ceph.md",450],"87ff8807":[()=>n.e(6636).then(n.bind(n,6761)),"@site/docs/guides/concept-guide/components/netdata.md",6761],"88884f83":[()=>n.e(2540).then(n.bind(n,9654)),"@site/docs/appendix/glossary.md",9654],"8c451eb7":[()=>n.e(1223).then(n.bind(n,5751)),"@site/blog/2024-01-14-use-of-the-clustershell.md",5751],"8da03187":[()=>n.e(3394).then(n.bind(n,7309)),"@site/docs/guides/deploy-guide/services/infrastructure.md",7309],"8e33b65d":[()=>n.e(9052).then(n.bind(n,1312)),"@site/src/pages/privacy.md",1312],"8e5f32ed":[()=>n.e(1748).then(n.bind(n,526)),"@site/docs/guides/configuration-guide/commons/index.md",526],"8ff7deab":[()=>n.e(8187).then(n.bind(n,6567)),"@site/docs/references/configuration.md",6567],"9008e2e2":[()=>n.e(9061).then(n.bind(n,1612)),"@site/docs/guides/operations-guide/openstack/tools/image-manager/index.md",1612],90342430:[()=>n.e(6378).then(n.bind(n,569)),"@site/docs/guides/other-guides/contributor-guide.md",569],"95c58dad":[()=>n.e(5962).then(n.bind(n,2689)),"@site/blog/2024-01-16-switch-to-opentofu.md?truncated=true",2689],"9731ed60":[()=>n.e(2471).then(n.bind(n,1939)),"@site/src/pages/contact-us.md",1939],"97ec1344":[()=>n.e(8445).then(n.bind(n,9233)),"@site/docs/guides/configuration-guide/openstack/designate.md",9233],"9a9ff86d":[()=>n.e(9877).then(n.bind(n,9883)),"@site/docs/guides/configuration-guide/services/chrony.md",9883],"9e4087bc":[()=>n.e(3608).then(n.bind(n,3169)),"@theme/BlogArchivePage",3169],"9f9f68f7":[()=>n.e(779).then(n.bind(n,8835)),"@site/docs/guides/operations-guide/openstack/tools/project-manager.md",8835],a1f2ef26:[()=>n.e(1067).then(n.bind(n,7697)),"@site/blog/2024-01-16-switch-to-opentofu.md",7697],a3144996:[()=>n.e(2221).then(n.bind(n,955)),"@site/docs/guides/configuration-guide/openstack/neutron.md",955],a4e0d55c:[()=>n.e(8317).then(n.bind(n,7338)),"@site/blog/2024-01-16-use-of-the-container-shell.md?truncated=true",7338],a6659507:[()=>n.e(9498).then(n.bind(n,4362)),"@site/docs/guides/operations-guide/openstack/index.md",4362],a6aa9e1f:[()=>Promise.all([n.e(532),n.e(2802),n.e(7534),n.e(3089)]).then(n.bind(n,4351)),"@theme/BlogListPage",4351],a7017fd1:[()=>n.e(7397).then(n.bind(n,7848)),"@site/docs/guides/configuration-guide/openstack/heat.md",7848],a7456010:[()=>n.e(5980).then(n.t.bind(n,9365,19)),"@generated/docusaurus-plugin-content-pages/default/__plugin.json",9365],a7bd4aaa:[()=>n.e(8518).then(n.bind(n,8564)),"@theme/DocVersionRoot",8564],a7c5002b:[()=>n.e(2968).then(n.bind(n,8479)),"@site/docs/guides/concept-guide/components/openstack.md",8479],a94703ab:[()=>Promise.all([n.e(532),n.e(4368)]).then(n.bind(n,2674)),"@theme/DocRoot",2674],aba21aa0:[()=>n.e(3629).then(n.t.bind(n,1765,19)),"@generated/docusaurus-plugin-content-docs/default/__plugin.json",1765],acecf23e:[()=>n.e(7393).then(n.t.bind(n,1838,19)),"~blog/default/blogMetadata-default.json",1838],ae934d1a:[()=>n.e(1943).then(n.bind(n,969)),"@site/docs/guides/deploy-guide/manager.md",969],b30c80d2:[()=>n.e(7682).then(n.bind(n,8661)),"@site/docs/guides/configuration-guide/validations/index.md",8661],b3cc9666:[()=>n.e(5238).then(n.bind(n,9573)),"@site/docs/guides/concept-guide/components/keycloak.md",9573],b4b93543:[()=>n.e(4689).then(n.bind(n,6418)),"@site/docs/appendix/standards.md",6418],b68de40d:[()=>n.e(6641).then(n.bind(n,3906)),"@site/docs/guides/deploy-guide/provisioning.md",3906],b798ea2b:[()=>n.e(4744).then(n.bind(n,2407)),"@site/docs/guides/operations-guide/manager/apply.md",2407],b89e0d93:[()=>n.e(698).then(n.t.bind(n,9607,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-tags-osism-c1d.json",9607],bb89255b:[()=>n.e(2695).then(n.bind(n,2164)),"@site/docs/guides/concept-guide/use-cases.md",2164],bd14d84e:[()=>n.e(5109).then(n.bind(n,1089)),"@site/docs/guides/configuration-guide/openstack/aodh.md",1089],bd92db3a:[()=>n.e(1594).then(n.bind(n,1693)),"@site/docs/guides/operations-guide/openstack/tools/openstack-health-monitor.md",1693],bde6240a:[()=>n.e(9830).then(n.bind(n,967)),"@site/docs/guides/concept-guide/components/index.md",967],bed2b685:[()=>n.e(4488).then(n.bind(n,5550)),"@site/docs/guides/configuration-guide/commons/timezone.md",5550],c15d9823:[()=>n.e(6642).then(n.t.bind(n,2506,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-bd9.json",2506],c30598cf:[()=>n.e(2684).then(n.bind(n,5959)),"@site/src/pages/jobs.md",5959],c377a04b:[()=>n.e(6971).then(n.bind(n,8463)),"@site/docs/index.md",8463],c45d899e:[()=>n.e(2018).then(n.bind(n,1450)),"@site/docs/guides/deploy-guide/seed.md",1450],c4f5d8e4:[()=>Promise.all([n.e(532),n.e(4195)]).then(n.bind(n,752)),"@site/src/pages/index.js",752],c7384a82:[()=>n.e(5864).then(n.bind(n,8300)),"@site/docs/guides/operations-guide/openstack/tools/flavor-manager.md",8300],c78af355:[()=>n.e(5322).then(n.bind(n,6662)),"@site/docs/guides/configuration-guide/index.md",6662],c9821a2e:[()=>n.e(9246).then(n.bind(n,4009)),"@site/docs/guides/configuration-guide/proxy.md",4009],ccc45f31:[()=>n.e(1100).then(n.bind(n,7004)),"@site/docs/guides/configuration-guide/services/index.md",7004],ccc49370:[()=>Promise.all([n.e(532),n.e(2802),n.e(7534),n.e(6103)]).then(n.bind(n,9209)),"@theme/BlogPostPage",9209],ccee9b10:[()=>n.e(4283).then(n.bind(n,2788)),"@site/src/pages/about-us.md",2788],ce8be473:[()=>n.e(6497).then(n.bind(n,4778)),"@site/docs/guides/configuration-guide/openstack/placement.md",4778],ced2dfef:[()=>n.e(1361).then(n.bind(n,2515)),"@site/docs/guides/concept-guide/layers.md",2515],cf1d2b40:[()=>n.e(5698).then(n.bind(n,7869)),"@site/docs/guides/operations-guide/openstack/keystone.md",7869],cfb372b1:[()=>n.e(3252).then(n.bind(n,3642)),"@site/docs/guides/operations-guide/openstack/tools/sandbox-manager.md",3642],d03241c9:[()=>n.e(2871).then(n.bind(n,5846)),"@site/docs/guides/index.md",5846],d0703ff7:[()=>n.e(6931).then(n.t.bind(n,5796,19)),"@generated/docusaurus-plugin-content-docs/users/__plugin.json",5796],d0b7b1a7:[()=>n.e(5222).then(n.t.bind(n,2221,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-tags-sneak-peak-41a.json",2221],d0f03c80:[()=>n.e(366).then(n.bind(n,8691)),"@site/docs/guides/upgrade-guide/openstack.md",8691],d2b0f7bd:[()=>n.e(3199).then(n.bind(n,5581)),"@site/docs/guides/configuration-guide/network.md",5581],d5f7a6fc:[()=>n.e(1892).then(n.bind(n,1414)),"@site/docs/guides/concept-guide/components/prometheus.md",1414],d7a98899:[()=>n.e(6666).then(n.bind(n,4976)),"@site/docs/guides/configuration-guide/openstack/magnum.md",4976],db7ff767:[()=>n.e(6537).then(n.bind(n,347)),"@site/docs/guides/configuration-guide/inventory.md",347],dbb7d2f3:[()=>Promise.all([n.e(532),n.e(5378)]).then(n.bind(n,9488)),"@site/docs/guides/deploy-guide/services/ceph.mdx",9488],dbbbc829:[()=>n.e(4329).then(n.bind(n,2625)),"@site/docs/guides/upgrade-guide/network.md",2625],dbe528c9:[()=>n.e(6330).then(n.bind(n,7752)),"@site/docs/guides/deploy-guide/services/openstack.md",7752],dd3359e9:[()=>Promise.all([n.e(532),n.e(4134)]).then(n.bind(n,6268)),"@site/docs/guides/upgrade-guide/manager.mdx",6268],de57d45c:[()=>n.e(1574).then(n.bind(n,7623)),"@site/docs/guides/operations-guide/index.md",7623],e0698a94:[()=>n.e(8157).then(n.bind(n,9177)),"@site/docs/guides/deploy-guide/services/index.md",9177],e29aad9d:[()=>n.e(1195).then(n.bind(n,7292)),"@site/docs/guides/operations-guide/manager/console.md",7292],e331e3e2:[()=>n.e(2868).then(n.bind(n,7414)),"@site/docs/guides/user-guide/migration-vmware-esix.md",7414],e5eb6f7e:[()=>n.e(1180).then(n.bind(n,3434)),"@site/src/pages/legals.md",3434],e6963042:[()=>n.e(7937).then(n.bind(n,7417)),"@site/docs/guides/user-guide/openstack/user-data-backups.md",7417],e934a396:[()=>n.e(3188).then(n.bind(n,2716)),"@site/docs/guides/configuration-guide/commons/packages.md",2716],e9b984e6:[()=>n.e(201).then(n.bind(n,9116)),"@site/docs/appendix/comparisons.md",9116],ea4c6a72:[()=>n.e(6985).then(n.bind(n,3612)),"@site/src/pages/partners.md",3612],f159c280:[()=>n.e(2557).then(n.bind(n,9406)),"@site/docs/guides/operations-guide/network.md",9406],f2afad6f:[()=>n.e(7419).then(n.bind(n,1481)),"@site/src/pages/support.md",1481],f3e1e4c4:[()=>n.e(1336).then(n.bind(n,6023)),"@site/docs/guides/other-guides/developer-guide/scripts.md",6023],f4931b40:[()=>n.e(7).then(n.bind(n,8121)),"@site/docs/guides/configuration-guide/commons/user.md",8121],f6217829:[()=>n.e(6882).then(n.bind(n,4565)),"@site/docs/guides/configuration-guide/services/docker.md",4565],f7e4724a:[()=>n.e(5826).then(n.bind(n,3005)),"@site/docs/guides/deploy-guide/bootstrap.md",3005],f81c1134:[()=>n.e(4031).then(n.t.bind(n,4108,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-archive-f05.json",4108],f8a055c5:[()=>n.e(289).then(n.bind(n,9155)),"@site/docs/release-notes/osism-7.md",9155],f96dc981:[()=>n.e(6571).then(n.bind(n,9911)),"@site/docs/guides/concept-guide/components/clusterapi.md",9911],fac2b365:[()=>n.e(9377).then(n.bind(n,2201)),"@site/docs/guides/configuration-guide/configuration-repository.md",2201],fb66bc4c:[()=>n.e(5961).then(n.bind(n,6504)),"@site/docs/guides/other-guides/style-guide.md",6504]};var s=n(5893);function l(e){let{error:t,retry:n,pastDelay:r}=e;return t?(0,s.jsxs)("div",{style:{textAlign:"center",color:"#fff",backgroundColor:"#fa383e",borderColor:"#fa383e",borderStyle:"solid",borderRadius:"0.25rem",borderWidth:"1px",boxSizing:"border-box",display:"block",padding:"1rem",flex:"0 0 50%",marginLeft:"25%",marginRight:"25%",marginTop:"5rem",maxWidth:"50%",width:"100%"},children:[(0,s.jsx)("p",{children:String(t)}),(0,s.jsx)("div",{children:(0,s.jsx)("button",{type:"button",onClick:n,children:"Retry"})})]}):r?(0,s.jsx)("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh"},children:(0,s.jsx)("svg",{id:"loader",style:{width:128,height:110,position:"absolute",top:"calc(100vh - 64%)"},viewBox:"0 0 45 45",xmlns:"http://www.w3.org/2000/svg",stroke:"#61dafb",children:(0,s.jsxs)("g",{fill:"none",fillRule:"evenodd",transform:"translate(1 1)",strokeWidth:"2",children:[(0,s.jsxs)("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0",children:[(0,s.jsx)("animate",{attributeName:"r",begin:"1.5s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-opacity",begin:"1.5s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-width",begin:"1.5s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})]}),(0,s.jsxs)("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0",children:[(0,s.jsx)("animate",{attributeName:"r",begin:"3s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-opacity",begin:"3s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-width",begin:"3s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})]}),(0,s.jsx)("circle",{cx:"22",cy:"22",r:"8",children:(0,s.jsx)("animate",{attributeName:"r",begin:"0s",dur:"1.5s",values:"6;1;2;3;4;5;6",calcMode:"linear",repeatCount:"indefinite"})})]})})}):null}var c=n(9670),u=n(226);function d(e,t){if("*"===e)return o()({loading:l,loader:()=>n.e(1772).then(n.bind(n,1772)),modules:["@theme/NotFound"],webpack:()=>[1772],render(e,t){const n=e.default;return(0,s.jsx)(u.z,{value:{plugin:{name:"native",id:"default"}},children:(0,s.jsx)(n,{...t})})}});const r=i[`${e}-${t}`],d={},p=[],f=[],g=(0,c.Z)(r);return Object.entries(g).forEach((e=>{let[t,n]=e;const r=a[n];r&&(d[t]=r[0],p.push(r[1]),f.push(r[2]))})),o().Map({loading:l,loader:d,modules:p,webpack:()=>f,render(t,n){const o=JSON.parse(JSON.stringify(r));Object.entries(t).forEach((t=>{let[n,r]=t;const i=r.default;if(!i)throw new Error(`The page component at ${e} doesn't have a default export. This makes it impossible to render anything. Consider default-exporting a React component.`);"object"!=typeof i&&"function"!=typeof i||Object.keys(r).filter((e=>"default"!==e)).forEach((e=>{i[e]=r[e]}));let a=o;const s=n.split(".");s.slice(0,-1).forEach((e=>{a=a[e]})),a[s[s.length-1]]=i}));const i=o.__comp;delete o.__comp;const a=o.__context;delete o.__context;const l=o.__props;return delete o.__props,(0,s.jsx)(u.z,{value:a,children:(0,s.jsx)(i,{...o,...l,...n})})}})}const p=[{path:"/about-us",component:d("/about-us","960"),exact:!0},{path:"/blog",component:d("/blog","3af"),exact:!0},{path:"/blog/2024-01-11-kubernetes-service-deployment",component:d("/blog/2024-01-11-kubernetes-service-deployment","e02"),exact:!0},{path:"/blog/2024-01-12-restart-of-a-container-on-a-specific-node",component:d("/blog/2024-01-12-restart-of-a-container-on-a-specific-node","eb4"),exact:!0},{path:"/blog/2024-01-14-use-of-the-clustershell",component:d("/blog/2024-01-14-use-of-the-clustershell","00c"),exact:!0},{path:"/blog/2024-01-16-switch-to-opentofu",component:d("/blog/2024-01-16-switch-to-opentofu","e2b"),exact:!0},{path:"/blog/2024-01-16-use-of-the-container-shell",component:d("/blog/2024-01-16-use-of-the-container-shell","113"),exact:!0},{path:"/blog/2024-03-04-show-versions-used-on-the-manager",component:d("/blog/2024-03-04-show-versions-used-on-the-manager","4c8"),exact:!0},{path:"/blog/archive",component:d("/blog/archive","182"),exact:!0},{path:"/blog/tags",component:d("/blog/tags","287"),exact:!0},{path:"/blog/tags/kubernetes",component:d("/blog/tags/kubernetes","48c"),exact:!0},{path:"/blog/tags/machine-room",component:d("/blog/tags/machine-room","a2e"),exact:!0},{path:"/blog/tags/news",component:d("/blog/tags/news","395"),exact:!0},{path:"/blog/tags/osism",component:d("/blog/tags/osism","20c"),exact:!0},{path:"/blog/tags/sneak-peak",component:d("/blog/tags/sneak-peak","13f"),exact:!0},{path:"/contact-us",component:d("/contact-us","d8e"),exact:!0},{path:"/jobs",component:d("/jobs","563"),exact:!0},{path:"/legals",component:d("/legals","952"),exact:!0},{path:"/partners",component:d("/partners","43d"),exact:!0},{path:"/privacy",component:d("/privacy","476"),exact:!0},{path:"/search",component:d("/search","822"),exact:!0},{path:"/support",component:d("/support","ce4"),exact:!0},{path:"/terms",component:d("/terms","235"),exact:!0},{path:"/docs",component:d("/docs","f59"),routes:[{path:"/docs",component:d("/docs","eda"),routes:[{path:"/docs",component:d("/docs","cf2"),routes:[{path:"/docs/",component:d("/docs/","4a8"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/appendix/",component:d("/docs/appendix/","f91"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/appendix/comparisons",component:d("/docs/appendix/comparisons","87f"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/appendix/glossary",component:d("/docs/appendix/glossary","16e"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/appendix/networks",component:d("/docs/appendix/networks","eb6"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/appendix/standards",component:d("/docs/appendix/standards","4db"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/",component:d("/docs/guides/","e13"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/concept-guide/",component:d("/docs/guides/concept-guide/","3f5"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/concept-guide/components/",component:d("/docs/guides/concept-guide/components/","55f"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/concept-guide/components/ceph",component:d("/docs/guides/concept-guide/components/ceph","23a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/concept-guide/components/clusterapi",component:d("/docs/guides/concept-guide/components/clusterapi","c76"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/concept-guide/components/gardener",component:d("/docs/guides/concept-guide/components/gardener","74a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/concept-guide/components/ironic",component:d("/docs/guides/concept-guide/components/ironic","68b"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/concept-guide/components/k3s",component:d("/docs/guides/concept-guide/components/k3s","04c"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/concept-guide/components/keycloak",component:d("/docs/guides/concept-guide/components/keycloak","ea4"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/concept-guide/components/netdata",component:d("/docs/guides/concept-guide/components/netdata","384"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/concept-guide/components/openstack",component:d("/docs/guides/concept-guide/components/openstack","772"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/concept-guide/components/prometheus",component:d("/docs/guides/concept-guide/components/prometheus","4ac"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/concept-guide/components/proxmox",component:d("/docs/guides/concept-guide/components/proxmox","f51"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/concept-guide/components/sonic",component:d("/docs/guides/concept-guide/components/sonic","de3"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/concept-guide/components/teleport",component:d("/docs/guides/concept-guide/components/teleport","ce4"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/concept-guide/design",component:d("/docs/guides/concept-guide/design","e9b"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/concept-guide/hardware-bom",component:d("/docs/guides/concept-guide/hardware-bom","b58"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/concept-guide/layers",component:d("/docs/guides/concept-guide/layers","a24"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/concept-guide/nodes",component:d("/docs/guides/concept-guide/nodes","ee8"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/concept-guide/use-cases",component:d("/docs/guides/concept-guide/use-cases","3d9"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/configuration-guide/",component:d("/docs/guides/configuration-guide/","c40"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/configuration-guide/ceph",component:d("/docs/guides/configuration-guide/ceph","fe5"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/configuration-guide/commons/",component:d("/docs/guides/configuration-guide/commons/","757"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/configuration-guide/commons/certificates",component:d("/docs/guides/configuration-guide/commons/certificates","60b"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/configuration-guide/commons/packages",component:d("/docs/guides/configuration-guide/commons/packages","2f2"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/configuration-guide/commons/resolvconf",component:d("/docs/guides/configuration-guide/commons/resolvconf","beb"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/configuration-guide/commons/services",component:d("/docs/guides/configuration-guide/commons/services","722"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/configuration-guide/commons/sshconfig",component:d("/docs/guides/configuration-guide/commons/sshconfig","1e4"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/configuration-guide/commons/sysctl",component:d("/docs/guides/configuration-guide/commons/sysctl","c91"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/configuration-guide/commons/timezone",component:d("/docs/guides/configuration-guide/commons/timezone","0f8"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/configuration-guide/commons/user",component:d("/docs/guides/configuration-guide/commons/user","ea5"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/configuration-guide/configuration-repository",component:d("/docs/guides/configuration-guide/configuration-repository","7cf"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/configuration-guide/inventory",component:d("/docs/guides/configuration-guide/inventory","955"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/configuration-guide/loadbalancer",component:d("/docs/guides/configuration-guide/loadbalancer","a3a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/configuration-guide/manager",component:d("/docs/guides/configuration-guide/manager","116"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/configuration-guide/network",component:d("/docs/guides/configuration-guide/network","13c"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/configuration-guide/openstack/",component:d("/docs/guides/configuration-guide/openstack/","c16"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/configuration-guide/openstack/aodh",component:d("/docs/guides/configuration-guide/openstack/aodh","7c6"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/configuration-guide/openstack/barbican",component:d("/docs/guides/configuration-guide/openstack/barbican","953"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/configuration-guide/openstack/ceilometer",component:d("/docs/guides/configuration-guide/openstack/ceilometer","5c7"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/configuration-guide/openstack/cinder",component:d("/docs/guides/configuration-guide/openstack/cinder","998"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/configuration-guide/openstack/designate",component:d("/docs/guides/configuration-guide/openstack/designate","6c2"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/configuration-guide/openstack/glance",component:d("/docs/guides/configuration-guide/openstack/glance","f43"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/configuration-guide/openstack/heat",component:d("/docs/guides/configuration-guide/openstack/heat","cda"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/configuration-guide/openstack/horizon",component:d("/docs/guides/configuration-guide/openstack/horizon","9f0"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/configuration-guide/openstack/ironic",component:d("/docs/guides/configuration-guide/openstack/ironic","381"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/configuration-guide/openstack/keystone",component:d("/docs/guides/configuration-guide/openstack/keystone","42a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/configuration-guide/openstack/magnum",component:d("/docs/guides/configuration-guide/openstack/magnum","93a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/configuration-guide/openstack/manila",component:d("/docs/guides/configuration-guide/openstack/manila","889"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/configuration-guide/openstack/neutron",component:d("/docs/guides/configuration-guide/openstack/neutron","317"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/configuration-guide/openstack/nova",component:d("/docs/guides/configuration-guide/openstack/nova","d3d"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/configuration-guide/openstack/octavia",component:d("/docs/guides/configuration-guide/openstack/octavia","66a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/configuration-guide/openstack/placement",component:d("/docs/guides/configuration-guide/openstack/placement","783"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/configuration-guide/openstack/skyline",component:d("/docs/guides/configuration-guide/openstack/skyline","bf0"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/configuration-guide/proxy",component:d("/docs/guides/configuration-guide/proxy","3a1"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/configuration-guide/services/",component:d("/docs/guides/configuration-guide/services/","93c"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/configuration-guide/services/chrony",component:d("/docs/guides/configuration-guide/services/chrony","50e"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/configuration-guide/services/docker",component:d("/docs/guides/configuration-guide/services/docker","643"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/configuration-guide/services/tuned",component:d("/docs/guides/configuration-guide/services/tuned","02d"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/configuration-guide/validations/",component:d("/docs/guides/configuration-guide/validations/","c76"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/deploy-guide/",component:d("/docs/guides/deploy-guide/","0fd"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/deploy-guide/bootstrap",component:d("/docs/guides/deploy-guide/bootstrap","3ec"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/deploy-guide/examples/",component:d("/docs/guides/deploy-guide/examples/","f2f"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/deploy-guide/examples/cloud-in-a-box",component:d("/docs/guides/deploy-guide/examples/cloud-in-a-box","957"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/deploy-guide/examples/testbed",component:d("/docs/guides/deploy-guide/examples/testbed","772"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/deploy-guide/manager",component:d("/docs/guides/deploy-guide/manager","8c5"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/deploy-guide/provisioning",component:d("/docs/guides/deploy-guide/provisioning","af9"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/deploy-guide/seed",component:d("/docs/guides/deploy-guide/seed","3f0"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/deploy-guide/services/",component:d("/docs/guides/deploy-guide/services/","e37"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/deploy-guide/services/ceph",component:d("/docs/guides/deploy-guide/services/ceph","f0d"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/deploy-guide/services/infrastructure",component:d("/docs/guides/deploy-guide/services/infrastructure","b48"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/deploy-guide/services/kubernetes",component:d("/docs/guides/deploy-guide/services/kubernetes","fba"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/deploy-guide/services/logging-monitoring",component:d("/docs/guides/deploy-guide/services/logging-monitoring","4ab"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/deploy-guide/services/network",component:d("/docs/guides/deploy-guide/services/network","6ae"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/deploy-guide/services/openstack",component:d("/docs/guides/deploy-guide/services/openstack","ea0"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/operations-guide/",component:d("/docs/guides/operations-guide/","291"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/operations-guide/ceph",component:d("/docs/guides/operations-guide/ceph","03d"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/operations-guide/infrastructure",component:d("/docs/guides/operations-guide/infrastructure","aca"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/operations-guide/manager/",component:d("/docs/guides/operations-guide/manager/","cf1"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/operations-guide/manager/apply",component:d("/docs/guides/operations-guide/manager/apply","393"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/operations-guide/manager/console",component:d("/docs/guides/operations-guide/manager/console","a8d"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/operations-guide/manager/get",component:d("/docs/guides/operations-guide/manager/get","e94"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/operations-guide/manager/log",component:d("/docs/guides/operations-guide/manager/log","a36"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/operations-guide/manager/task",component:d("/docs/guides/operations-guide/manager/task","2dd"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/operations-guide/network",component:d("/docs/guides/operations-guide/network","6e9"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/operations-guide/openstack/",component:d("/docs/guides/operations-guide/openstack/","641"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/operations-guide/openstack/cinder",component:d("/docs/guides/operations-guide/openstack/cinder","577"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/operations-guide/openstack/keystone",component:d("/docs/guides/operations-guide/openstack/keystone","df0"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/operations-guide/openstack/neutron",component:d("/docs/guides/operations-guide/openstack/neutron","888"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/operations-guide/openstack/nova",component:d("/docs/guides/operations-guide/openstack/nova","d86"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/operations-guide/openstack/octavia",component:d("/docs/guides/operations-guide/openstack/octavia","52a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/operations-guide/openstack/tools/",component:d("/docs/guides/operations-guide/openstack/tools/","b4b"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/operations-guide/openstack/tools/flavor-manager",component:d("/docs/guides/operations-guide/openstack/tools/flavor-manager","79a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/operations-guide/openstack/tools/image-manager/",component:d("/docs/guides/operations-guide/openstack/tools/image-manager/","d33"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/operations-guide/openstack/tools/image-manager/update",component:d("/docs/guides/operations-guide/openstack/tools/image-manager/update","dea"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/operations-guide/openstack/tools/openstack-health-monitor",component:d("/docs/guides/operations-guide/openstack/tools/openstack-health-monitor","efd"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/operations-guide/openstack/tools/project-manager",component:d("/docs/guides/operations-guide/openstack/tools/project-manager","b83"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/operations-guide/openstack/tools/resource-manager",component:d("/docs/guides/operations-guide/openstack/tools/resource-manager","f5d"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/operations-guide/openstack/tools/sandbox-manager",component:d("/docs/guides/operations-guide/openstack/tools/sandbox-manager","622"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/operations-guide/openstack/tools/simple-stress",component:d("/docs/guides/operations-guide/openstack/tools/simple-stress","44d"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/other-guides/",component:d("/docs/guides/other-guides/","849"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/other-guides/cloud-in-a-box",component:d("/docs/guides/other-guides/cloud-in-a-box","4d9"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/other-guides/contributor-guide",component:d("/docs/guides/other-guides/contributor-guide","628"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/other-guides/developer-guide/",component:d("/docs/guides/other-guides/developer-guide/","39e"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/other-guides/developer-guide/releases",component:d("/docs/guides/other-guides/developer-guide/releases","d02"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/other-guides/developer-guide/scripts",component:d("/docs/guides/other-guides/developer-guide/scripts","8ac"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/other-guides/developer-guide/zuul",component:d("/docs/guides/other-guides/developer-guide/zuul","54b"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/other-guides/style-guide",component:d("/docs/guides/other-guides/style-guide","a32"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/other-guides/testbed",component:d("/docs/guides/other-guides/testbed","a41"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/troubleshooting-guide/",component:d("/docs/guides/troubleshooting-guide/","590"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/troubleshooting-guide/ceph",component:d("/docs/guides/troubleshooting-guide/ceph","c65"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/troubleshooting-guide/manager",component:d("/docs/guides/troubleshooting-guide/manager","df5"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/troubleshooting-guide/openstack",component:d("/docs/guides/troubleshooting-guide/openstack","04c"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/upgrade-guide/",component:d("/docs/guides/upgrade-guide/","6e6"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/upgrade-guide/ceph",component:d("/docs/guides/upgrade-guide/ceph","2a6"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/upgrade-guide/docker",component:d("/docs/guides/upgrade-guide/docker","10b"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/upgrade-guide/infrastructure",component:d("/docs/guides/upgrade-guide/infrastructure","16c"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/upgrade-guide/logging-monitoring",component:d("/docs/guides/upgrade-guide/logging-monitoring","8fc"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/upgrade-guide/manager",component:d("/docs/guides/upgrade-guide/manager","5f4"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/upgrade-guide/network",component:d("/docs/guides/upgrade-guide/network","130"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/upgrade-guide/openstack",component:d("/docs/guides/upgrade-guide/openstack","ee5"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/user-guide/",component:d("/docs/guides/user-guide/","873"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/user-guide/migration-vmware-esix",component:d("/docs/guides/user-guide/migration-vmware-esix","fb5"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/user-guide/openstack/",component:d("/docs/guides/user-guide/openstack/","cbf"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/user-guide/openstack/openstackclient",component:d("/docs/guides/user-guide/openstack/openstackclient","12c"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/user-guide/openstack/security-groups",component:d("/docs/guides/user-guide/openstack/security-groups","9c3"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/user-guide/openstack/user-data-backups",component:d("/docs/guides/user-guide/openstack/user-data-backups","c5d"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/references/",component:d("/docs/references/","1f1"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/references/cli",component:d("/docs/references/cli","c7e"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/references/configuration",component:d("/docs/references/configuration","fca"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/references/parameters",component:d("/docs/references/parameters","85e"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/release-notes/",component:d("/docs/release-notes/","dfd"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/release-notes/osism-7",component:d("/docs/release-notes/osism-7","b9d"),exact:!0,sidebar:"tutorialSidebar"}]}]}]},{path:"/users",component:d("/users","4b4"),routes:[{path:"/users",component:d("/users","33d"),routes:[{path:"/users",component:d("/users","5ee"),routes:[{path:"/users/",component:d("/users/","dff"),exact:!0,sidebar:"adaptorsSidebar"}]}]}]},{path:"/",component:d("/","2e1"),exact:!0},{path:"*",component:d("*")}]},8934:(e,t,n)=>{"use strict";n.d(t,{_:()=>i,t:()=>a});var r=n(7294),o=n(5893);const i=r.createContext(!1);function a(e){let{children:t}=e;const[n,a]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{a(!0)}),[]),(0,o.jsx)(i.Provider,{value:n,children:t})}},7221:(e,t,n)=>{"use strict";var r=n(7294),o=n(745),i=n(405),a=n(3727),s=n(6809),l=n(412);const c=[n(2497),n(3310),n(8320),n(2295)];var u=n(723),d=n(6550),p=n(8790),f=n(5893);function g(e){let{children:t}=e;return(0,f.jsx)(f.Fragment,{children:t})}var m=n(5742),h=n(2263),b=n(4996),y=n(6668),v=n(8264),w=n(4711),k=n(9727),x=n(3320),S=n(8780),_=n(197);function E(){const{i18n:{currentLocale:e,defaultLocale:t,localeConfigs:n}}=(0,h.Z)(),r=(0,w.l)(),o=n[e].htmlLang,i=e=>e.replace("-","_");return(0,f.jsxs)(m.Z,{children:[Object.entries(n).map((e=>{let[t,{htmlLang:n}]=e;return(0,f.jsx)("link",{rel:"alternate",href:r.createUrl({locale:t,fullyQualified:!0}),hrefLang:n},t)})),(0,f.jsx)("link",{rel:"alternate",href:r.createUrl({locale:t,fullyQualified:!0}),hrefLang:"x-default"}),(0,f.jsx)("meta",{property:"og:locale",content:i(o)}),Object.values(n).filter((e=>o!==e.htmlLang)).map((e=>(0,f.jsx)("meta",{property:"og:locale:alternate",content:i(e.htmlLang)},`meta-og-${e.htmlLang}`)))]})}function C(e){let{permalink:t}=e;const{siteConfig:{url:n}}=(0,h.Z)(),r=function(){const{siteConfig:{url:e,baseUrl:t,trailingSlash:n}}=(0,h.Z)(),{pathname:r}=(0,d.TH)();return e+(0,S.applyTrailingSlash)((0,b.ZP)(r),{trailingSlash:n,baseUrl:t})}(),o=t?`${n}${t}`:r;return(0,f.jsxs)(m.Z,{children:[(0,f.jsx)("meta",{property:"og:url",content:o}),(0,f.jsx)("link",{rel:"canonical",href:o})]})}function T(){const{i18n:{currentLocale:e}}=(0,h.Z)(),{metadata:t,image:n}=(0,y.L)();return(0,f.jsxs)(f.Fragment,{children:[(0,f.jsxs)(m.Z,{children:[(0,f.jsx)("meta",{name:"twitter:card",content:"summary_large_image"}),(0,f.jsx)("body",{className:k.h})]}),n&&(0,f.jsx)(v.d,{image:n}),(0,f.jsx)(C,{}),(0,f.jsx)(E,{}),(0,f.jsx)(_.Z,{tag:x.HX,locale:e}),(0,f.jsx)(m.Z,{children:t.map(((e,t)=>(0,f.jsx)("meta",{...e},t)))})]})}const L=new Map;var P=n(8934),j=n(8940),A=n(469);function R(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r{const r=t.default?.[e]??t[e];return r?.(...n)}));return()=>o.forEach((e=>e?.()))}const N=function(e){let{children:t,location:n,previousLocation:r}=e;return(0,A.Z)((()=>{r!==n&&(!function(e){let{location:t,previousLocation:n}=e;if(!n)return;const r=t.pathname===n.pathname,o=t.hash===n.hash,i=t.search===n.search;if(r&&o&&!i)return;const{hash:a}=t;if(a){const e=decodeURIComponent(a.substring(1)),t=document.getElementById(e);t?.scrollIntoView()}else window.scrollTo(0,0)}({location:n,previousLocation:r}),R("onRouteDidUpdate",{previousLocation:r,location:n}))}),[r,n]),t};function O(e){const t=Array.from(new Set([e,decodeURI(e)])).map((e=>(0,p.f)(u.Z,e))).flat();return Promise.all(t.map((e=>e.route.component.preload?.())))}class I extends r.Component{previousLocation;routeUpdateCleanupCb;constructor(e){super(e),this.previousLocation=null,this.routeUpdateCleanupCb=l.Z.canUseDOM?R("onRouteUpdate",{previousLocation:null,location:this.props.location}):()=>{},this.state={nextRouteHasLoaded:!0}}shouldComponentUpdate(e,t){if(e.location===this.props.location)return t.nextRouteHasLoaded;const n=e.location;return this.previousLocation=this.props.location,this.setState({nextRouteHasLoaded:!1}),this.routeUpdateCleanupCb=R("onRouteUpdate",{previousLocation:this.previousLocation,location:n}),O(n.pathname).then((()=>{this.routeUpdateCleanupCb(),this.setState({nextRouteHasLoaded:!0})})).catch((e=>{console.warn(e),window.location.reload()})),!1}render(){const{children:e,location:t}=this.props;return(0,f.jsx)(N,{previousLocation:this.previousLocation,location:t,children:(0,f.jsx)(d.AW,{location:t,render:()=>e})})}}const D=I,F="__docusaurus-base-url-issue-banner-container",M="__docusaurus-base-url-issue-banner",B="__docusaurus-base-url-issue-banner-suggestion-container";function z(e){return`\ndocument.addEventListener('DOMContentLoaded', function maybeInsertBanner() {\n var shouldInsert = typeof window['docusaurus'] === 'undefined';\n shouldInsert && insertBanner();\n});\n\nfunction insertBanner() {\n var bannerContainer = document.createElement('div');\n bannerContainer.id = '${F}';\n var bannerHtml = ${JSON.stringify(function(e){return`\n
\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(/{let{route:t}=e;return!0===t.exact})))return L.set(e.pathname,e.pathname),e;const t=e.pathname.trim().replace(/(?:\/index)?\.html$/,"")||"/";return L.set(e.pathname,t),{...e,pathname:t}}((0,d.TH)());return(0,f.jsx)(D,{location:e,children:V})}function G(){return(0,f.jsx)(H.Z,{children:(0,f.jsx)(j.M,{children:(0,f.jsxs)(P.t,{children:[(0,f.jsxs)(g,{children:[(0,f.jsx)(q,{}),(0,f.jsx)(T,{}),(0,f.jsx)(U,{}),(0,f.jsx)(W,{})]}),(0,f.jsx)(Z,{})]})})})}var K=n(6887);const Y=function(e){try{return document.createElement("link").relList.supports(e)}catch{return!1}}("prefetch")?function(e){return new Promise(((t,n)=>{if("undefined"==typeof document)return void n();const r=document.createElement("link");r.setAttribute("rel","prefetch"),r.setAttribute("href",e),r.onload=()=>t(),r.onerror=()=>n();const o=document.getElementsByTagName("head")[0]??document.getElementsByName("script")[0]?.parentNode;o?.appendChild(r)}))}:function(e){return new Promise(((t,n)=>{const r=new XMLHttpRequest;r.open("GET",e,!0),r.withCredentials=!0,r.onload=()=>{200===r.status?t():n()},r.send(null)}))};var X=n(9670);const J=new Set,ee=new Set,te=()=>navigator.connection?.effectiveType.includes("2g")||navigator.connection?.saveData,ne={prefetch:e=>{if(!(e=>!te()&&!ee.has(e)&&!J.has(e))(e))return!1;J.add(e);const t=(0,p.f)(u.Z,e).flatMap((e=>{return t=e.route.path,Object.entries(K).filter((e=>{let[n]=e;return n.replace(/-[^-]+$/,"")===t})).flatMap((e=>{let[,t]=e;return Object.values((0,X.Z)(t))}));var t}));return Promise.all(t.map((e=>{const t=n.gca(e);return t&&!t.includes("undefined")?Y(t).catch((()=>{})):Promise.resolve()})))},preload:e=>!!(e=>!te()&&!ee.has(e))(e)&&(ee.add(e),O(e))},re=Object.freeze(ne);function oe(e){let{children:t}=e;return"hash"===s.default.future.experimental_router?(0,f.jsx)(a.UT,{children:t}):(0,f.jsx)(a.VK,{children:t})}const ie=Boolean(!0);if(l.Z.canUseDOM){window.docusaurus=re;const e=document.getElementById("__docusaurus"),t=(0,f.jsx)(i.B6,{children:(0,f.jsx)(oe,{children:(0,f.jsx)(G,{})})}),n=(e,t)=>{console.error("Docusaurus React Root onRecoverableError:",e,t)},a=()=>{if(window.docusaurusRoot)window.docusaurusRoot.render(t);else if(ie)window.docusaurusRoot=o.hydrateRoot(e,t,{onRecoverableError:n});else{const r=o.createRoot(e,{onRecoverableError:n});r.render(t),window.docusaurusRoot=r}};O(window.location.pathname).then((()=>{(0,r.startTransition)(a)}))}},8940:(e,t,n)=>{"use strict";n.d(t,{_:()=>d,M:()=>p});var r=n(7294),o=n(6809);const i=JSON.parse('{"docusaurus-plugin-content-docs":{"default":{"path":"/docs","versions":[{"name":"current","label":"Next","isLast":true,"path":"/docs","mainDocId":"index","docs":[{"id":"appendix/comparisons","path":"/docs/appendix/comparisons","sidebar":"tutorialSidebar"},{"id":"appendix/glossary","path":"/docs/appendix/glossary","sidebar":"tutorialSidebar"},{"id":"appendix/index","path":"/docs/appendix/","sidebar":"tutorialSidebar"},{"id":"appendix/networks","path":"/docs/appendix/networks","sidebar":"tutorialSidebar"},{"id":"appendix/standards","path":"/docs/appendix/standards","sidebar":"tutorialSidebar"},{"id":"guides/concept-guide/components/ceph","path":"/docs/guides/concept-guide/components/ceph","sidebar":"tutorialSidebar"},{"id":"guides/concept-guide/components/clusterapi","path":"/docs/guides/concept-guide/components/clusterapi","sidebar":"tutorialSidebar"},{"id":"guides/concept-guide/components/gardener","path":"/docs/guides/concept-guide/components/gardener","sidebar":"tutorialSidebar"},{"id":"guides/concept-guide/components/index","path":"/docs/guides/concept-guide/components/","sidebar":"tutorialSidebar"},{"id":"guides/concept-guide/components/ironic","path":"/docs/guides/concept-guide/components/ironic","sidebar":"tutorialSidebar"},{"id":"guides/concept-guide/components/k3s","path":"/docs/guides/concept-guide/components/k3s","sidebar":"tutorialSidebar"},{"id":"guides/concept-guide/components/keycloak","path":"/docs/guides/concept-guide/components/keycloak","sidebar":"tutorialSidebar"},{"id":"guides/concept-guide/components/netdata","path":"/docs/guides/concept-guide/components/netdata","sidebar":"tutorialSidebar"},{"id":"guides/concept-guide/components/openstack","path":"/docs/guides/concept-guide/components/openstack","sidebar":"tutorialSidebar"},{"id":"guides/concept-guide/components/prometheus","path":"/docs/guides/concept-guide/components/prometheus","sidebar":"tutorialSidebar"},{"id":"guides/concept-guide/components/proxmox","path":"/docs/guides/concept-guide/components/proxmox","sidebar":"tutorialSidebar"},{"id":"guides/concept-guide/components/sonic","path":"/docs/guides/concept-guide/components/sonic","sidebar":"tutorialSidebar"},{"id":"guides/concept-guide/components/teleport","path":"/docs/guides/concept-guide/components/teleport","sidebar":"tutorialSidebar"},{"id":"guides/concept-guide/design","path":"/docs/guides/concept-guide/design","sidebar":"tutorialSidebar"},{"id":"guides/concept-guide/hardware-bom","path":"/docs/guides/concept-guide/hardware-bom","sidebar":"tutorialSidebar"},{"id":"guides/concept-guide/index","path":"/docs/guides/concept-guide/","sidebar":"tutorialSidebar"},{"id":"guides/concept-guide/layers","path":"/docs/guides/concept-guide/layers","sidebar":"tutorialSidebar"},{"id":"guides/concept-guide/nodes","path":"/docs/guides/concept-guide/nodes","sidebar":"tutorialSidebar"},{"id":"guides/concept-guide/use-cases","path":"/docs/guides/concept-guide/use-cases","sidebar":"tutorialSidebar"},{"id":"guides/configuration-guide/ceph","path":"/docs/guides/configuration-guide/ceph","sidebar":"tutorialSidebar"},{"id":"guides/configuration-guide/commons/certificates","path":"/docs/guides/configuration-guide/commons/certificates","sidebar":"tutorialSidebar"},{"id":"guides/configuration-guide/commons/index","path":"/docs/guides/configuration-guide/commons/","sidebar":"tutorialSidebar"},{"id":"guides/configuration-guide/commons/packages","path":"/docs/guides/configuration-guide/commons/packages","sidebar":"tutorialSidebar"},{"id":"guides/configuration-guide/commons/resolvconf","path":"/docs/guides/configuration-guide/commons/resolvconf","sidebar":"tutorialSidebar"},{"id":"guides/configuration-guide/commons/services","path":"/docs/guides/configuration-guide/commons/services","sidebar":"tutorialSidebar"},{"id":"guides/configuration-guide/commons/sshconfig","path":"/docs/guides/configuration-guide/commons/sshconfig","sidebar":"tutorialSidebar"},{"id":"guides/configuration-guide/commons/sysctl","path":"/docs/guides/configuration-guide/commons/sysctl","sidebar":"tutorialSidebar"},{"id":"guides/configuration-guide/commons/timezone","path":"/docs/guides/configuration-guide/commons/timezone","sidebar":"tutorialSidebar"},{"id":"guides/configuration-guide/commons/user","path":"/docs/guides/configuration-guide/commons/user","sidebar":"tutorialSidebar"},{"id":"guides/configuration-guide/configuration-repository","path":"/docs/guides/configuration-guide/configuration-repository","sidebar":"tutorialSidebar"},{"id":"guides/configuration-guide/index","path":"/docs/guides/configuration-guide/","sidebar":"tutorialSidebar"},{"id":"guides/configuration-guide/inventory","path":"/docs/guides/configuration-guide/inventory","sidebar":"tutorialSidebar"},{"id":"guides/configuration-guide/loadbalancer","path":"/docs/guides/configuration-guide/loadbalancer","sidebar":"tutorialSidebar"},{"id":"guides/configuration-guide/manager","path":"/docs/guides/configuration-guide/manager","sidebar":"tutorialSidebar"},{"id":"guides/configuration-guide/network","path":"/docs/guides/configuration-guide/network","sidebar":"tutorialSidebar"},{"id":"guides/configuration-guide/openstack/aodh","path":"/docs/guides/configuration-guide/openstack/aodh","sidebar":"tutorialSidebar"},{"id":"guides/configuration-guide/openstack/barbican","path":"/docs/guides/configuration-guide/openstack/barbican","sidebar":"tutorialSidebar"},{"id":"guides/configuration-guide/openstack/ceilometer","path":"/docs/guides/configuration-guide/openstack/ceilometer","sidebar":"tutorialSidebar"},{"id":"guides/configuration-guide/openstack/cinder","path":"/docs/guides/configuration-guide/openstack/cinder","sidebar":"tutorialSidebar"},{"id":"guides/configuration-guide/openstack/designate","path":"/docs/guides/configuration-guide/openstack/designate","sidebar":"tutorialSidebar"},{"id":"guides/configuration-guide/openstack/glance","path":"/docs/guides/configuration-guide/openstack/glance","sidebar":"tutorialSidebar"},{"id":"guides/configuration-guide/openstack/heat","path":"/docs/guides/configuration-guide/openstack/heat","sidebar":"tutorialSidebar"},{"id":"guides/configuration-guide/openstack/horizon","path":"/docs/guides/configuration-guide/openstack/horizon","sidebar":"tutorialSidebar"},{"id":"guides/configuration-guide/openstack/index","path":"/docs/guides/configuration-guide/openstack/","sidebar":"tutorialSidebar"},{"id":"guides/configuration-guide/openstack/ironic","path":"/docs/guides/configuration-guide/openstack/ironic","sidebar":"tutorialSidebar"},{"id":"guides/configuration-guide/openstack/keystone","path":"/docs/guides/configuration-guide/openstack/keystone","sidebar":"tutorialSidebar"},{"id":"guides/configuration-guide/openstack/magnum","path":"/docs/guides/configuration-guide/openstack/magnum","sidebar":"tutorialSidebar"},{"id":"guides/configuration-guide/openstack/manila","path":"/docs/guides/configuration-guide/openstack/manila","sidebar":"tutorialSidebar"},{"id":"guides/configuration-guide/openstack/neutron","path":"/docs/guides/configuration-guide/openstack/neutron","sidebar":"tutorialSidebar"},{"id":"guides/configuration-guide/openstack/nova","path":"/docs/guides/configuration-guide/openstack/nova","sidebar":"tutorialSidebar"},{"id":"guides/configuration-guide/openstack/octavia","path":"/docs/guides/configuration-guide/openstack/octavia","sidebar":"tutorialSidebar"},{"id":"guides/configuration-guide/openstack/placement","path":"/docs/guides/configuration-guide/openstack/placement","sidebar":"tutorialSidebar"},{"id":"guides/configuration-guide/openstack/skyline","path":"/docs/guides/configuration-guide/openstack/skyline","sidebar":"tutorialSidebar"},{"id":"guides/configuration-guide/proxy","path":"/docs/guides/configuration-guide/proxy","sidebar":"tutorialSidebar"},{"id":"guides/configuration-guide/services/chrony","path":"/docs/guides/configuration-guide/services/chrony","sidebar":"tutorialSidebar"},{"id":"guides/configuration-guide/services/docker","path":"/docs/guides/configuration-guide/services/docker","sidebar":"tutorialSidebar"},{"id":"guides/configuration-guide/services/index","path":"/docs/guides/configuration-guide/services/","sidebar":"tutorialSidebar"},{"id":"guides/configuration-guide/services/tuned","path":"/docs/guides/configuration-guide/services/tuned","sidebar":"tutorialSidebar"},{"id":"guides/configuration-guide/validations/index","path":"/docs/guides/configuration-guide/validations/","sidebar":"tutorialSidebar"},{"id":"guides/deploy-guide/bootstrap","path":"/docs/guides/deploy-guide/bootstrap","sidebar":"tutorialSidebar"},{"id":"guides/deploy-guide/examples/cloud-in-a-box","path":"/docs/guides/deploy-guide/examples/cloud-in-a-box","sidebar":"tutorialSidebar"},{"id":"guides/deploy-guide/examples/index","path":"/docs/guides/deploy-guide/examples/","sidebar":"tutorialSidebar"},{"id":"guides/deploy-guide/examples/testbed","path":"/docs/guides/deploy-guide/examples/testbed","sidebar":"tutorialSidebar"},{"id":"guides/deploy-guide/index","path":"/docs/guides/deploy-guide/","sidebar":"tutorialSidebar"},{"id":"guides/deploy-guide/manager","path":"/docs/guides/deploy-guide/manager","sidebar":"tutorialSidebar"},{"id":"guides/deploy-guide/provisioning","path":"/docs/guides/deploy-guide/provisioning","sidebar":"tutorialSidebar"},{"id":"guides/deploy-guide/seed","path":"/docs/guides/deploy-guide/seed","sidebar":"tutorialSidebar"},{"id":"guides/deploy-guide/services/ceph","path":"/docs/guides/deploy-guide/services/ceph","sidebar":"tutorialSidebar"},{"id":"guides/deploy-guide/services/index","path":"/docs/guides/deploy-guide/services/","sidebar":"tutorialSidebar"},{"id":"guides/deploy-guide/services/infrastructure","path":"/docs/guides/deploy-guide/services/infrastructure","sidebar":"tutorialSidebar"},{"id":"guides/deploy-guide/services/kubernetes","path":"/docs/guides/deploy-guide/services/kubernetes","sidebar":"tutorialSidebar"},{"id":"guides/deploy-guide/services/logging-monitoring","path":"/docs/guides/deploy-guide/services/logging-monitoring","sidebar":"tutorialSidebar"},{"id":"guides/deploy-guide/services/network","path":"/docs/guides/deploy-guide/services/network","sidebar":"tutorialSidebar"},{"id":"guides/deploy-guide/services/openstack","path":"/docs/guides/deploy-guide/services/openstack","sidebar":"tutorialSidebar"},{"id":"guides/index","path":"/docs/guides/","sidebar":"tutorialSidebar"},{"id":"guides/operations-guide/ceph","path":"/docs/guides/operations-guide/ceph","sidebar":"tutorialSidebar"},{"id":"guides/operations-guide/index","path":"/docs/guides/operations-guide/","sidebar":"tutorialSidebar"},{"id":"guides/operations-guide/infrastructure","path":"/docs/guides/operations-guide/infrastructure","sidebar":"tutorialSidebar"},{"id":"guides/operations-guide/manager/apply","path":"/docs/guides/operations-guide/manager/apply","sidebar":"tutorialSidebar"},{"id":"guides/operations-guide/manager/console","path":"/docs/guides/operations-guide/manager/console","sidebar":"tutorialSidebar"},{"id":"guides/operations-guide/manager/get","path":"/docs/guides/operations-guide/manager/get","sidebar":"tutorialSidebar"},{"id":"guides/operations-guide/manager/index","path":"/docs/guides/operations-guide/manager/","sidebar":"tutorialSidebar"},{"id":"guides/operations-guide/manager/log","path":"/docs/guides/operations-guide/manager/log","sidebar":"tutorialSidebar"},{"id":"guides/operations-guide/manager/task","path":"/docs/guides/operations-guide/manager/task","sidebar":"tutorialSidebar"},{"id":"guides/operations-guide/network","path":"/docs/guides/operations-guide/network","sidebar":"tutorialSidebar"},{"id":"guides/operations-guide/openstack/cinder","path":"/docs/guides/operations-guide/openstack/cinder","sidebar":"tutorialSidebar"},{"id":"guides/operations-guide/openstack/index","path":"/docs/guides/operations-guide/openstack/","sidebar":"tutorialSidebar"},{"id":"guides/operations-guide/openstack/keystone","path":"/docs/guides/operations-guide/openstack/keystone","sidebar":"tutorialSidebar"},{"id":"guides/operations-guide/openstack/neutron","path":"/docs/guides/operations-guide/openstack/neutron","sidebar":"tutorialSidebar"},{"id":"guides/operations-guide/openstack/nova","path":"/docs/guides/operations-guide/openstack/nova","sidebar":"tutorialSidebar"},{"id":"guides/operations-guide/openstack/octavia","path":"/docs/guides/operations-guide/openstack/octavia","sidebar":"tutorialSidebar"},{"id":"guides/operations-guide/openstack/tools/flavor-manager","path":"/docs/guides/operations-guide/openstack/tools/flavor-manager","sidebar":"tutorialSidebar"},{"id":"guides/operations-guide/openstack/tools/image-manager/index","path":"/docs/guides/operations-guide/openstack/tools/image-manager/","sidebar":"tutorialSidebar"},{"id":"guides/operations-guide/openstack/tools/image-manager/update","path":"/docs/guides/operations-guide/openstack/tools/image-manager/update","sidebar":"tutorialSidebar"},{"id":"guides/operations-guide/openstack/tools/index","path":"/docs/guides/operations-guide/openstack/tools/","sidebar":"tutorialSidebar"},{"id":"guides/operations-guide/openstack/tools/openstack-health-monitor","path":"/docs/guides/operations-guide/openstack/tools/openstack-health-monitor","sidebar":"tutorialSidebar"},{"id":"guides/operations-guide/openstack/tools/project-manager","path":"/docs/guides/operations-guide/openstack/tools/project-manager","sidebar":"tutorialSidebar"},{"id":"guides/operations-guide/openstack/tools/resource-manager","path":"/docs/guides/operations-guide/openstack/tools/resource-manager","sidebar":"tutorialSidebar"},{"id":"guides/operations-guide/openstack/tools/sandbox-manager","path":"/docs/guides/operations-guide/openstack/tools/sandbox-manager","sidebar":"tutorialSidebar"},{"id":"guides/operations-guide/openstack/tools/simple-stress","path":"/docs/guides/operations-guide/openstack/tools/simple-stress","sidebar":"tutorialSidebar"},{"id":"guides/other-guides/cloud-in-a-box","path":"/docs/guides/other-guides/cloud-in-a-box","sidebar":"tutorialSidebar"},{"id":"guides/other-guides/contributor-guide","path":"/docs/guides/other-guides/contributor-guide","sidebar":"tutorialSidebar"},{"id":"guides/other-guides/developer-guide/index","path":"/docs/guides/other-guides/developer-guide/","sidebar":"tutorialSidebar"},{"id":"guides/other-guides/developer-guide/releases","path":"/docs/guides/other-guides/developer-guide/releases","sidebar":"tutorialSidebar"},{"id":"guides/other-guides/developer-guide/scripts","path":"/docs/guides/other-guides/developer-guide/scripts","sidebar":"tutorialSidebar"},{"id":"guides/other-guides/developer-guide/zuul","path":"/docs/guides/other-guides/developer-guide/zuul","sidebar":"tutorialSidebar"},{"id":"guides/other-guides/index","path":"/docs/guides/other-guides/","sidebar":"tutorialSidebar"},{"id":"guides/other-guides/style-guide","path":"/docs/guides/other-guides/style-guide","sidebar":"tutorialSidebar"},{"id":"guides/other-guides/testbed","path":"/docs/guides/other-guides/testbed","sidebar":"tutorialSidebar"},{"id":"guides/troubleshooting-guide/ceph","path":"/docs/guides/troubleshooting-guide/ceph","sidebar":"tutorialSidebar"},{"id":"guides/troubleshooting-guide/index","path":"/docs/guides/troubleshooting-guide/","sidebar":"tutorialSidebar"},{"id":"guides/troubleshooting-guide/manager","path":"/docs/guides/troubleshooting-guide/manager","sidebar":"tutorialSidebar"},{"id":"guides/troubleshooting-guide/openstack","path":"/docs/guides/troubleshooting-guide/openstack","sidebar":"tutorialSidebar"},{"id":"guides/upgrade-guide/ceph","path":"/docs/guides/upgrade-guide/ceph","sidebar":"tutorialSidebar"},{"id":"guides/upgrade-guide/docker","path":"/docs/guides/upgrade-guide/docker","sidebar":"tutorialSidebar"},{"id":"guides/upgrade-guide/index","path":"/docs/guides/upgrade-guide/","sidebar":"tutorialSidebar"},{"id":"guides/upgrade-guide/infrastructure","path":"/docs/guides/upgrade-guide/infrastructure","sidebar":"tutorialSidebar"},{"id":"guides/upgrade-guide/logging-monitoring","path":"/docs/guides/upgrade-guide/logging-monitoring","sidebar":"tutorialSidebar"},{"id":"guides/upgrade-guide/manager","path":"/docs/guides/upgrade-guide/manager","sidebar":"tutorialSidebar"},{"id":"guides/upgrade-guide/network","path":"/docs/guides/upgrade-guide/network","sidebar":"tutorialSidebar"},{"id":"guides/upgrade-guide/openstack","path":"/docs/guides/upgrade-guide/openstack","sidebar":"tutorialSidebar"},{"id":"guides/user-guide/index","path":"/docs/guides/user-guide/","sidebar":"tutorialSidebar"},{"id":"guides/user-guide/migration-vmware-esix","path":"/docs/guides/user-guide/migration-vmware-esix","sidebar":"tutorialSidebar"},{"id":"guides/user-guide/openstack/index","path":"/docs/guides/user-guide/openstack/","sidebar":"tutorialSidebar"},{"id":"guides/user-guide/openstack/openstackclient","path":"/docs/guides/user-guide/openstack/openstackclient","sidebar":"tutorialSidebar"},{"id":"guides/user-guide/openstack/security-groups","path":"/docs/guides/user-guide/openstack/security-groups","sidebar":"tutorialSidebar"},{"id":"guides/user-guide/openstack/user-data-backups","path":"/docs/guides/user-guide/openstack/user-data-backups","sidebar":"tutorialSidebar"},{"id":"index","path":"/docs/","sidebar":"tutorialSidebar"},{"id":"references/cli","path":"/docs/references/cli","sidebar":"tutorialSidebar"},{"id":"references/configuration","path":"/docs/references/configuration","sidebar":"tutorialSidebar"},{"id":"references/index","path":"/docs/references/","sidebar":"tutorialSidebar"},{"id":"references/parameters","path":"/docs/references/parameters","sidebar":"tutorialSidebar"},{"id":"release-notes/index","path":"/docs/release-notes/","sidebar":"tutorialSidebar"},{"id":"release-notes/osism-7","path":"/docs/release-notes/osism-7","sidebar":"tutorialSidebar"}],"draftIds":[],"sidebars":{"tutorialSidebar":{"link":{"path":"/docs/","label":"Getting started"}}}}],"breadcrumbs":true},"users":{"path":"/users","versions":[{"name":"current","label":"Next","isLast":true,"path":"/users","mainDocId":"index","docs":[{"id":"index","path":"/users/","sidebar":"adaptorsSidebar"}],"draftIds":[],"sidebars":{"adaptorsSidebar":{"link":{"path":"/users/","label":"index"}}}}],"breadcrumbs":true}}}'),a=JSON.parse('{"defaultLocale":"en","locales":["en","de"],"path":"i18n","currentLocale":"en","localeConfigs":{"en":{"label":"English","direction":"ltr","htmlLang":"en","calendar":"gregory","path":"en"},"de":{"label":"Deutsch","direction":"ltr","htmlLang":"de","calendar":"gregory","path":"de"}}}');var s=n(7529);const l=JSON.parse('{"docusaurusVersion":"3.4.0","siteVersion":"0.0.0","pluginVersions":{"docusaurus-plugin-content-docs":{"type":"package","name":"@docusaurus/plugin-content-docs","version":"3.4.0"},"docusaurus-plugin-content-blog":{"type":"package","name":"@docusaurus/plugin-content-blog","version":"3.4.0"},"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"3.4.0"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"3.4.0"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"3.4.0"},"@easyops-cn/docusaurus-search-local":{"type":"package","name":"@easyops-cn/docusaurus-search-local","version":"0.44.2"}}}');var c=n(5893);const u={siteConfig:o.default,siteMetadata:l,globalData:i,i18n:a,codeTranslations:s},d=r.createContext(u);function p(e){let{children:t}=e;return(0,c.jsx)(d.Provider,{value:u,children:t})}},4763:(e,t,n)=>{"use strict";n.d(t,{Z:()=>m});var r=n(7294),o=n(412),i=n(5742),a=n(8780),s=n(8862),l=n(226),c=n(5893);function u(e){let{error:t,tryAgain:n}=e;return(0,c.jsxs)("div",{style:{display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"flex-start",minHeight:"100vh",width:"100%",maxWidth:"80ch",fontSize:"20px",margin:"0 auto",padding:"1rem"},children:[(0,c.jsx)("h1",{style:{fontSize:"3rem"},children:"This page crashed"}),(0,c.jsx)("button",{type:"button",onClick:n,style:{margin:"1rem 0",fontSize:"2rem",cursor:"pointer",borderRadius:20,padding:"1rem"},children:"Try again"}),(0,c.jsx)(d,{error:t})]})}function d(e){let{error:t}=e;const n=(0,a.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return(0,c.jsx)("p",{style:{whiteSpace:"pre-wrap"},children:n})}function p(e){let{children:t}=e;return(0,c.jsx)(l.z,{value:{plugin:{name:"docusaurus-core-error-boundary",id:"default"}},children:t})}function f(e){let{error:t,tryAgain:n}=e;return(0,c.jsx)(p,{children:(0,c.jsxs)(m,{fallback:()=>(0,c.jsx)(u,{error:t,tryAgain:n}),children:[(0,c.jsx)(i.Z,{children:(0,c.jsx)("title",{children:"Page Error"})}),(0,c.jsx)(s.Z,{children:(0,c.jsx)(u,{error:t,tryAgain:n})})]})})}const g=e=>(0,c.jsx)(f,{...e});class m extends r.Component{constructor(e){super(e),this.state={error:null}}componentDidCatch(e){o.Z.canUseDOM&&this.setState({error:e})}render(){const{children:e}=this.props,{error:t}=this.state;if(t){const e={error:t,tryAgain:()=>this.setState({error:null})};return(this.props.fallback??g)(e)}return e??null}}},412:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});const r="undefined"!=typeof window&&"document"in window&&"createElement"in window.document,o={canUseDOM:r,canUseEventListeners:r&&("addEventListener"in window||"attachEvent"in window),canUseIntersectionObserver:r&&"IntersectionObserver"in window,canUseViewport:r&&"screen"in window}},5742:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});n(7294);var r=n(405),o=n(5893);function i(e){return(0,o.jsx)(r.ql,{...e})}},3692:(e,t,n)=>{"use strict";n.d(t,{Z:()=>f});var r=n(7294),o=n(3727),i=n(8780),a=n(2263),s=n(3919),l=n(412),c=n(8138),u=n(4996),d=n(5893);function p(e,t){let{isNavLink:n,to:p,href:f,activeClassName:g,isActive:m,"data-noBrokenLinkCheck":h,autoAddBaseUrl:b=!0,...y}=e;const{siteConfig:v}=(0,a.Z)(),{trailingSlash:w,baseUrl:k}=v,x=v.future.experimental_router,{withBaseUrl:S}=(0,u.Cg)(),_=(0,c.Z)(),E=(0,r.useRef)(null);(0,r.useImperativeHandle)(t,(()=>E.current));const C=p||f;const T=(0,s.Z)(C),L=C?.replace("pathname://","");let P=void 0!==L?(j=L,b&&(e=>e.startsWith("/"))(j)?S(j):j):void 0;var j;"hash"===x&&P?.startsWith("./")&&(P=P?.slice(1)),P&&T&&(P=(0,i.applyTrailingSlash)(P,{trailingSlash:w,baseUrl:k}));const A=(0,r.useRef)(!1),R=n?o.OL:o.rU,N=l.Z.canUseIntersectionObserver,O=(0,r.useRef)(),I=()=>{A.current||null==P||(window.docusaurus.preload(P),A.current=!0)};(0,r.useEffect)((()=>(!N&&T&&null!=P&&window.docusaurus.prefetch(P),()=>{N&&O.current&&O.current.disconnect()})),[O,P,N,T]);const D=P?.startsWith("#")??!1,F=!y.target||"_self"===y.target,M=!P||!T||!F;return h||!D&&M||_.collectLink(P),y.id&&_.collectAnchor(y.id),M?(0,d.jsx)("a",{ref:E,href:P,...C&&!T&&{target:"_blank",rel:"noopener noreferrer"},...y}):(0,d.jsx)(R,{...y,onMouseEnter:I,onTouchStart:I,innerRef:e=>{E.current=e,N&&e&&T&&(O.current=new window.IntersectionObserver((t=>{t.forEach((t=>{e===t.target&&(t.isIntersecting||t.intersectionRatio>0)&&(O.current.unobserve(e),O.current.disconnect(),null!=P&&window.docusaurus.prefetch(P))}))})),O.current.observe(e))},to:P,...n&&{isActive:m,activeClassName:g}})}const f=r.forwardRef(p)},5999:(e,t,n)=>{"use strict";n.d(t,{Z:()=>c,I:()=>l});var r=n(7294),o=n(5893);function i(e,t){const n=e.split(/(\{\w+\})/).map(((e,n)=>{if(n%2==1){const n=t?.[e.slice(1,-1)];if(void 0!==n)return n}return e}));return n.some((e=>(0,r.isValidElement)(e)))?n.map(((e,t)=>(0,r.isValidElement)(e)?r.cloneElement(e,{key:t}):e)).filter((e=>""!==e)):n.join("")}var a=n(7529);function s(e){let{id:t,message:n}=e;if(void 0===t&&void 0===n)throw new Error("Docusaurus translation declarations must have at least a translation id or a default translation message");return a[t??n]??n??t}function l(e,t){let{message:n,id:r}=e;return i(s({message:n,id:r}),t)}function c(e){let{children:t,id:n,values:r}=e;if(t&&"string"!=typeof t)throw console.warn("Illegal children",t),new Error("The Docusaurus component only accept simple string values");const a=s({message:t,id:n});return(0,o.jsx)(o.Fragment,{children:i(a,r)})}},9935:(e,t,n)=>{"use strict";n.d(t,{m:()=>r});const r="default"},3919:(e,t,n)=>{"use strict";function r(e){return/^(?:\w*:|\/\/)/.test(e)}function o(e){return void 0!==e&&!r(e)}n.d(t,{Z:()=>o,b:()=>r})},4996:(e,t,n)=>{"use strict";n.d(t,{Cg:()=>a,ZP:()=>s});var r=n(7294),o=n(2263),i=n(3919);function a(){const{siteConfig:e}=(0,o.Z)(),{baseUrl:t,url:n}=e,a=e.future.experimental_router,s=(0,r.useCallback)(((e,r)=>function(e){let{siteUrl:t,baseUrl:n,url:r,options:{forcePrependBaseUrl:o=!1,absolute:a=!1}={},router:s}=e;if(!r||r.startsWith("#")||(0,i.b)(r))return r;if("hash"===s)return r.startsWith("/")?`.${r}`:`./${r}`;if(o)return n+r.replace(/^\//,"");if(r===n.replace(/\/$/,""))return n;const l=r.startsWith(n)?r:n+r.replace(/^\//,"");return a?t+l:l}({siteUrl:n,baseUrl:t,url:e,options:r,router:a})),[n,t,a]);return{withBaseUrl:s}}function s(e,t){void 0===t&&(t={});const{withBaseUrl:n}=a();return n(e,t)}},8138:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(7294);n(5893);const o=r.createContext({collectAnchor:()=>{},collectLink:()=>{}}),i=()=>(0,r.useContext)(o);function a(){return i()}},2263:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});var r=n(7294),o=n(8940);function i(){return(0,r.useContext)(o._)}},2389:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});var r=n(7294),o=n(8934);function i(){return(0,r.useContext)(o._)}},469:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294);const o=n(412).Z.canUseDOM?r.useLayoutEffect:r.useEffect},5102:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});var r=n(7294),o=n(226);function i(){const e=r.useContext(o._);if(!e)throw new Error("Unexpected: no Docusaurus route context found");return e}},9670:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});const r=e=>"object"==typeof e&&!!e&&Object.keys(e).length>0;function o(e){const t={};return function e(n,o){Object.entries(n).forEach((n=>{let[i,a]=n;const s=o?`${o}.${i}`:i;r(a)?e(a,s):t[s]=a}))}(e),t}},226:(e,t,n)=>{"use strict";n.d(t,{_:()=>i,z:()=>a});var r=n(7294),o=n(5893);const i=r.createContext(null);function a(e){let{children:t,value:n}=e;const a=r.useContext(i),s=(0,r.useMemo)((()=>function(e){let{parent:t,value:n}=e;if(!t){if(!n)throw new Error("Unexpected: no Docusaurus route context found");if(!("plugin"in n))throw new Error("Unexpected: Docusaurus topmost route context has no `plugin` attribute");return n}const r={...t.data,...n?.data};return{plugin:t.plugin,data:r}}({parent:a,value:n})),[a,n]);return(0,o.jsx)(i.Provider,{value:s,children:t})}},143:(e,t,n)=>{"use strict";n.d(t,{Iw:()=>m,gA:()=>p,_r:()=>u,Jo:()=>h,zh:()=>d,yW:()=>g,gB:()=>f});var r=n(6550),o=n(2263),i=n(9935);function a(e,t){void 0===t&&(t={});const n=function(){const{globalData:e}=(0,o.Z)();return e}()[e];if(!n&&t.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin.`);return n}const s=e=>e.versions.find((e=>e.isLast));function l(e,t){const n=function(e,t){const n=s(e);return[...e.versions.filter((e=>e!==n)),n].find((e=>!!(0,r.LX)(t,{path:e.path,exact:!1,strict:!1})))}(e,t),o=n?.docs.find((e=>!!(0,r.LX)(t,{path:e.path,exact:!0,strict:!1})));return{activeVersion:n,activeDoc:o,alternateDocVersions:o?function(t){const n={};return e.versions.forEach((e=>{e.docs.forEach((r=>{r.id===t&&(n[e.name]=r)}))})),n}(o.id):{}}}const c={},u=()=>a("docusaurus-plugin-content-docs")??c,d=e=>{try{return function(e,t,n){void 0===t&&(t=i.m),void 0===n&&(n={});const r=a(e),o=r?.[t];if(!o&&n.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin with id "${t}".`);return o}("docusaurus-plugin-content-docs",e,{failfast:!0})}catch(t){throw new Error("You are using a feature of the Docusaurus docs plugin, but this plugin does not seem to be enabled"+("Default"===e?"":` (pluginId=${e}`),{cause:t})}};function p(e){void 0===e&&(e={});const t=u(),{pathname:n}=(0,r.TH)();return function(e,t,n){void 0===n&&(n={});const o=Object.entries(e).sort(((e,t)=>t[1].path.localeCompare(e[1].path))).find((e=>{let[,n]=e;return!!(0,r.LX)(t,{path:n.path,exact:!1,strict:!1})})),i=o?{pluginId:o[0],pluginData:o[1]}:void 0;if(!i&&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((e=>e.path)).join(", ")}`);return i}(t,n,e)}function f(e){return d(e).versions}function g(e){const t=d(e);return s(t)}function m(e){const t=d(e),{pathname:n}=(0,r.TH)();return l(t,n)}function h(e){const t=d(e),{pathname:n}=(0,r.TH)();return function(e,t){const n=s(e);return{latestDocSuggestion:l(e,t).alternateDocVersions[n.name],latestVersionSuggestion:n}}(t,n)}},8320:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r=n(4865),o=n.n(r);o().configure({showSpinner:!1});const i={onRouteUpdate(e){let{location:t,previousLocation:n}=e;if(n&&t.pathname!==n.pathname){const e=window.setTimeout((()=>{o().start()}),200);return()=>window.clearTimeout(e)}},onRouteDidUpdate(){o().done()}}},3310:(e,t,n)=>{"use strict";n.r(t);var r=n(4965),o=n(6809);!function(e){const{themeConfig:{prism:t}}=o.default,{additionalLanguages:r}=t;globalThis.Prism=e,r.forEach((e=>{"php"===e&&n(6854),n(6726)(`./prism-${e}`)})),delete globalThis.Prism}(r.p1)},2503:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});n(7294);var r=n(6905),o=n(5999),i=n(6668),a=n(3692),s=n(8138);const l={anchorWithStickyNavbar:"anchorWithStickyNavbar_LWe7",anchorWithHideOnScrollNavbar:"anchorWithHideOnScrollNavbar_WYt5"};var c=n(5893);function u(e){let{as:t,id:n,...u}=e;const d=(0,s.Z)(),{navbar:{hideOnScroll:p}}=(0,i.L)();if("h1"===t||!n)return(0,c.jsx)(t,{...u,id:void 0});d.collectAnchor(n);const f=(0,o.I)({id:"theme.common.headingLinkTitle",message:"Direct link to {heading}",description:"Title for link to heading"},{heading:"string"==typeof u.children?u.children:n});return(0,c.jsxs)(t,{...u,className:(0,r.Z)("anchor",p?l.anchorWithHideOnScrollNavbar:l.anchorWithStickyNavbar,u.className),id:n,children:[u.children,(0,c.jsx)(a.Z,{className:"hash-link",to:`#${n}`,"aria-label":f,title:f,children:"\u200b"})]})}},9471:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});n(7294);const r={iconExternalLink:"iconExternalLink_nPIU"};var o=n(5893);function i(e){let{width:t=13.5,height:n=13.5}=e;return(0,o.jsx)("svg",{width:t,height:n,"aria-hidden":"true",viewBox:"0 0 24 24",className:r.iconExternalLink,children:(0,o.jsx)("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"})})}},8862:(e,t,n)=>{"use strict";n.d(t,{Z:()=>Dt});var r=n(7294),o=n(6905),i=n(4763),a=n(8264),s=n(6550),l=n(5999),c=n(5936),u=n(5893);const d="__docusaurus_skipToContent_fallback";function p(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}function f(){const e=(0,r.useRef)(null),{action:t}=(0,s.k6)(),n=(0,r.useCallback)((e=>{e.preventDefault();const t=document.querySelector("main:first-of-type")??document.getElementById(d);t&&p(t)}),[]);return(0,c.S)((n=>{let{location:r}=n;e.current&&!r.hash&&"PUSH"===t&&p(e.current)})),{containerRef:e,onClick:n}}const g=(0,l.I)({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",message:"Skip to main content"});function m(e){const t=e.children??g,{containerRef:n,onClick:r}=f();return(0,u.jsx)("div",{ref:n,role:"region","aria-label":g,children:(0,u.jsx)("a",{...e,href:`#${d}`,onClick:r,children:t})})}var h=n(5281),b=n(9727);const y={skipToContent:"skipToContent_fXgn"};function v(){return(0,u.jsx)(m,{className:y.skipToContent})}var w=n(6668),k=n(9689);function x(e){let{width:t=21,height:n=21,color:r="currentColor",strokeWidth:o=1.2,className:i,...a}=e;return(0,u.jsx)("svg",{viewBox:"0 0 15 15",width:t,height:n,...a,children:(0,u.jsx)("g",{stroke:r,strokeWidth:o,children:(0,u.jsx)("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})})})}const S={closeButton:"closeButton_CVFx"};function _(e){return(0,u.jsx)("button",{type:"button","aria-label":(0,l.I)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"}),...e,className:(0,o.Z)("clean-btn close",S.closeButton,e.className),children:(0,u.jsx)(x,{width:14,height:14,strokeWidth:3.1})})}const E={content:"content_knG7"};function C(e){const{announcementBar:t}=(0,w.L)(),{content:n}=t;return(0,u.jsx)("div",{...e,className:(0,o.Z)(E.content,e.className),dangerouslySetInnerHTML:{__html:n}})}const T={announcementBar:"announcementBar_mb4j",announcementBarPlaceholder:"announcementBarPlaceholder_vyr4",announcementBarClose:"announcementBarClose_gvF7",announcementBarContent:"announcementBarContent_xLdY"};function L(){const{announcementBar:e}=(0,w.L)(),{isActive:t,close:n}=(0,k.n)();if(!t)return null;const{backgroundColor:r,textColor:o,isCloseable:i}=e;return(0,u.jsxs)("div",{className:T.announcementBar,style:{backgroundColor:r,color:o},role:"banner",children:[i&&(0,u.jsx)("div",{className:T.announcementBarPlaceholder}),(0,u.jsx)(C,{className:T.announcementBarContent}),i&&(0,u.jsx)(_,{onClick:n,className:T.announcementBarClose})]})}var P=n(3163),j=n(2466);var A=n(902),R=n(3102);const N=r.createContext(null);function O(e){let{children:t}=e;const n=function(){const e=(0,P.e)(),t=(0,R.HY)(),[n,o]=(0,r.useState)(!1),i=null!==t.component,a=(0,A.D9)(i);return(0,r.useEffect)((()=>{i&&!a&&o(!0)}),[i,a]),(0,r.useEffect)((()=>{i?e.shown||o(!0):o(!1)}),[e.shown,i]),(0,r.useMemo)((()=>[n,o]),[n])}();return(0,u.jsx)(N.Provider,{value:n,children:t})}function I(e){if(e.component){const t=e.component;return(0,u.jsx)(t,{...e.props})}}function D(){const e=(0,r.useContext)(N);if(!e)throw new A.i6("NavbarSecondaryMenuDisplayProvider");const[t,n]=e,o=(0,r.useCallback)((()=>n(!1)),[n]),i=(0,R.HY)();return(0,r.useMemo)((()=>({shown:t,hide:o,content:I(i)})),[o,i,t])}function F(e){let{header:t,primaryMenu:n,secondaryMenu:r}=e;const{shown:i}=D();return(0,u.jsxs)("div",{className:"navbar-sidebar",children:[t,(0,u.jsxs)("div",{className:(0,o.Z)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":i}),children:[(0,u.jsx)("div",{className:"navbar-sidebar__item menu",children:n}),(0,u.jsx)("div",{className:"navbar-sidebar__item menu",children:r})]})]})}var M=n(2949),B=n(2389);function z(e){return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,u.jsx)("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(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,u.jsx)("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"})})}const U={toggle:"toggle_vylO",toggleButton:"toggleButton_gllP",darkToggleIcon:"darkToggleIcon_wfgR",lightToggleIcon:"lightToggleIcon_pyhR",toggleButtonDisabled:"toggleButtonDisabled_aARS"};function q(e){let{className:t,buttonClassName:n,value:r,onChange:i}=e;const a=(0,B.Z)(),s=(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:"dark"===r?(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"})});return(0,u.jsx)("div",{className:(0,o.Z)(U.toggle,t),children:(0,u.jsxs)("button",{className:(0,o.Z)("clean-btn",U.toggleButton,!a&&U.toggleButtonDisabled,n),type:"button",onClick:()=>i("dark"===r?"light":"dark"),disabled:!a,title:s,"aria-label":s,"aria-live":"polite",children:[(0,u.jsx)(z,{className:(0,o.Z)(U.toggleIcon,U.lightToggleIcon)}),(0,u.jsx)($,{className:(0,o.Z)(U.toggleIcon,U.darkToggleIcon)})]})})}const H=r.memo(q),Q={darkNavbarColorModeToggle:"darkNavbarColorModeToggle_X3D1"};function Z(e){let{className:t}=e;const n=(0,w.L)().navbar.style,r=(0,w.L)().colorMode.disableSwitch,{colorMode:o,setColorMode:i}=(0,M.I)();return r?null:(0,u.jsx)(H,{className:t,buttonClassName:"dark"===n?Q.darkNavbarColorModeToggle:void 0,value:o,onChange:i})}var V=n(1327);function W(){return(0,u.jsx)(V.Z,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title text--truncate"})}function G(){const e=(0,P.e)();return(0,u.jsx)("button",{type:"button","aria-label":(0,l.I)({id:"theme.docs.sidebar.closeSidebarButtonAriaLabel",message:"Close navigation bar",description:"The ARIA label for close button of mobile sidebar"}),className:"clean-btn navbar-sidebar__close",onClick:()=>e.toggle(),children:(0,u.jsx)(x,{color:"var(--ifm-color-emphasis-600)"})})}function K(){return(0,u.jsxs)("div",{className:"navbar-sidebar__brand",children:[(0,u.jsx)(W,{}),(0,u.jsx)(Z,{className:"margin-right--md"}),(0,u.jsx)(G,{})]})}var Y=n(3692),X=n(4996),J=n(3919);function ee(e,t){return void 0!==e&&void 0!==t&&new RegExp(e,"gi").test(t)}var te=n(9471);function ne(e){let{activeBasePath:t,activeBaseRegex:n,to:r,href:o,label:i,html:a,isDropdownLink:s,prependBaseUrlToHref:l,...c}=e;const d=(0,X.ZP)(r),p=(0,X.ZP)(t),f=(0,X.ZP)(o,{forcePrependBaseUrl:!0}),g=i&&o&&!(0,J.Z)(o),m=a?{dangerouslySetInnerHTML:{__html:a}}:{children:(0,u.jsxs)(u.Fragment,{children:[i,g&&(0,u.jsx)(te.Z,{...s&&{width:12,height:12}})]})};return o?(0,u.jsx)(Y.Z,{href:l?f:o,...c,...m}):(0,u.jsx)(Y.Z,{to:d,isNavLink:!0,...(t||n)&&{isActive:(e,t)=>n?ee(n,t.pathname):t.pathname.startsWith(p)},...c,...m})}function re(e){let{className:t,isDropdownItem:n=!1,...r}=e;const i=(0,u.jsx)(ne,{className:(0,o.Z)(n?"dropdown__link":"navbar__item navbar__link",t),isDropdownLink:n,...r});return n?(0,u.jsx)("li",{children:i}):i}function oe(e){let{className:t,isDropdownItem:n,...r}=e;return(0,u.jsx)("li",{className:"menu__list-item",children:(0,u.jsx)(ne,{className:(0,o.Z)("menu__link",t),...r})})}function ie(e){let{mobile:t=!1,position:n,...r}=e;const o=t?oe:re;return(0,u.jsx)(o,{...r,activeClassName:r.activeClassName??(t?"menu__link--active":"navbar__link--active")})}var ae=n(6043),se=n(8596),le=n(2263);const ce={dropdownNavbarItemMobile:"dropdownNavbarItemMobile_S0Fm"};function ue(e,t){return e.some((e=>function(e,t){return!!(0,se.Mg)(e.to,t)||!!ee(e.activeBaseRegex,t)||!(!e.activeBasePath||!t.startsWith(e.activeBasePath))}(e,t)))}function de(e){let{items:t,position:n,className:i,onClick:a,...s}=e;const l=(0,r.useRef)(null),[c,d]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{const e=e=>{l.current&&!l.current.contains(e.target)&&d(!1)};return document.addEventListener("mousedown",e),document.addEventListener("touchstart",e),document.addEventListener("focusin",e),()=>{document.removeEventListener("mousedown",e),document.removeEventListener("touchstart",e),document.removeEventListener("focusin",e)}}),[l]),(0,u.jsxs)("div",{ref:l,className:(0,o.Z)("navbar__item","dropdown","dropdown--hoverable",{"dropdown--right":"right"===n,"dropdown--show":c}),children:[(0,u.jsx)(ne,{"aria-haspopup":"true","aria-expanded":c,role:"button",href:s.to?void 0:"#",className:(0,o.Z)("navbar__link",i),...s,onClick:s.to?void 0:e=>e.preventDefault(),onKeyDown:e=>{"Enter"===e.key&&(e.preventDefault(),d(!c))},children:s.children??s.label}),(0,u.jsx)("ul",{className:"dropdown__menu",children:t.map(((e,t)=>(0,r.createElement)(We,{isDropdownItem:!0,activeClassName:"dropdown__link--active",...e,key:t})))})]})}function pe(e){let{items:t,className:n,position:i,onClick:a,...l}=e;const c=function(){const{siteConfig:{baseUrl:e}}=(0,le.Z)(),{pathname:t}=(0,s.TH)();return t.replace(e,"/")}(),d=ue(t,c),{collapsed:p,toggleCollapsed:f,setCollapsed:g}=(0,ae.u)({initialState:()=>!d});return(0,r.useEffect)((()=>{d&&g(!d)}),[c,d,g]),(0,u.jsxs)("li",{className:(0,o.Z)("menu__list-item",{"menu__list-item--collapsed":p}),children:[(0,u.jsx)(ne,{role:"button",className:(0,o.Z)(ce.dropdownNavbarItemMobile,"menu__link menu__link--sublist menu__link--sublist-caret",n),...l,onClick:e=>{e.preventDefault(),f()},children:l.children??l.label}),(0,u.jsx)(ae.z,{lazy:!0,as:"ul",className:"menu__list",collapsed:p,children:t.map(((e,t)=>(0,r.createElement)(We,{mobile:!0,isDropdownItem:!0,onClick:a,activeClassName:"menu__link--active",...e,key:t})))})]})}function fe(e){let{mobile:t=!1,...n}=e;const r=t?pe:de;return(0,u.jsx)(r,{...n})}var ge=n(4711);function me(e){let{width:t=20,height:n=20,...r}=e;return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:t,height:n,"aria-hidden":!0,...r,children:(0,u.jsx)("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"})})}const he="iconLanguage_nlXk";var be=n(1029),ye=n(6010),ve=n(373),we=n(143),ke=n(22),xe=n(8202),Se=n(3545),_e=n(3926),Ee=n(1073),Ce=n(2539),Te=n(726);const Le='',Pe='',je='',Ae='',Re='',Ne='',Oe='',Ie={searchBar:"searchBar_RVTs",dropdownMenu:"dropdownMenu_qbY6",searchBarLeft:"searchBarLeft_MXDe",suggestion:"suggestion_fB_2",cursor:"cursor_eG29",hitTree:"hitTree_kk6K",hitIcon:"hitIcon_a7Zy",hitPath:"hitPath_ieM4",noResultsIcon:"noResultsIcon_EBY5",hitFooter:"hitFooter_E9YW",hitWrapper:"hitWrapper_sAK8",hitTitle:"hitTitle_vyVt",hitAction:"hitAction_NqkB",hideAction:"hideAction_vcyE",noResults:"noResults_l6Q3",searchBarContainer:"searchBarContainer_NW3z",searchBarLoadingRing:"searchBarLoadingRing_YnHq",searchClearButton:"searchClearButton_qk4g",searchIndexLoading:"searchIndexLoading_EJ1f",searchHintContainer:"searchHintContainer_Pkmr",searchHint:"searchHint_iIMx",focused:"focused_OWtg",input:"input_FOTf",hint:"hint_URu1",suggestions:"suggestions_X8XU",dataset:"dataset_QiCy",empty:"empty_eITn"};function De(e){let{document:t,type:n,page:r,metadata:o,tokens:i,isInterOfTree:a,isLastOfTree:s}=e;const l=n===Se.P.Title,c=n===Se.P.Keywords,u=l||c,d=n===Se.P.Heading,p=[];a?p.push(Ne):s&&p.push(Oe);const f=p.map((e=>`${e}`)),g=`${u?Le:d?Pe:je}`,m=[`${c?(0,Ce.C)(t.s,i):(0,Te.o)(t.t,(0,Ee.m)(o,"t"),i)}`];if(!a&&!s&&be.H6){const e=r?r.b?.concat(r.t).concat(t.s&&t.s!==r.t?t.s:[]):t.b;m.push(`${(0,_e.e)(e??[])}`)}else u||m.push(`${(0,Ce.C)(r.t||(t.u.startsWith("/docs/api-reference/")?"API Reference":""),i)}`);const h=`${Ae}`;return[...f,g,``,...m,"",h].join("")}function Fe(){return`${Re}${(0,l.I)({id:"theme.SearchBar.noResultsText",message:"No results"})}`}var Me=n(311),Be=n(51);async function ze(){const e=await Promise.all([n.e(8443),n.e(5525)]).then(n.t.bind(n,8443,23)),t=e.default;return t.noConflict?t.noConflict():e.noConflict&&e.noConflict(),t}const $e="_highlight";const Ue=function(e){let{handleSearchBarToggle:t}=e;const n=(0,B.Z)(),{siteConfig:{baseUrl:o},i18n:{currentLocale:i}}=(0,le.Z)(),a=(0,we.gA)();let c=o;try{const{preferredVersion:e}=(0,ve.J)(a?.pluginId??be.gQ);e&&!e.isLast&&(c=e.path+"/")}catch(F){if(be.l9&&!(F instanceof A.i6))throw F}const d=(0,s.k6)(),p=(0,s.TH)(),f=(0,r.useRef)(null),g=(0,r.useRef)(new Map),m=(0,r.useRef)(!1),[h,b]=(0,r.useState)(!1),[y,v]=(0,r.useState)(!1),[w,k]=(0,r.useState)(""),x=(0,r.useRef)(null),S=(0,r.useRef)(""),[_,E]=(0,r.useState)("");(0,r.useEffect)((()=>{if(!Array.isArray(be.Kc))return;let e="";if(p.pathname.startsWith(c)){const t=p.pathname.substring(c.length);let n;for(const e of be.Kc){const r="string"==typeof e?e:e.path;if(t===r||t.startsWith(`${r}/`)){n=r;break}}n&&(e=n)}S.current!==e&&(g.current.delete(e),S.current=e),E(e)}),[p.pathname,c]);const C=!!be.hG&&Array.isArray(be.Kc)&&""===_,T=(0,r.useCallback)((async()=>{if(C||g.current.get(_))return;g.current.set(_,"loading"),x.current?.autocomplete.destroy(),b(!0);const[{wrappedIndexes:e,zhDictionary:t},n]=await Promise.all([(0,ke.w)(c,_),ze()]);if(x.current=n(f.current,{hint:!1,autoselect:!0,openOnFocus:!0,cssClasses:{root:(0,ye.Z)(Ie.searchBar,{[Ie.searchBarLeft]:"left"===be.pu}),noPrefix:!0,dropdownMenu:Ie.dropdownMenu,input:Ie.input,hint:Ie.hint,suggestions:Ie.suggestions,suggestion:Ie.suggestion,cursor:Ie.cursor,dataset:Ie.dataset,empty:Ie.empty}},[{source:(0,xe.v)(e,t,be.qo),templates:{suggestion:De,empty:Fe,footer:e=>{let{query:t,isEmpty:n}=e;if(n&&(!_||!be.pQ))return;const r=(e=>{let{query:t,isEmpty:n}=e;const r=document.createElement("a"),a=new URLSearchParams;let s;if(a.set("q",t),_){const e=_&&Array.isArray(be.Kc)?be.Kc.find((e=>"string"==typeof e?e===_:e.path===_)):_,t=e?(0,Be._)(e,i).label:_;s=be.pQ&&n?(0,l.I)({id:"theme.SearchBar.seeAllOutsideContext",message:'See all results outside "{context}"'},{context:t}):(0,l.I)({id:"theme.SearchBar.searchInContext",message:'See all results within "{context}"'},{context:t})}else s=(0,l.I)({id:"theme.SearchBar.seeAll",message:"See all results"});if(!_||!Array.isArray(be.Kc)||be.pQ&&n||a.set("ctx",_),c!==o){if(!c.startsWith(o))throw new Error(`Version url '${c}' does not start with base url '${o}', this is a bug of \`@easyops-cn/docusaurus-search-local\`, please report it.`);a.set("version",c.substring(o.length))}const u=`${o}search?${a.toString()}`;return r.href=u,r.textContent=s,r.addEventListener("click",(e=>{e.ctrlKey||e.metaKey||(e.preventDefault(),x.current?.autocomplete.close(),d.push(u))})),r})({query:t,isEmpty:n}),a=document.createElement("div");return a.className=Ie.hitFooter,a.appendChild(r),a}}}]).on("autocomplete:selected",(function(e,t){let{document:{u:n,h:r},tokens:o}=t;f.current?.blur();let i=n;if(be.vc&&o.length>0){const e=new URLSearchParams;for(const t of o)e.append($e,t);i+=`?${e.toString()}`}r&&(i+=r),d.push(i)})).on("autocomplete:closed",(()=>{f.current?.blur()})),g.current.set(_,"done"),b(!1),m.current){const e=f.current;e.value&&x.current?.autocomplete.open(),e.focus()}}),[C,_,c,o,d]);(0,r.useEffect)((()=>{if(!be.vc)return;const e=n?new URLSearchParams(p.search).getAll($e):[];setTimeout((()=>{const t=document.querySelector("article");if(!t)return;const n=new be.vc(t);n.unmark(),0!==e.length&&n.mark(e),k(e.join(" ")),x.current?.autocomplete.setVal(e.join(" "))}))}),[n,p.search,p.pathname]);const[L,P]=(0,r.useState)(!1),j=(0,r.useCallback)((()=>{m.current=!0,T(),P(!0),t?.(!0)}),[t,T]),R=(0,r.useCallback)((()=>{P(!1),t?.(!1)}),[t]),N=(0,r.useCallback)((()=>{T()}),[T]),O=(0,r.useCallback)((e=>{k(e.target.value),e.target.value&&v(!0)}),[]),I=!!n&&/mac/i.test(navigator.userAgentData?.platform??navigator.platform);(0,r.useEffect)((()=>{if(!be.AY)return;const e=e=>{!(I?e.metaKey:e.ctrlKey)||"k"!==e.key&&"K"!==e.key||(e.preventDefault(),f.current?.focus(),j())};return document.addEventListener("keydown",e),()=>{document.removeEventListener("keydown",e)}}),[I,j]);const D=(0,r.useCallback)((()=>{const e=new URLSearchParams(p.search);e.delete($e);const t=e.toString(),n=p.pathname+(""!=t?`?${t}`:"")+p.hash;n!=p.pathname+p.search+p.hash&&d.push(n),k(""),x.current?.autocomplete.setVal("")}),[p.pathname,p.search,p.hash,d]);return(0,u.jsxs)("div",{className:(0,ye.Z)("navbar__search",Ie.searchBarContainer,{[Ie.searchIndexLoading]:h&&y,[Ie.focused]:L}),hidden:C,dir:"ltr",children:[(0,u.jsx)("input",{placeholder:(0,l.I)({id:"theme.SearchBar.label",message:"Search",description:"The ARIA label and placeholder for search button"}),"aria-label":"Search",className:"navbar__search-input",onMouseEnter:N,onFocus:j,onBlur:R,onChange:O,ref:f,value:w}),(0,u.jsx)(Me.Z,{className:Ie.searchBarLoadingRing}),be.AY&&be.t_&&(""!==w?(0,u.jsx)("button",{className:Ie.searchClearButton,onClick:D,children:"\u2715"}):n&&(0,u.jsxs)("div",{className:Ie.searchHintContainer,children:[(0,u.jsx)("kbd",{className:Ie.searchHint,children:I?"\u2318":"ctrl"}),(0,u.jsx)("kbd",{className:Ie.searchHint,children:"K"})]}))]})},qe={navbarSearchContainer:"navbarSearchContainer_Bca1"};function He(e){let{children:t,className:n}=e;return(0,u.jsx)("div",{className:(0,o.Z)(n,qe.navbarSearchContainer),children:t})}var Qe=n(3438);const Ze=e=>e.docs.find((t=>t.id===e.mainDocId));const Ve={default:ie,localeDropdown:function(e){let{mobile:t,dropdownItemsBefore:n,dropdownItemsAfter:r,queryString:o="",...i}=e;const{i18n:{currentLocale:a,locales:c,localeConfigs:d}}=(0,le.Z)(),p=(0,ge.l)(),{search:f,hash:g}=(0,s.TH)(),m=[...n,...c.map((e=>{const n=`${`pathname://${p.createUrl({locale:e,fullyQualified:!1})}`}${f}${g}${o}`;return{label:d[e].label,lang:d[e].htmlLang,to:n,target:"_self",autoAddBaseUrl:!1,className:e===a?t?"menu__link--active":"dropdown__link--active":""}})),...r],h=t?(0,l.I)({message:"Languages",id:"theme.navbar.mobileLanguageDropdown.label",description:"The label for the mobile language switcher dropdown"}):d[a].label;return(0,u.jsx)(fe,{...i,mobile:t,label:(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(me,{className:he}),h]}),items:m})},search:function(e){let{mobile:t,className:n}=e;return t?null:(0,u.jsx)(He,{className:n,children:(0,u.jsx)(Ue,{})})},dropdown:fe,html:function(e){let{value:t,className:n,mobile:r=!1,isDropdownItem:i=!1}=e;const a=i?"li":"div";return(0,u.jsx)(a,{className:(0,o.Z)({navbar__item:!r&&!i,"menu__list-item":r},n),dangerouslySetInnerHTML:{__html:t}})},doc:function(e){let{docId:t,label:n,docsPluginId:r,...o}=e;const{activeDoc:i}=(0,we.Iw)(r),a=(0,Qe.vY)(t,r),s=i?.path===a?.path;return null===a||a.unlisted&&!s?null:(0,u.jsx)(ie,{exact:!0,...o,isActive:()=>s||!!i?.sidebar&&i.sidebar===a.sidebar,label:n??a.id,to:a.path})},docSidebar:function(e){let{sidebarId:t,label:n,docsPluginId:r,...o}=e;const{activeDoc:i}=(0,we.Iw)(r),a=(0,Qe.oz)(t,r).link;if(!a)throw new Error(`DocSidebarNavbarItem: Sidebar with ID "${t}" doesn't have anything to be linked to.`);return(0,u.jsx)(ie,{exact:!0,...o,isActive:()=>i?.sidebar===t,label:n??a.label,to:a.path})},docsVersion:function(e){let{label:t,to:n,docsPluginId:r,...o}=e;const i=(0,Qe.lO)(r)[0],a=t??i.label,s=n??(e=>e.docs.find((t=>t.id===e.mainDocId)))(i).path;return(0,u.jsx)(ie,{...o,label:a,to:s})},docsVersionDropdown:function(e){let{mobile:t,docsPluginId:n,dropdownActiveClassDisabled:r,dropdownItemsBefore:o,dropdownItemsAfter:i,...a}=e;const{search:c,hash:d}=(0,s.TH)(),p=(0,we.Iw)(n),f=(0,we.gB)(n),{savePreferredVersionName:g}=(0,ve.J)(n),m=[...o,...f.map((e=>{const t=p.alternateDocVersions[e.name]??Ze(e);return{label:e.label,to:`${t.path}${c}${d}`,isActive:()=>e===p.activeVersion,onClick:()=>g(e.name)}})),...i],h=(0,Qe.lO)(n)[0],b=t&&m.length>1?(0,l.I)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):h.label,y=t&&m.length>1?void 0:Ze(h).path;return m.length<=1?(0,u.jsx)(ie,{...a,mobile:t,label:b,to:y,isActive:r?()=>!1:void 0}):(0,u.jsx)(fe,{...a,mobile:t,label:b,to:y,items:m,isActive:r?()=>!1:void 0})}};function We(e){let{type:t,...n}=e;const r=function(e,t){return e&&"default"!==e?e:"items"in t?"dropdown":"default"}(t,n),o=Ve[r];if(!o)throw new Error(`No NavbarItem component found for type "${t}".`);return(0,u.jsx)(o,{...n})}function Ge(){const e=(0,P.e)(),t=(0,w.L)().navbar.items;return(0,u.jsx)("ul",{className:"menu__list",children:t.map(((t,n)=>(0,r.createElement)(We,{mobile:!0,...t,onClick:()=>e.toggle(),key:n})))})}function Ke(e){return(0,u.jsx)("button",{...e,type:"button",className:"clean-btn navbar-sidebar__back",children:(0,u.jsx)(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)",children:"\u2190 Back to main menu"})})}function Ye(){const e=0===(0,w.L)().navbar.items.length,t=D();return(0,u.jsxs)(u.Fragment,{children:[!e&&(0,u.jsx)(Ke,{onClick:()=>t.hide()}),t.content]})}function Xe(){const e=(0,P.e)();var t;return void 0===(t=e.shown)&&(t=!0),(0,r.useEffect)((()=>(document.body.style.overflow=t?"hidden":"visible",()=>{document.body.style.overflow="visible"})),[t]),e.shouldRender?(0,u.jsx)(F,{header:(0,u.jsx)(K,{}),primaryMenu:(0,u.jsx)(Ge,{}),secondaryMenu:(0,u.jsx)(Ye,{})}):null}const Je={navbarHideable:"navbarHideable_m1mJ",navbarHidden:"navbarHidden_jGov"};function et(e){return(0,u.jsx)("div",{role:"presentation",...e,className:(0,o.Z)("navbar-sidebar__backdrop",e.className)})}function tt(e){let{children:t}=e;const{navbar:{hideOnScroll:n,style:i}}=(0,w.L)(),a=(0,P.e)(),{navbarRef:s,isNavbarVisible:d}=function(e){const[t,n]=(0,r.useState)(e),o=(0,r.useRef)(!1),i=(0,r.useRef)(0),a=(0,r.useCallback)((e=>{null!==e&&(i.current=e.getBoundingClientRect().height)}),[]);return(0,j.RF)(((t,r)=>{let{scrollY:a}=t;if(!e)return;if(a=s?n(!1):a+c{if(!e)return;const r=t.location.hash;if(r?document.getElementById(r.substring(1)):void 0)return o.current=!0,void n(!1);n(!0)})),{navbarRef:a,isNavbarVisible:t}}(n);return(0,u.jsxs)("nav",{ref:s,"aria-label":(0,l.I)({id:"theme.NavBar.navAriaLabel",message:"Main",description:"The ARIA label for the main navigation"}),className:(0,o.Z)("navbar","navbar--fixed-top",n&&[Je.navbarHideable,!d&&Je.navbarHidden],{"navbar--dark":"dark"===i,"navbar--primary":"primary"===i,"navbar-sidebar--show":a.shown}),children:[t,(0,u.jsx)(et,{onClick:a.toggle}),(0,u.jsx)(Xe,{})]})}var nt=n(8780);const rt={errorBoundaryError:"errorBoundaryError_a6uf",errorBoundaryFallback:"errorBoundaryFallback_VBag"};function ot(e){return(0,u.jsx)("button",{type:"button",...e,children:(0,u.jsx)(l.Z,{id:"theme.ErrorPageContent.tryAgain",description:"The label of the button to try again rendering when the React error boundary captures an error",children:"Try again"})})}function it(e){let{error:t}=e;const n=(0,nt.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return(0,u.jsx)("p",{className:rt.errorBoundaryError,children:n})}class at extends r.Component{componentDidCatch(e,t){throw this.props.onError(e,t)}render(){return this.props.children}}const st="right";function lt(e){let{width:t=30,height:n=30,className:r,...o}=e;return(0,u.jsx)("svg",{className:r,width:t,height:n,viewBox:"0 0 30 30","aria-hidden":"true",...o,children:(0,u.jsx)("path",{stroke:"currentColor",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"2",d:"M4 7h22M4 15h22M4 23h22"})})}function ct(){const{toggle:e,shown:t}=(0,P.e)();return(0,u.jsx)("button",{onClick:e,"aria-label":(0,l.I)({id:"theme.docs.sidebar.toggleSidebarButtonAriaLabel",message:"Toggle navigation bar",description:"The ARIA label for hamburger menu button of mobile navigation"}),"aria-expanded":t,className:"navbar__toggle clean-btn",type:"button",children:(0,u.jsx)(lt,{})})}const ut={colorModeToggle:"colorModeToggle_DEke"};function dt(e){let{items:t}=e;return(0,u.jsx)(u.Fragment,{children:t.map(((e,t)=>(0,u.jsx)(at,{onError:t=>new Error(`A theme navbar item failed to render.\nPlease double-check the following navbar item (themeConfig.navbar.items) of your Docusaurus config:\n${JSON.stringify(e,null,2)}`,{cause:t}),children:(0,u.jsx)(We,{...e})},t)))})}function pt(e){let{left:t,right:n}=e;return(0,u.jsxs)("div",{className:"navbar__inner",children:[(0,u.jsx)("div",{className:"navbar__items",children:t}),(0,u.jsx)("div",{className:"navbar__items navbar__items--right",children:n})]})}function ft(){const e=(0,P.e)(),t=(0,w.L)().navbar.items,[n,r]=function(e){function t(e){return"left"===(e.position??st)}return[e.filter(t),e.filter((e=>!t(e)))]}(t),o=t.find((e=>"search"===e.type));return(0,u.jsx)(pt,{left:(0,u.jsxs)(u.Fragment,{children:[!e.disabled&&(0,u.jsx)(ct,{}),(0,u.jsx)(W,{}),(0,u.jsx)(dt,{items:n})]}),right:(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(dt,{items:r}),(0,u.jsx)(Z,{className:ut.colorModeToggle}),!o&&(0,u.jsx)(He,{children:(0,u.jsx)(Ue,{})})]})})}function gt(){return(0,u.jsx)(tt,{children:(0,u.jsx)(ft,{})})}function mt(e){let{item:t}=e;const{to:n,href:r,label:o,prependBaseUrlToHref:i,...a}=t,s=(0,X.ZP)(n),l=(0,X.ZP)(r,{forcePrependBaseUrl:!0});return(0,u.jsxs)(Y.Z,{className:"footer__link-item",...r?{href:i?l:r}:{to:s},...a,children:[o,r&&!(0,J.Z)(r)&&(0,u.jsx)(te.Z,{})]})}function ht(e){let{item:t}=e;return t.html?(0,u.jsx)("li",{className:"footer__item",dangerouslySetInnerHTML:{__html:t.html}}):(0,u.jsx)("li",{className:"footer__item",children:(0,u.jsx)(mt,{item:t})},t.href??t.to)}function bt(e){let{column:t}=e;return(0,u.jsxs)("div",{className:"col footer__col",children:[(0,u.jsx)("div",{className:"footer__title",children:t.title}),(0,u.jsx)("ul",{className:"footer__items clean-list",children:t.items.map(((e,t)=>(0,u.jsx)(ht,{item:e},t)))})]})}function yt(e){let{columns:t}=e;return(0,u.jsx)("div",{className:"row footer__links",children:t.map(((e,t)=>(0,u.jsx)(bt,{column:e},t)))})}function vt(){return(0,u.jsx)("span",{className:"footer__link-separator",children:"\xb7"})}function wt(e){let{item:t}=e;return t.html?(0,u.jsx)("span",{className:"footer__link-item",dangerouslySetInnerHTML:{__html:t.html}}):(0,u.jsx)(mt,{item:t})}function kt(e){let{links:t}=e;return(0,u.jsx)("div",{className:"footer__links text--center",children:(0,u.jsx)("div",{className:"footer__links",children:t.map(((e,n)=>(0,u.jsxs)(r.Fragment,{children:[(0,u.jsx)(wt,{item:e}),t.length!==n+1&&(0,u.jsx)(vt,{})]},n)))})})}function xt(e){let{links:t}=e;return function(e){return"title"in e[0]}(t)?(0,u.jsx)(yt,{columns:t}):(0,u.jsx)(kt,{links:t})}var St=n(9965);const _t={footerLogoLink:"footerLogoLink_BH7S"};function Et(e){let{logo:t}=e;const{withBaseUrl:n}=(0,X.Cg)(),r={light:n(t.src),dark:n(t.srcDark??t.src)};return(0,u.jsx)(St.Z,{className:(0,o.Z)("footer__logo",t.className),alt:t.alt,sources:r,width:t.width,height:t.height,style:t.style})}function Ct(e){let{logo:t}=e;return t.href?(0,u.jsx)(Y.Z,{href:t.href,className:_t.footerLogoLink,target:t.target,children:(0,u.jsx)(Et,{logo:t})}):(0,u.jsx)(Et,{logo:t})}function Tt(e){let{copyright:t}=e;return(0,u.jsx)("div",{className:"footer__copyright",dangerouslySetInnerHTML:{__html:t}})}function Lt(e){let{style:t,links:n,logo:r,copyright:i}=e;return(0,u.jsx)("footer",{className:(0,o.Z)("footer",{"footer--dark":"dark"===t}),children:(0,u.jsxs)("div",{className:"container container-fluid",children:[n,(r||i)&&(0,u.jsxs)("div",{className:"footer__bottom text--center",children:[r&&(0,u.jsx)("div",{className:"margin-bottom--sm",children:r}),i]})]})})}function Pt(){const{footer:e}=(0,w.L)();if(!e)return null;const{copyright:t,links:n,logo:r,style:o}=e;return(0,u.jsx)(Lt,{style:o,links:n&&n.length>0&&(0,u.jsx)(xt,{links:n}),logo:r&&(0,u.jsx)(Ct,{logo:r}),copyright:t&&(0,u.jsx)(Tt,{copyright:t})})}const jt=r.memo(Pt),At=(0,A.Qc)([M.S,k.p,j.OC,ve.L5,a.VC,function(e){let{children:t}=e;return(0,u.jsx)(R.n2,{children:(0,u.jsx)(P.M,{children:(0,u.jsx)(O,{children:t})})})}]);function Rt(e){let{children:t}=e;return(0,u.jsx)(At,{children:t})}var Nt=n(2503);function Ot(e){let{error:t,tryAgain:n}=e;return(0,u.jsx)("main",{className:"container margin-vert--xl",children:(0,u.jsx)("div",{className:"row",children:(0,u.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,u.jsx)(Nt.Z,{as:"h1",className:"hero__title",children:(0,u.jsx)(l.Z,{id:"theme.ErrorPageContent.title",description:"The title of the fallback page when the page crashed",children:"This page crashed."})}),(0,u.jsx)("div",{className:"margin-vert--lg",children:(0,u.jsx)(ot,{onClick:n,className:"button button--primary shadow--lw"})}),(0,u.jsx)("hr",{}),(0,u.jsx)("div",{className:"margin-vert--md",children:(0,u.jsx)(it,{error:t})})]})})})}const It={mainWrapper:"mainWrapper_z2l0"};function Dt(e){const{children:t,noFooter:n,wrapperClassName:r,title:s,description:l}=e;return(0,b.t)(),(0,u.jsxs)(Rt,{children:[(0,u.jsx)(a.d,{title:s,description:l}),(0,u.jsx)(v,{}),(0,u.jsx)(L,{}),(0,u.jsx)(gt,{}),(0,u.jsx)("div",{id:d,className:(0,o.Z)(h.k.wrapper.main,It.mainWrapper,r),children:(0,u.jsx)(i.Z,{fallback:e=>(0,u.jsx)(Ot,{...e}),children:t})}),!n&&(0,u.jsx)(jt,{})]})}},1327:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});n(7294);var r=n(3692),o=n(4996),i=n(2263),a=n(6668),s=n(9965),l=n(5893);function c(e){let{logo:t,alt:n,imageClassName:r}=e;const i={light:(0,o.ZP)(t.src),dark:(0,o.ZP)(t.srcDark||t.src)},a=(0,l.jsx)(s.Z,{className:t.className,sources:i,height:t.height,width:t.width,alt:n,style:t.style});return r?(0,l.jsx)("div",{className:r,children:a}):a}function u(e){const{siteConfig:{title:t}}=(0,i.Z)(),{navbar:{title:n,logo:s}}=(0,a.L)(),{imageClassName:u,titleClassName:d,...p}=e,f=(0,o.ZP)(s?.href||"/"),g=n?"":t,m=s?.alt??g;return(0,l.jsxs)(r.Z,{to:f,...p,...s?.target&&{target:s.target},children:[s&&(0,l.jsx)(c,{logo:s,alt:m,imageClassName:u}),null!=n&&(0,l.jsx)("b",{className:d,children:n})]})}},197:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});n(7294);var r=n(5742),o=n(5893);function i(e){let{locale:t,version:n,tag:i}=e;const a=t;return(0,o.jsxs)(r.Z,{children:[t&&(0,o.jsx)("meta",{name:"docusaurus_locale",content:t}),n&&(0,o.jsx)("meta",{name:"docusaurus_version",content:n}),i&&(0,o.jsx)("meta",{name:"docusaurus_tag",content:i}),a&&(0,o.jsx)("meta",{name:"docsearch:language",content:a}),n&&(0,o.jsx)("meta",{name:"docsearch:version",content:n}),i&&(0,o.jsx)("meta",{name:"docsearch:docusaurus_tag",content:i})]})}},9965:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});var r=n(7294),o=n(788),i=n(2389),a=n(2949);const s={themedComponent:"themedComponent_mlkZ","themedComponent--light":"themedComponent--light_NVdE","themedComponent--dark":"themedComponent--dark_xIcU"};var l=n(5893);function c(e){let{className:t,children:n}=e;const c=(0,i.Z)(),{colorMode:u}=(0,a.I)();return(0,l.jsx)(l.Fragment,{children:(c?"dark"===u?["dark"]:["light"]:["light","dark"]).map((e=>{const i=n({theme:e,className:(0,o.Z)(t,s.themedComponent,s[`themedComponent--${e}`])});return(0,l.jsx)(r.Fragment,{children:i},e)}))})}function u(e){const{sources:t,className:n,alt:r,...o}=e;return(0,l.jsx)(c,{className:n,children:e=>{let{theme:n,className:i}=e;return(0,l.jsx)("img",{src:t[n],alt:r,className:i,...o})}})}},6043:(e,t,n)=>{"use strict";n.d(t,{u:()=>c,z:()=>b});var r=n(7294),o=n(412),i=n(469),a=n(1442),s=n(5893);const l="ease-in-out";function c(e){let{initialState:t}=e;const[n,o]=(0,r.useState)(t??!1),i=(0,r.useCallback)((()=>{o((e=>!e))}),[]);return{collapsed:n,setCollapsed:o,toggleCollapsed:i}}const u={display:"none",overflow:"hidden",height:"0px"},d={display:"block",overflow:"visible",height:"auto"};function p(e,t){const n=t?u:d;e.style.display=n.display,e.style.overflow=n.overflow,e.style.height=n.height}function f(e){let{collapsibleRef:t,collapsed:n,animation:o}=e;const i=(0,r.useRef)(!1);(0,r.useEffect)((()=>{const e=t.current;function r(){const t=e.scrollHeight,n=o?.duration??function(e){if((0,a.n)())return 1;const t=e/36;return Math.round(10*(4+15*t**.25+t/5))}(t);return{transition:`height ${n}ms ${o?.easing??l}`,height:`${t}px`}}function s(){const t=r();e.style.transition=t.transition,e.style.height=t.height}if(!i.current)return p(e,n),void(i.current=!0);return e.style.willChange="height",function(){const t=requestAnimationFrame((()=>{n?(s(),requestAnimationFrame((()=>{e.style.height=u.height,e.style.overflow=u.overflow}))):(e.style.display="block",requestAnimationFrame((()=>{s()})))}));return()=>cancelAnimationFrame(t)}()}),[t,n,o])}function g(e){if(!o.Z.canUseDOM)return e?u:d}function m(e){let{as:t="div",collapsed:n,children:o,animation:i,onCollapseTransitionEnd:a,className:l,disableSSRStyle:c}=e;const u=(0,r.useRef)(null);return f({collapsibleRef:u,collapsed:n,animation:i}),(0,s.jsx)(t,{ref:u,style:c?void 0:g(n),onTransitionEnd:e=>{"height"===e.propertyName&&(p(u.current,n),a?.(n))},className:l,children:o})}function h(e){let{collapsed:t,...n}=e;const[o,a]=(0,r.useState)(!t),[l,c]=(0,r.useState)(t);return(0,i.Z)((()=>{t||a(!0)}),[t]),(0,i.Z)((()=>{o&&c(t)}),[o,t]),o?(0,s.jsx)(m,{...n,collapsed:l}):null}function b(e){let{lazy:t,...n}=e;const r=t?h:m;return(0,s.jsx)(r,{...n})}},9689:(e,t,n)=>{"use strict";n.d(t,{n:()=>m,p:()=>g});var r=n(7294),o=n(2389),i=n(812),a=n(902),s=n(6668),l=n(5893);const c=(0,i.WA)("docusaurus.announcement.dismiss"),u=(0,i.WA)("docusaurus.announcement.id"),d=()=>"true"===c.get(),p=e=>c.set(String(e)),f=r.createContext(null);function g(e){let{children:t}=e;const n=function(){const{announcementBar:e}=(0,s.L)(),t=(0,o.Z)(),[n,i]=(0,r.useState)((()=>!!t&&d()));(0,r.useEffect)((()=>{i(d())}),[]);const a=(0,r.useCallback)((()=>{p(!0),i(!0)}),[]);return(0,r.useEffect)((()=>{if(!e)return;const{id:t}=e;let n=u.get();"annoucement-bar"===n&&(n="announcement-bar");const r=t!==n;u.set(t),r&&p(!1),!r&&d()||i(!1)}),[e]),(0,r.useMemo)((()=>({isActive:!!e&&!n,close:a})),[e,n,a])}();return(0,l.jsx)(f.Provider,{value:n,children:t})}function m(){const e=(0,r.useContext)(f);if(!e)throw new a.i6("AnnouncementBarProvider");return e}},2949:(e,t,n)=>{"use strict";n.d(t,{I:()=>b,S:()=>h});var r=n(7294),o=n(412),i=n(902),a=n(812),s=n(6668),l=n(5893);const c=r.createContext(void 0),u="theme",d=(0,a.WA)(u),p={light:"light",dark:"dark"},f=e=>e===p.dark?p.dark:p.light,g=e=>o.Z.canUseDOM?f(document.documentElement.getAttribute("data-theme")):f(e),m=e=>{d.set(f(e))};function h(e){let{children:t}=e;const n=function(){const{colorMode:{defaultMode:e,disableSwitch:t,respectPrefersColorScheme:n}}=(0,s.L)(),[o,i]=(0,r.useState)(g(e));(0,r.useEffect)((()=>{t&&d.del()}),[t]);const a=(0,r.useCallback)((function(t,r){void 0===r&&(r={});const{persist:o=!0}=r;t?(i(t),o&&m(t)):(i(n?window.matchMedia("(prefers-color-scheme: dark)").matches?p.dark:p.light:e),d.del())}),[n,e]);(0,r.useEffect)((()=>{document.documentElement.setAttribute("data-theme",f(o))}),[o]),(0,r.useEffect)((()=>{if(t)return;const e=e=>{if(e.key!==u)return;const t=d.get();null!==t&&a(f(t))};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)}),[t,a]);const l=(0,r.useRef)(!1);return(0,r.useEffect)((()=>{if(t&&!n)return;const e=window.matchMedia("(prefers-color-scheme: dark)"),r=()=>{window.matchMedia("print").matches||l.current?l.current=window.matchMedia("print").matches:a(null)};return e.addListener(r),()=>e.removeListener(r)}),[a,t,n]),(0,r.useMemo)((()=>({colorMode:o,setColorMode:a,get isDarkTheme(){return o===p.dark},setLightTheme(){a(p.light)},setDarkTheme(){a(p.dark)}})),[o,a])}();return(0,l.jsx)(c.Provider,{value:n,children:t})}function b(){const e=(0,r.useContext)(c);if(null==e)throw new i.i6("ColorModeProvider","Please see https://docusaurus.io/docs/api/themes/configuration#use-color-mode.");return e}},373:(e,t,n)=>{"use strict";n.d(t,{J:()=>v,L5:()=>b});var r=n(7294),o=n(143),i=n(9935),a=n(6668),s=n(3438),l=n(902),c=n(812),u=n(5893);const d=e=>`docs-preferred-version-${e}`,p={save:(e,t,n)=>{(0,c.WA)(d(e),{persistence:t}).set(n)},read:(e,t)=>(0,c.WA)(d(e),{persistence:t}).get(),clear:(e,t)=>{(0,c.WA)(d(e),{persistence:t}).del()}},f=e=>Object.fromEntries(e.map((e=>[e,{preferredVersionName:null}])));const g=r.createContext(null);function m(){const e=(0,o._r)(),t=(0,a.L)().docs.versionPersistence,n=(0,r.useMemo)((()=>Object.keys(e)),[e]),[i,s]=(0,r.useState)((()=>f(n)));(0,r.useEffect)((()=>{s(function(e){let{pluginIds:t,versionPersistence:n,allDocsData:r}=e;function o(e){const t=p.read(e,n);return r[e].versions.some((e=>e.name===t))?{preferredVersionName:t}:(p.clear(e,n),{preferredVersionName:null})}return Object.fromEntries(t.map((e=>[e,o(e)])))}({allDocsData:e,versionPersistence:t,pluginIds:n}))}),[e,t,n]);return[i,(0,r.useMemo)((()=>({savePreferredVersion:function(e,n){p.save(e,t,n),s((t=>({...t,[e]:{preferredVersionName:n}})))}})),[t])]}function h(e){let{children:t}=e;const n=m();return(0,u.jsx)(g.Provider,{value:n,children:t})}function b(e){let{children:t}=e;return s.cE?(0,u.jsx)(h,{children:t}):(0,u.jsx)(u.Fragment,{children:t})}function y(){const e=(0,r.useContext)(g);if(!e)throw new l.i6("DocsPreferredVersionContextProvider");return e}function v(e){void 0===e&&(e=i.m);const t=(0,o.zh)(e),[n,a]=y(),{preferredVersionName:s}=n[e];return{preferredVersion:t.versions.find((e=>e.name===s))??null,savePreferredVersionName:(0,r.useCallback)((t=>{a.savePreferredVersion(e,t)}),[a,e])}}},1116:(e,t,n)=>{"use strict";n.d(t,{V:()=>c,b:()=>l});var r=n(7294),o=n(902),i=n(5893);const a=Symbol("EmptyContext"),s=r.createContext(a);function l(e){let{children:t,name:n,items:o}=e;const a=(0,r.useMemo)((()=>n&&o?{name:n,items:o}:null),[n,o]);return(0,i.jsx)(s.Provider,{value:a,children:t})}function c(){const e=(0,r.useContext)(s);if(e===a)throw new o.i6("DocsSidebarProvider");return e}},4477:(e,t,n)=>{"use strict";n.d(t,{E:()=>l,q:()=>s});var r=n(7294),o=n(902),i=n(5893);const a=r.createContext(null);function s(e){let{children:t,version:n}=e;return(0,i.jsx)(a.Provider,{value:n,children:t})}function l(){const e=(0,r.useContext)(a);if(null===e)throw new o.i6("DocsVersionProvider");return e}},3163:(e,t,n)=>{"use strict";n.d(t,{M:()=>p,e:()=>f});var r=n(7294),o=n(3102),i=n(7524),a=n(1980),s=n(6668),l=n(902),c=n(5893);const u=r.createContext(void 0);function d(){const e=function(){const e=(0,o.HY)(),{items:t}=(0,s.L)().navbar;return 0===t.length&&!e.component}(),t=(0,i.i)(),n=!e&&"mobile"===t,[l,c]=(0,r.useState)(!1);(0,a.Rb)((()=>{if(l)return c(!1),!1}));const u=(0,r.useCallback)((()=>{c((e=>!e))}),[]);return(0,r.useEffect)((()=>{"desktop"===t&&c(!1)}),[t]),(0,r.useMemo)((()=>({disabled:e,shouldRender:n,toggle:u,shown:l})),[e,n,u,l])}function p(e){let{children:t}=e;const n=d();return(0,c.jsx)(u.Provider,{value:n,children:t})}function f(){const e=r.useContext(u);if(void 0===e)throw new l.i6("NavbarMobileSidebarProvider");return e}},3102:(e,t,n)=>{"use strict";n.d(t,{HY:()=>l,Zo:()=>c,n2:()=>s});var r=n(7294),o=n(902),i=n(5893);const a=r.createContext(null);function s(e){let{children:t}=e;const n=(0,r.useState)({component:null,props:null});return(0,i.jsx)(a.Provider,{value:n,children:t})}function l(){const e=(0,r.useContext)(a);if(!e)throw new o.i6("NavbarSecondaryMenuContentProvider");return e[0]}function c(e){let{component:t,props:n}=e;const i=(0,r.useContext)(a);if(!i)throw new o.i6("NavbarSecondaryMenuContentProvider");const[,s]=i,l=(0,o.Ql)(n);return(0,r.useEffect)((()=>{s({component:t,props:l})}),[s,t,l]),(0,r.useEffect)((()=>()=>s({component:null,props:null})),[s]),null}},9727:(e,t,n)=>{"use strict";n.d(t,{h:()=>o,t:()=>i});var r=n(7294);const o="navigation-with-keyboard";function i(){(0,r.useEffect)((()=>{function e(e){"keydown"===e.type&&"Tab"===e.key&&document.body.classList.add(o),"mousedown"===e.type&&document.body.classList.remove(o)}return document.addEventListener("keydown",e),document.addEventListener("mousedown",e),()=>{document.body.classList.remove(o),document.removeEventListener("keydown",e),document.removeEventListener("mousedown",e)}}),[])}},7524:(e,t,n)=>{"use strict";n.d(t,{i:()=>s});var r=n(7294),o=n(412);const i={desktop:"desktop",mobile:"mobile",ssr:"ssr"},a=996;function s(e){let{desktopBreakpoint:t=a}=void 0===e?{}:e;const[n,s]=(0,r.useState)((()=>"ssr"));return(0,r.useEffect)((()=>{function e(){s(function(e){if(!o.Z.canUseDOM)throw new Error("getWindowSize() should only be called after React hydration");return window.innerWidth>e?i.desktop:i.mobile}(t))}return e(),window.addEventListener("resize",e),()=>{window.removeEventListener("resize",e)}}),[t]),n}},5281:(e,t,n)=>{"use strict";n.d(t,{k:()=>r});const r={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",admonition:"theme-admonition",unlistedBanner:"theme-unlisted-banner",admonitionType:e=>`theme-admonition-${e}`},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:e=>`theme-doc-sidebar-item-category-level-${e}`,docSidebarItemLinkLevel:e=>`theme-doc-sidebar-item-link-level-${e}`},blog:{blogFooterTagsRow:"theme-blog-footer-tags-row",blogFooterEditMetaRow:"theme-blog-footer-edit-meta-row"},pages:{pageFooterEditMetaRow:"theme-pages-footer-edit-meta-row"}}},1442:(e,t,n)=>{"use strict";function r(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}n.d(t,{n:()=>r})},3438:(e,t,n)=>{"use strict";n.d(t,{LM:()=>f,SN:()=>_,_F:()=>h,cE:()=>p,f:()=>y,lO:()=>k,oz:()=>x,s1:()=>w,vY:()=>S});var r=n(7294),o=n(6550),i=n(8790),a=n(143),s=n(373),l=n(4477),c=n(1116),u=n(7392),d=n(8596);const p=!!a._r;function f(e){return"link"!==e.type||e.unlisted?"category"===e.type?function(e){if(e.href&&!e.linkUnlisted)return e.href;for(const t of e.items){const e=f(t);if(e)return e}}(e):void 0:e.href}const g=(e,t)=>void 0!==e&&(0,d.Mg)(e,t),m=(e,t)=>e.some((e=>h(e,t)));function h(e,t){return"link"===e.type?g(e.href,t):"category"===e.type&&(g(e.href,t)||m(e.items,t))}function b(e,t){switch(e.type){case"category":return h(e,t)||e.items.some((e=>b(e,t)));case"link":return!e.unlisted||h(e,t);default:return!0}}function y(e,t){return(0,r.useMemo)((()=>e.filter((e=>b(e,t)))),[e,t])}function v(e){let{sidebarItems:t,pathname:n,onlyCategories:r=!1}=e;const o=[];return function e(t){for(const i of t)if("category"===i.type&&((0,d.Mg)(i.href,n)||e(i.items))||"link"===i.type&&(0,d.Mg)(i.href,n)){return r&&"category"!==i.type||o.unshift(i),!0}return!1}(t),o}function w(){const e=(0,c.V)(),{pathname:t}=(0,o.TH)(),n=(0,a.gA)()?.pluginData.breadcrumbs;return!1!==n&&e?v({sidebarItems:e.items,pathname:t}):null}function k(e){const{activeVersion:t}=(0,a.Iw)(e),{preferredVersion:n}=(0,s.J)(e),o=(0,a.yW)(e);return(0,r.useMemo)((()=>(0,u.j)([t,n,o].filter(Boolean))),[t,n,o])}function x(e,t){const n=k(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.sidebars?Object.entries(e.sidebars):[])),r=t.find((t=>t[0]===e));if(!r)throw new Error(`Can't find any sidebar with id "${e}" in version${n.length>1?"s":""} ${n.map((e=>e.name)).join(", ")}".\nAvailable sidebar ids are:\n- ${t.map((e=>e[0])).join("\n- ")}`);return r[1]}),[e,n])}function S(e,t){const n=k(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.docs)),r=t.find((t=>t.id===e));if(!r){if(n.flatMap((e=>e.draftIds)).includes(e))return null;throw new Error(`Couldn't find any doc with id "${e}" in version${n.length>1?"s":""} "${n.map((e=>e.name)).join(", ")}".\nAvailable doc ids are:\n- ${(0,u.j)(t.map((e=>e.id))).join("\n- ")}`)}return r}),[e,n])}function _(e){let{route:t}=e;const n=(0,o.TH)(),r=(0,l.E)(),a=t.routes,s=a.find((e=>(0,o.LX)(n.pathname,e)));if(!s)return null;const c=s.sidebar,u=c?r.docsSidebars[c]:void 0;return{docElement:(0,i.H)(a),sidebarName:c,sidebarItems:u}}},1980:(e,t,n)=>{"use strict";n.d(t,{Rb:()=>a,_X:()=>l});var r=n(7294),o=n(6550),i=n(902);function a(e){!function(e){const t=(0,o.k6)(),n=(0,i.zX)(e);(0,r.useEffect)((()=>t.block(((e,t)=>n(e,t)))),[t,n])}(((t,n)=>{if("POP"===n)return e(t,n)}))}function s(e){const t=(0,o.k6)();return(0,r.useSyncExternalStore)(t.listen,(()=>e(t)),(()=>e(t)))}function l(e){return s((t=>null===e?null:new URLSearchParams(t.location.search).get(e)))}},7392:(e,t,n)=>{"use strict";function r(e,t){return void 0===t&&(t=(e,t)=>e===t),e.filter(((n,r)=>e.findIndex((e=>t(e,n)))!==r))}function o(e){return Array.from(new Set(e))}n.d(t,{j:()=>o,l:()=>r})},8264:(e,t,n)=>{"use strict";n.d(t,{FG:()=>p,d:()=>u,VC:()=>f});var r=n(7294),o=n(788),i=n(5742),a=n(5102),s=n(4996),l=n(2263);var c=n(5893);function u(e){let{title:t,description:n,keywords:r,image:o,children:a}=e;const u=function(e){const{siteConfig:t}=(0,l.Z)(),{title:n,titleDelimiter:r}=t;return e?.trim().length?`${e.trim()} ${r} ${n}`:n}(t),{withBaseUrl:d}=(0,s.Cg)(),p=o?d(o,{absolute:!0}):void 0;return(0,c.jsxs)(i.Z,{children:[t&&(0,c.jsx)("title",{children:u}),t&&(0,c.jsx)("meta",{property:"og:title",content:u}),n&&(0,c.jsx)("meta",{name:"description",content:n}),n&&(0,c.jsx)("meta",{property:"og:description",content:n}),r&&(0,c.jsx)("meta",{name:"keywords",content:Array.isArray(r)?r.join(","):r}),p&&(0,c.jsx)("meta",{property:"og:image",content:p}),p&&(0,c.jsx)("meta",{name:"twitter:image",content:p}),a]})}const d=r.createContext(void 0);function p(e){let{className:t,children:n}=e;const a=r.useContext(d),s=(0,o.Z)(a,t);return(0,c.jsxs)(d.Provider,{value:s,children:[(0,c.jsx)(i.Z,{children:(0,c.jsx)("html",{className:s})}),n]})}function f(e){let{children:t}=e;const n=(0,a.Z)(),r=`plugin-${n.plugin.name.replace(/docusaurus-(?:plugin|theme)-(?:content-)?/gi,"")}`;const i=`plugin-id-${n.plugin.id}`;return(0,c.jsx)(p,{className:(0,o.Z)(r,i),children:t})}},902:(e,t,n)=>{"use strict";n.d(t,{D9:()=>s,Qc:()=>u,Ql:()=>c,i6:()=>l,zX:()=>a});var r=n(7294),o=n(469),i=n(5893);function a(e){const t=(0,r.useRef)(e);return(0,o.Z)((()=>{t.current=e}),[e]),(0,r.useCallback)((function(){return t.current(...arguments)}),[])}function s(e){const t=(0,r.useRef)();return(0,o.Z)((()=>{t.current=e})),t.current}class l extends Error{constructor(e,t){super(),this.name="ReactContextError",this.message=`Hook ${this.stack?.split("\n")[1]?.match(/at (?:\w+\.)?(?\w+)/)?.groups.name??""} is called outside the <${e}>. ${t??""}`}}function c(e){const t=Object.entries(e);return t.sort(((e,t)=>e[0].localeCompare(t[0]))),(0,r.useMemo)((()=>e),t.flat())}function u(e){return t=>{let{children:n}=t;return(0,i.jsx)(i.Fragment,{children:e.reduceRight(((e,t)=>(0,i.jsx)(t,{children:e})),n)})}}},8596:(e,t,n)=>{"use strict";n.d(t,{Mg:()=>a,Ns:()=>s});var r=n(7294),o=n(723),i=n(2263);function a(e,t){const n=e=>(!e||e.endsWith("/")?e:`${e}/`)?.toLowerCase();return n(e)===n(t)}function s(){const{baseUrl:e}=(0,i.Z)().siteConfig;return(0,r.useMemo)((()=>function(e){let{baseUrl:t,routes:n}=e;function r(e){return e.path===t&&!0===e.exact}function o(e){return e.path===t&&!e.exact}return function e(t){if(0===t.length)return;return t.find(r)||e(t.filter(o).flatMap((e=>e.routes??[])))}(n)}({routes:o.Z,baseUrl:e})),[e])}},2466:(e,t,n)=>{"use strict";n.d(t,{Ct:()=>m,OC:()=>u,RF:()=>f,o5:()=>g});var r=n(7294),o=n(412),i=n(2389),a=n(469),s=n(902),l=n(5893);const c=r.createContext(void 0);function u(e){let{children:t}=e;const n=function(){const e=(0,r.useRef)(!0);return(0,r.useMemo)((()=>({scrollEventsEnabledRef:e,enableScrollEvents:()=>{e.current=!0},disableScrollEvents:()=>{e.current=!1}})),[])}();return(0,l.jsx)(c.Provider,{value:n,children:t})}function d(){const e=(0,r.useContext)(c);if(null==e)throw new s.i6("ScrollControllerProvider");return e}const p=()=>o.Z.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null;function f(e,t){void 0===t&&(t=[]);const{scrollEventsEnabledRef:n}=d(),o=(0,r.useRef)(p()),i=(0,s.zX)(e);(0,r.useEffect)((()=>{const e=()=>{if(!n.current)return;const e=p();i(e,o.current),o.current=e},t={passive:!0};return e(),window.addEventListener("scroll",e,t),()=>window.removeEventListener("scroll",e,t)}),[i,n,...t])}function g(){const e=d(),t=function(){const e=(0,r.useRef)({elem:null,top:0}),t=(0,r.useCallback)((t=>{e.current={elem:t,top:t.getBoundingClientRect().top}}),[]),n=(0,r.useCallback)((()=>{const{current:{elem:t,top:n}}=e;if(!t)return{restored:!1};const r=t.getBoundingClientRect().top-n;return r&&window.scrollBy({left:0,top:r}),e.current={elem:null,top:0},{restored:0!==r}}),[]);return(0,r.useMemo)((()=>({save:t,restore:n})),[n,t])}(),n=(0,r.useRef)(void 0),o=(0,r.useCallback)((r=>{t.save(r),e.disableScrollEvents(),n.current=()=>{const{restored:r}=t.restore();if(n.current=void 0,r){const t=()=>{e.enableScrollEvents(),window.removeEventListener("scroll",t)};window.addEventListener("scroll",t)}else e.enableScrollEvents()}}),[e,t]);return(0,a.Z)((()=>{queueMicrotask((()=>n.current?.()))})),{blockElementScrollPositionUntilNextRender:o}}function m(){const e=(0,r.useRef)(null),t=(0,i.Z)()&&"smooth"===getComputedStyle(document.documentElement).scrollBehavior;return{startScroll:n=>{e.current=t?function(e){return window.scrollTo({top:e,behavior:"smooth"}),()=>{}}(n):function(e){let t=null;const n=document.documentElement.scrollTop>e;return function r(){const o=document.documentElement.scrollTop;(n&&o>e||!n&&ot&&cancelAnimationFrame(t)}(n)},cancelScroll:()=>e.current?.()}}},3320:(e,t,n)=>{"use strict";n.d(t,{HX:()=>r,os:()=>o});n(2263);const r="default";function o(e,t){return`docs-${e}-${t}`}},812:(e,t,n)=>{"use strict";n.d(t,{WA:()=>u,Nk:()=>d});var r=n(7294);const o=JSON.parse('{"d":"localStorage","u":""}'),i=o.d;function a(e){let{key:t,oldValue:n,newValue:r,storage:o}=e;if(n===r)return;const i=document.createEvent("StorageEvent");i.initStorageEvent("storage",!1,!1,t,n,r,window.location.href,o),window.dispatchEvent(i)}function s(e){if(void 0===e&&(e=i),"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,l||(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),l=!0),null}var t}let l=!1;const c={get:()=>null,set:()=>{},del:()=>{},listen:()=>()=>{}};function u(e,t){const n=`${e}${o.u}`;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,listen:t}}(n);const r=s(t?.persistence);return null===r?c:{get:()=>{try{return r.getItem(n)}catch(e){return console.error(`Docusaurus storage error, can't get key=${n}`,e),null}},set:e=>{try{const t=r.getItem(n);r.setItem(n,e),a({key:n,oldValue:t,newValue:e,storage:r})}catch(t){console.error(`Docusaurus storage error, can't set ${n}=${e}`,t)}},del:()=>{try{const e=r.getItem(n);r.removeItem(n),a({key:n,oldValue:e,newValue:null,storage:r})}catch(e){console.error(`Docusaurus storage error, can't delete key=${n}`,e)}},listen:e=>{try{const t=t=>{t.storageArea===r&&t.key===n&&e(t)};return window.addEventListener("storage",t),()=>window.removeEventListener("storage",t)}catch(t){return console.error(`Docusaurus storage error, can't listen for changes of key=${n}`,t),()=>{}}}}}function d(e,t){const n=(0,r.useRef)((()=>null===e?c:u(e,t))).current(),o=(0,r.useCallback)((e=>"undefined"==typeof window?()=>{}:n.listen(e)),[n]);return[(0,r.useSyncExternalStore)(o,(()=>"undefined"==typeof window?null:n.get()),(()=>null)),n]}},4711:(e,t,n)=>{"use strict";n.d(t,{l:()=>a});var r=n(2263),o=n(6550),i=n(8780);function a(){const{siteConfig:{baseUrl:e,url:t,trailingSlash:n},i18n:{defaultLocale:a,currentLocale:s}}=(0,r.Z)(),{pathname:l}=(0,o.TH)(),c=(0,i.applyTrailingSlash)(l,{trailingSlash:n,baseUrl:e}),u=s===a?e:e.replace(`/${s}/`,"/"),d=c.replace(e,"");return{createUrl:function(e){let{locale:n,fullyQualified:r}=e;return`${r?t:""}${function(e){return e===a?`${u}`:`${u}${e}/`}(n)}${d}`}}}},5936:(e,t,n)=>{"use strict";n.d(t,{S:()=>a});var r=n(7294),o=n(6550),i=n(902);function a(e){const t=(0,o.TH)(),n=(0,i.D9)(t),a=(0,i.zX)(e);(0,r.useEffect)((()=>{n&&t!==n&&a({location:t,previousLocation:n})}),[a,t,n])}},6668:(e,t,n)=>{"use strict";n.d(t,{L:()=>o});var r=n(2263);function o(){return(0,r.Z)().siteConfig.themeConfig}},8802:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.removeTrailingSlash=t.addLeadingSlash=t.addTrailingSlash=void 0;const r=n(5913);function o(e){return e.endsWith("/")?e:`${e}/`}function i(e){return(0,r.removeSuffix)(e,"/")}t.addTrailingSlash=o,t.default=function(e,t){const{trailingSlash:n,baseUrl:r}=t;if(e.startsWith("#"))return e;if(void 0===n)return e;const[a]=e.split(/[#?]/),s="/"===a||a===r?a:(l=a,n?o(l):i(l));var l;return e.replace(a,s)},t.addLeadingSlash=function(e){return(0,r.addPrefix)(e,"/")},t.removeTrailingSlash=i},4143:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=void 0,t.getErrorCausalChain=function e(t){return t.cause?[t,...e(t.cause)]:[t]}},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.getErrorCausalChain=t.removePrefix=t.addSuffix=t.removeSuffix=t.addPrefix=t.removeTrailingSlash=t.addLeadingSlash=t.addTrailingSlash=t.applyTrailingSlash=t.blogPostContainerID=void 0,t.blogPostContainerID="__blog-post-container";var o=n(8802);Object.defineProperty(t,"applyTrailingSlash",{enumerable:!0,get:function(){return r(o).default}}),Object.defineProperty(t,"addTrailingSlash",{enumerable:!0,get:function(){return o.addTrailingSlash}}),Object.defineProperty(t,"addLeadingSlash",{enumerable:!0,get:function(){return o.addLeadingSlash}}),Object.defineProperty(t,"removeTrailingSlash",{enumerable:!0,get:function(){return o.removeTrailingSlash}});var i=n(5913);Object.defineProperty(t,"addPrefix",{enumerable:!0,get:function(){return i.addPrefix}}),Object.defineProperty(t,"removeSuffix",{enumerable:!0,get:function(){return i.removeSuffix}}),Object.defineProperty(t,"addSuffix",{enumerable:!0,get:function(){return i.addSuffix}}),Object.defineProperty(t,"removePrefix",{enumerable:!0,get:function(){return i.removePrefix}});var a=n(4143);Object.defineProperty(t,"getErrorCausalChain",{enumerable:!0,get:function(){return a.getErrorCausalChain}})},5913:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.removePrefix=t.addSuffix=t.removeSuffix=t.addPrefix=void 0,t.addPrefix=function(e,t){return e.startsWith(t)?e:`${t}${e}`},t.removeSuffix=function(e,t){return""===t?e:e.endsWith(t)?e.slice(0,-t.length):e},t.addSuffix=function(e,t){return e.endsWith(t)?e:`${e}${t}`},t.removePrefix=function(e,t){return e.startsWith(t)?e.slice(t.length):e}},311:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});n(7294);var r=n(6010);const o={loadingRing:"loadingRing_RJI3","loading-ring":"loading-ring_FB5o"};var i=n(5893);function a(e){let{className:t}=e;return(0,i.jsxs)("div",{className:(0,r.Z)(o.loadingRing,t),children:[(0,i.jsx)("div",{}),(0,i.jsx)("div",{}),(0,i.jsx)("div",{}),(0,i.jsx)("div",{})]})}},22:(e,t,n)=>{"use strict";n.d(t,{w:()=>s});var r=n(1336),o=n.n(r),i=n(1029);const a=new Map;function s(e,t){const n=`${e}${t}`;let r=a.get(n);return r||(r=async function(e,t){{const n=`${e}${i.J.replace("{dir}",t?`-${t.replace(/\//g,"-")}`:"")}`;if(new URL(n,location.origin).origin!==location.origin)throw new Error("Unexpected version url");const r=await(await fetch(n)).json(),a=r.map(((e,t)=>{let{documents:n,index:r}=e;return{type:t,documents:n,index:o().Index.load(r)}})),s=r.reduce(((e,t)=>{for(const n of t.index.invertedIndex)/\p{Unified_Ideograph}/u.test(n[0][0])&&e.add(n[0]);return e}),new Set);return{wrappedIndexes:a,zhDictionary:Array.from(s)}}return{wrappedIndexes:[],zhDictionary:[]}}(e,t),a.set(n,r)),r}},8202:(e,t,n)=>{"use strict";n.d(t,{v:()=>c});var r=n(1336),o=n.n(r);var i=n(1029);function a(e){return s(e).concat(s(e.filter((e=>{const t=e[e.length-1];return!t.trailing&&t.maybeTyping})),!0))}function s(e,t){return e.map((e=>({tokens:e.map((e=>e.value)),term:e.map((e=>({value:e.value,presence:o().Query.presence.REQUIRED,wildcard:(t?e.trailing||e.maybeTyping:e.trailing)?o().Query.wildcard.TRAILING:o().Query.wildcard.NONE})))})))}var l=n(3545);function c(e,t,n){return function(r,s){const c=function(e,t){if(1===t.length&&["ja","jp","th"].includes(t[0]))return o()[t[0]].tokenizer(e).map((e=>e.toString()));let n=/[^-\s]+/g;return t.includes("zh")&&(n=/\w+|\p{Unified_Ideograph}+/gu),e.toLowerCase().match(n)||[]}(r,i.dK);if(0===c.length)return void s([]);const u=function(e,t){const n=function(e,t){const n=[];return function e(r,o){if(0===r.length)return void n.push(o);const i=r[0];if(/\p{Unified_Ideograph}/u.test(i)){const n=function(e,t){const n=[];return function e(r,o){let i=0,a=!1;for(const s of t)if(r.substr(0,s.length)===s){const t={missed:o.missed,term:o.term.concat({value:s})};r.length>s.length?e(r.substr(s.length),t):n.push(t),a=!0}else for(let t=s.length-1;t>i;t-=1){const l=s.substr(0,t);if(r.substr(0,t)===l){i=t;const s={missed:o.missed,term:o.term.concat({value:l,trailing:!0})};r.length>t?e(r.substr(t),s):n.push(s),a=!0;break}}a||(r.length>0?e(r.substr(1),{missed:o.missed+1,term:o.term}):o.term.length>0&&n.push(o))}(e,{missed:0,term:[]}),n.sort(((e,t)=>{const n=e.missed>0?1:0,r=t.missed>0?1:0;return n!==r?n-r:e.term.length-t.term.length})).map((e=>e.term))}(i,t);for(const t of n){const n=o.concat(...t);e(r.slice(1),n)}}else{const t=o.concat({value:i});e(r.slice(1),t)}}(e,[]),n}(e,t);if(0===n.length)return[{tokens:e,term:e.map((e=>({value:e,presence:o().Query.presence.REQUIRED,wildcard:o().Query.wildcard.LEADING|o().Query.wildcard.TRAILING})))}];for(const o of n)o[o.length-1].maybeTyping=!0;const r=[];for(const a of i.dK)if("en"===a)i._k||r.unshift(o().stopWordFilter);else{const e=o()[a];e.stopWordFilter&&r.unshift(e.stopWordFilter)}let s;if(r.length>0){const e=e=>r.reduce(((e,t)=>e.filter((e=>t(e.value)))),e);s=[];const t=[];for(const r of n){const n=e(r);s.push(n),n.length0&&t.push(n)}n.push(...t)}else s=n.slice();const l=[];for(const o of s)if(o.length>2)for(let e=o.length-1;e>=0;e-=1)l.push(o.slice(0,e).concat(o.slice(e+1)));return a(n).concat(a(l))}(c,t),d=[];e:for(const{term:t,tokens:o}of u)for(const{documents:r,index:i,type:a}of e)if(d.push(...i.query((e=>{for(const n of t)e.term(n.value,{wildcard:n.wildcard,presence:n.presence})})).slice(0,n).filter((e=>!d.some((t=>t.document.i.toString()===e.ref)))).slice(0,n-d.length).map((t=>{const n=r.find((e=>e.i.toString()===t.ref));return{document:n,type:a,page:a!==l.P.Title&&e[0].documents.find((e=>e.i===n.p)),metadata:t.matchData.metadata,tokens:o,score:t.score}}))),d.length>=n)break e;!function(e){e.forEach(((e,t)=>{e.index=t})),e.sort(((t,n)=>{let r=t.type!==l.P.Heading&&t.type!==l.P.Content&&t.type!==l.P.Description||!t.page?t.index:e.findIndex((e=>e.document===t.page)),o=n.type!==l.P.Heading&&n.type!==l.P.Content&&n.type!==l.P.Description||!n.page?n.index:e.findIndex((e=>e.document===n.page));if(-1===r&&(r=t.index),-1===o&&(o=n.index),r===o){const e=(0===n.type?1:0)-(0===t.type?1:0);return 0===e?t.index-n.index:e}return r-o}))}(d),function(e){e.forEach(((t,n)=>{n>0&&t.page&&e.slice(0,n).some((e=>(e.type===l.P.Keywords?e.page:e.document)===t.page))&&(n{"use strict";function r(e){return e.join(" \u203a ")}n.d(t,{e:()=>r})},1690:(e,t,n)=>{"use strict";function r(e){return e.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")}n.d(t,{X:()=>r})},1073:(e,t,n)=>{"use strict";function r(e,t){const n=[];for(const r of Object.values(e))r[t]&&n.push(...r[t].position);return n.sort(((e,t)=>e[0]-t[0]||t[1]-e[1]))}n.d(t,{m:()=>r})},2539:(e,t,n)=>{"use strict";n.d(t,{C:()=>o});var r=n(1690);function o(e,t,n){const i=[];for(const a of t){const n=e.toLowerCase().indexOf(a);if(n>=0){n>0&&i.push(o(e.substr(0,n),t)),i.push(`${(0,r.X)(e.substr(n,a.length))}`);const s=n+a.length;s${(0,r.X)(e)}`:(0,r.X)(e):i.join("")}},726:(e,t,n)=>{"use strict";n.d(t,{o:()=>l});var r=n(1690),o=n(2539);const i=/\w+|\p{Unified_Ideograph}/u;function a(e){const t=[];let n=0,r=e;for(;r.length>0;){const o=r.match(i);if(!o){t.push(r);break}o.index>0&&t.push(r.substring(0,o.index)),t.push(o[0]),n+=o.index+o[0].length,r=e.substring(n)}return t}var s=n(1029);function l(e,t,n,i){void 0===i&&(i=s.Hk);const{chunkIndex:l,chunks:c}=function(e,t,n){const i=[];let s=0,l=0,c=-1;for(;sl){const t=a(e.substring(l,u)).map((e=>({html:(0,r.X)(e),textLength:e.length})));for(const e of t)i.push(e)}-1===c&&(c=i.length),l=u+d,i.push({html:(0,o.C)(e.substring(u,l),n,!0),textLength:d})}}if(l({html:(0,r.X)(e),textLength:e.length})));for(const e of t)i.push(e)}return{chunkIndex:c,chunks:i}}(e,t,n),u=c.slice(0,l),d=c[l],p=[d.html],f=c.slice(l+1);let g=d.textLength,m=0,h=0,b=!1,y=!1;for(;g0){const e=u.pop();g+e.textLength<=i?(p.unshift(e.html),m+=e.textLength,g+=e.textLength):(b=!0,u.length=0)}else{if(!(f.length>0))break;{const e=f.shift();g+e.textLength<=i?(p.push(e.html),h+=e.textLength,g+=e.textLength):(y=!0,f.length=0)}}return(b||u.length>0)&&p.unshift("\u2026"),(y||f.length>0)&&p.push("\u2026"),p.join("")}},51:(e,t,n)=>{"use strict";function r(e,t){if("string"==typeof e)return{label:e,path:e};{const{label:n,path:r}=e;return"string"==typeof n?{label:n,path:r}:Object.prototype.hasOwnProperty.call(n,t)?{label:n[t],path:r}:{label:r,path:r}}}n.d(t,{_:()=>r})},1029:(e,t,n)=>{"use strict";n.d(t,{vc:()=>i,gQ:()=>f,H6:()=>c,hG:()=>h,l9:()=>g,dK:()=>r,_k:()=>o,pu:()=>p,AY:()=>u,t_:()=>d,Kc:()=>m,J:()=>a,Hk:()=>l,qo:()=>s,pQ:()=>b});n(1336);const r=["en"],o=!1,i=null,a="search-index{dir}.json?_=1ebdf63f",s=8,l=50,c=!1,u=!0,d=!0,p="right",f=void 0,g=!0,m=null,h=!1,b=!1},3545:(e,t,n)=>{"use strict";var r;n.d(t,{P:()=>r}),function(e){e[e.Title=0]="Title",e[e.Heading=1]="Heading",e[e.Description=2]="Description",e[e.Keywords=3]="Keywords",e[e.Content=4]="Content"}(r||(r={}))},6010:(e,t,n)=>{"use strict";function r(e){var t,n,o="";if("string"==typeof e||"number"==typeof e)o+=e;else if("object"==typeof e)if(Array.isArray(e))for(t=0;to});const o=function(){for(var e,t,n=0,o="";n{"use strict";n.d(t,{lX:()=>w,q_:()=>C,ob:()=>f,PP:()=>L,Ep:()=>p});var r=n(7462);function o(e){return"/"===e.charAt(0)}function i(e,t){for(var n=t,r=n+1,o=e.length;r=0;p--){var f=a[p];"."===f?i(a,p):".."===f?(i(a,p),d++):d&&(i(a,p),d--)}if(!c)for(;d--;d)a.unshift("..");!c||""===a[0]||a[0]&&o(a[0])||a.unshift("");var g=a.join("/");return n&&"/"!==g.substr(-1)&&(g+="/"),g};var s=n(8776);function l(e){return"/"===e.charAt(0)?e:"/"+e}function c(e){return"/"===e.charAt(0)?e.substr(1):e}function u(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 d(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function p(e){var t=e.pathname,n=e.search,r=e.hash,o=t||"/";return n&&"?"!==n&&(o+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(o+="#"===r.charAt(0)?r:"#"+r),o}function f(e,t,n,o){var i;"string"==typeof e?(i=function(e){var t=e||"/",n="",r="",o=t.indexOf("#");-1!==o&&(r=t.substr(o),t=t.substr(0,o));var i=t.indexOf("?");return-1!==i&&(n=t.substr(i),t=t.substr(0,i)),{pathname:t,search:"?"===n?"":n,hash:"#"===r?"":r}}(e),i.state=t):(void 0===(i=(0,r.Z)({},e)).pathname&&(i.pathname=""),i.search?"?"!==i.search.charAt(0)&&(i.search="?"+i.search):i.search="",i.hash?"#"!==i.hash.charAt(0)&&(i.hash="#"+i.hash):i.hash="",void 0!==t&&void 0===i.state&&(i.state=t));try{i.pathname=decodeURI(i.pathname)}catch(s){throw s instanceof URIError?new URIError('Pathname "'+i.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):s}return n&&(i.key=n),o?i.pathname?"/"!==i.pathname.charAt(0)&&(i.pathname=a(i.pathname,o.pathname)):i.pathname=o.pathname:i.pathname||(i.pathname="/"),i}function g(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,o){if(null!=e){var i="function"==typeof e?e(t,n):e;"string"==typeof i?"function"==typeof r?r(i,o):o(!0):o(!1!==i)}else o(!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,o):n.push(o),d({action:r,location:o,index:t,entries:n})}}))},replace:function(e,t){var r="REPLACE",o=f(e,t,m(),w.location);u.confirmTransitionTo(o,r,n,(function(e){e&&(w.entries[w.index]=o,d({action:r,location:o}))}))},go:v,goBack:function(){v(-1)},goForward:function(){v(1)},canGo:function(e){var t=w.index+e;return t>=0&&t{"use strict";var r=n(9864),o={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},i={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},a={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},s={};function l(e){return r.isMemo(e)?a:s[e.$$typeof]||o}s[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},s[r.Memo]=a;var c=Object.defineProperty,u=Object.getOwnPropertyNames,d=Object.getOwnPropertySymbols,p=Object.getOwnPropertyDescriptor,f=Object.getPrototypeOf,g=Object.prototype;e.exports=function e(t,n,r){if("string"!=typeof n){if(g){var o=f(n);o&&o!==g&&e(t,o,r)}var a=u(n);d&&(a=a.concat(d(n)));for(var s=l(t),m=l(n),h=0;h{"use strict";e.exports=function(e,t,n,r,o,i,a,s){if(!e){var l;if(void 0===t)l=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var c=[n,r,o,i,a,s],u=0;(l=new Error(t.replace(/%s/g,(function(){return c[u++]})))).name="Invariant Violation"}throw l.framesToPop=1,l}}},5826:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},1336:(e,t,n)=>{var r,o;!function(){var i,a,s,l,c,u,d,p,f,g,m,h,b,y,v,w,k,x,S,_,E,C,T,L,P,j,A,R,N,O,I=function(e){var t=new I.Builder;return t.pipeline.add(I.trimmer,I.stopWordFilter,I.stemmer),t.searchPipeline.add(I.stemmer),e.call(t,t),t.build()};I.version="2.3.9",I.utils={},I.utils.warn=(i=this,function(e){i.console&&console.warn&&console.warn(e)}),I.utils.asString=function(e){return null==e?"":e.toString()},I.utils.clone=function(e){if(null==e)return e;for(var t=Object.create(null),n=Object.keys(e),r=0;r0){var l=I.utils.clone(t)||{};l.position=[a,s],l.index=o.length,o.push(new I.Token(n.slice(a,i),l))}a=i+1}}return o},I.tokenizer.separator=/[\s\-]+/,I.Pipeline=function(){this._stack=[]},I.Pipeline.registeredFunctions=Object.create(null),I.Pipeline.registerFunction=function(e,t){t in this.registeredFunctions&&I.utils.warn("Overwriting existing registered function: "+t),e.label=t,I.Pipeline.registeredFunctions[e.label]=e},I.Pipeline.warnIfFunctionNotRegistered=function(e){e.label&&e.label in this.registeredFunctions||I.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},I.Pipeline.load=function(e){var t=new I.Pipeline;return e.forEach((function(e){var n=I.Pipeline.registeredFunctions[e];if(!n)throw new Error("Cannot load unregistered function: "+e);t.add(n)})),t},I.Pipeline.prototype.add=function(){Array.prototype.slice.call(arguments).forEach((function(e){I.Pipeline.warnIfFunctionNotRegistered(e),this._stack.push(e)}),this)},I.Pipeline.prototype.after=function(e,t){I.Pipeline.warnIfFunctionNotRegistered(t);var n=this._stack.indexOf(e);if(-1==n)throw new Error("Cannot find existingFn");n+=1,this._stack.splice(n,0,t)},I.Pipeline.prototype.before=function(e,t){I.Pipeline.warnIfFunctionNotRegistered(t);var n=this._stack.indexOf(e);if(-1==n)throw new Error("Cannot find existingFn");this._stack.splice(n,0,t)},I.Pipeline.prototype.remove=function(e){var t=this._stack.indexOf(e);-1!=t&&this._stack.splice(t,1)},I.Pipeline.prototype.run=function(e){for(var t=this._stack.length,n=0;n1&&(ie&&(n=o),i!=e);)r=n-t,o=t+Math.floor(r/2),i=this.elements[2*o];return i==e||i>e?2*o:is?c+=2:a==s&&(t+=n[l+1]*r[c+1],l+=2,c+=2);return t},I.Vector.prototype.similarity=function(e){return this.dot(e)/this.magnitude()||0},I.Vector.prototype.toArray=function(){for(var e=new Array(this.elements.length/2),t=1,n=0;t0){var i,a=o.str.charAt(0);a in o.node.edges?i=o.node.edges[a]:(i=new I.TokenSet,o.node.edges[a]=i),1==o.str.length&&(i.final=!0),r.push({node:i,editsRemaining:o.editsRemaining,str:o.str.slice(1)})}if(0!=o.editsRemaining){if("*"in o.node.edges)var s=o.node.edges["*"];else{s=new I.TokenSet;o.node.edges["*"]=s}if(0==o.str.length&&(s.final=!0),r.push({node:s,editsRemaining:o.editsRemaining-1,str:o.str}),o.str.length>1&&r.push({node:o.node,editsRemaining:o.editsRemaining-1,str:o.str.slice(1)}),1==o.str.length&&(o.node.final=!0),o.str.length>=1){if("*"in o.node.edges)var l=o.node.edges["*"];else{l=new I.TokenSet;o.node.edges["*"]=l}1==o.str.length&&(l.final=!0),r.push({node:l,editsRemaining:o.editsRemaining-1,str:o.str.slice(1)})}if(o.str.length>1){var c,u=o.str.charAt(0),d=o.str.charAt(1);d in o.node.edges?c=o.node.edges[d]:(c=new I.TokenSet,o.node.edges[d]=c),1==o.str.length&&(c.final=!0),r.push({node:c,editsRemaining:o.editsRemaining-1,str:u+o.str.slice(2)})}}}return n},I.TokenSet.fromString=function(e){for(var t=new I.TokenSet,n=t,r=0,o=e.length;r=e;t--){var n=this.uncheckedNodes[t],r=n.child.toString();r in this.minimizedNodes?n.parent.edges[n.char]=this.minimizedNodes[r]:(n.child._str=r,this.minimizedNodes[r]=n.child),this.uncheckedNodes.pop()}},I.Index=function(e){this.invertedIndex=e.invertedIndex,this.fieldVectors=e.fieldVectors,this.tokenSet=e.tokenSet,this.fields=e.fields,this.pipeline=e.pipeline},I.Index.prototype.search=function(e){return this.query((function(t){new I.QueryParser(e,t).parse()}))},I.Index.prototype.query=function(e){for(var t=new I.Query(this.fields),n=Object.create(null),r=Object.create(null),o=Object.create(null),i=Object.create(null),a=Object.create(null),s=0;s1?1:e},I.Builder.prototype.k1=function(e){this._k1=e},I.Builder.prototype.add=function(e,t){var n=e[this._ref],r=Object.keys(this._fields);this._documents[n]=t||{},this.documentCount+=1;for(var o=0;o=this.length)return I.QueryLexer.EOS;var e=this.str.charAt(this.pos);return this.pos+=1,e},I.QueryLexer.prototype.width=function(){return this.pos-this.start},I.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},I.QueryLexer.prototype.backup=function(){this.pos-=1},I.QueryLexer.prototype.acceptDigitRun=function(){var e,t;do{t=(e=this.next()).charCodeAt(0)}while(t>47&&t<58);e!=I.QueryLexer.EOS&&this.backup()},I.QueryLexer.prototype.more=function(){return this.pos1&&(e.backup(),e.emit(I.QueryLexer.TERM)),e.ignore(),e.more())return I.QueryLexer.lexText},I.QueryLexer.lexEditDistance=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(I.QueryLexer.EDIT_DISTANCE),I.QueryLexer.lexText},I.QueryLexer.lexBoost=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(I.QueryLexer.BOOST),I.QueryLexer.lexText},I.QueryLexer.lexEOS=function(e){e.width()>0&&e.emit(I.QueryLexer.TERM)},I.QueryLexer.termSeparator=I.tokenizer.separator,I.QueryLexer.lexText=function(e){for(;;){var t=e.next();if(t==I.QueryLexer.EOS)return I.QueryLexer.lexEOS;if(92!=t.charCodeAt(0)){if(":"==t)return I.QueryLexer.lexField;if("~"==t)return e.backup(),e.width()>0&&e.emit(I.QueryLexer.TERM),I.QueryLexer.lexEditDistance;if("^"==t)return e.backup(),e.width()>0&&e.emit(I.QueryLexer.TERM),I.QueryLexer.lexBoost;if("+"==t&&1===e.width())return e.emit(I.QueryLexer.PRESENCE),I.QueryLexer.lexText;if("-"==t&&1===e.width())return e.emit(I.QueryLexer.PRESENCE),I.QueryLexer.lexText;if(t.match(I.QueryLexer.termSeparator))return I.QueryLexer.lexTerm}else e.escapeCharacter()}},I.QueryParser=function(e,t){this.lexer=new I.QueryLexer(e),this.query=t,this.currentClause={},this.lexemeIdx=0},I.QueryParser.prototype.parse=function(){this.lexer.run(),this.lexemes=this.lexer.lexemes;for(var e=I.QueryParser.parseClause;e;)e=e(this);return this.query},I.QueryParser.prototype.peekLexeme=function(){return this.lexemes[this.lexemeIdx]},I.QueryParser.prototype.consumeLexeme=function(){var e=this.peekLexeme();return this.lexemeIdx+=1,e},I.QueryParser.prototype.nextClause=function(){var e=this.currentClause;this.query.clause(e),this.currentClause={}},I.QueryParser.parseClause=function(e){var t=e.peekLexeme();if(null!=t)switch(t.type){case I.QueryLexer.PRESENCE:return I.QueryParser.parsePresence;case I.QueryLexer.FIELD:return I.QueryParser.parseField;case I.QueryLexer.TERM:return I.QueryParser.parseTerm;default:var n="expected either a field or a term, found "+t.type;throw t.str.length>=1&&(n+=" with value '"+t.str+"'"),new I.QueryParseError(n,t.start,t.end)}},I.QueryParser.parsePresence=function(e){var t=e.consumeLexeme();if(null!=t){switch(t.str){case"-":e.currentClause.presence=I.Query.presence.PROHIBITED;break;case"+":e.currentClause.presence=I.Query.presence.REQUIRED;break;default:var n="unrecognised presence operator'"+t.str+"'";throw new I.QueryParseError(n,t.start,t.end)}var r=e.peekLexeme();if(null==r){n="expecting term or field, found nothing";throw new I.QueryParseError(n,t.start,t.end)}switch(r.type){case I.QueryLexer.FIELD:return I.QueryParser.parseField;case I.QueryLexer.TERM:return I.QueryParser.parseTerm;default:n="expecting term or field, found '"+r.type+"'";throw new I.QueryParseError(n,r.start,r.end)}}},I.QueryParser.parseField=function(e){var t=e.consumeLexeme();if(null!=t){if(-1==e.query.allFields.indexOf(t.str)){var n=e.query.allFields.map((function(e){return"'"+e+"'"})).join(", "),r="unrecognised field '"+t.str+"', possible fields: "+n;throw new I.QueryParseError(r,t.start,t.end)}e.currentClause.fields=[t.str];var o=e.peekLexeme();if(null==o){r="expecting term, found nothing";throw new I.QueryParseError(r,t.start,t.end)}if(o.type===I.QueryLexer.TERM)return I.QueryParser.parseTerm;r="expecting term, found '"+o.type+"'";throw new I.QueryParseError(r,o.start,o.end)}},I.QueryParser.parseTerm=function(e){var t=e.consumeLexeme();if(null!=t){e.currentClause.term=t.str.toLowerCase(),-1!=t.str.indexOf("*")&&(e.currentClause.usePipeline=!1);var n=e.peekLexeme();if(null!=n)switch(n.type){case I.QueryLexer.TERM:return e.nextClause(),I.QueryParser.parseTerm;case I.QueryLexer.FIELD:return e.nextClause(),I.QueryParser.parseField;case I.QueryLexer.EDIT_DISTANCE:return I.QueryParser.parseEditDistance;case I.QueryLexer.BOOST:return I.QueryParser.parseBoost;case I.QueryLexer.PRESENCE:return e.nextClause(),I.QueryParser.parsePresence;default:var r="Unexpected lexeme type '"+n.type+"'";throw new I.QueryParseError(r,n.start,n.end)}else e.nextClause()}},I.QueryParser.parseEditDistance=function(e){var t=e.consumeLexeme();if(null!=t){var n=parseInt(t.str,10);if(isNaN(n)){var r="edit distance must be numeric";throw new I.QueryParseError(r,t.start,t.end)}e.currentClause.editDistance=n;var o=e.peekLexeme();if(null!=o)switch(o.type){case I.QueryLexer.TERM:return e.nextClause(),I.QueryParser.parseTerm;case I.QueryLexer.FIELD:return e.nextClause(),I.QueryParser.parseField;case I.QueryLexer.EDIT_DISTANCE:return I.QueryParser.parseEditDistance;case I.QueryLexer.BOOST:return I.QueryParser.parseBoost;case I.QueryLexer.PRESENCE:return e.nextClause(),I.QueryParser.parsePresence;default:r="Unexpected lexeme type '"+o.type+"'";throw new I.QueryParseError(r,o.start,o.end)}else e.nextClause()}},I.QueryParser.parseBoost=function(e){var t=e.consumeLexeme();if(null!=t){var n=parseInt(t.str,10);if(isNaN(n)){var r="boost must be numeric";throw new I.QueryParseError(r,t.start,t.end)}e.currentClause.boost=n;var o=e.peekLexeme();if(null!=o)switch(o.type){case I.QueryLexer.TERM:return e.nextClause(),I.QueryParser.parseTerm;case I.QueryLexer.FIELD:return e.nextClause(),I.QueryParser.parseField;case I.QueryLexer.EDIT_DISTANCE:return I.QueryParser.parseEditDistance;case I.QueryLexer.BOOST:return I.QueryParser.parseBoost;case I.QueryLexer.PRESENCE:return e.nextClause(),I.QueryParser.parsePresence;default:r="Unexpected lexeme type '"+o.type+"'";throw new I.QueryParseError(r,o.start,o.end)}else e.nextClause()}},void 0===(o="function"==typeof(r=function(){return I})?r.call(t,n,t,e):r)||(e.exports=o)}()},2497:(e,t,n)=>{"use strict";n.r(t)},2295:(e,t,n)=>{"use strict";n.r(t)},4865:function(e,t,n){var r,o;r=function(){var e,t,n={version:"0.2.0"},r=n.settings={minimum:.08,easing:"ease",positionUsing:"",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,showSpinner:!0,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:"body",template:'
'};function o(e,t,n){return en?n:e}function i(e){return 100*(-1+e)}function a(e,t,n){var o;return(o="translate3d"===r.positionUsing?{transform:"translate3d("+i(e)+"%,0,0)"}:"translate"===r.positionUsing?{transform:"translate("+i(e)+"%,0)"}:{"margin-left":i(e)+"%"}).transition="all "+t+"ms "+n,o}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=o(e,r.minimum,1),n.status=1===e?null:e;var i=n.render(!t),c=i.querySelector(r.barSelector),u=r.speed,d=r.easing;return i.offsetWidth,s((function(t){""===r.positionUsing&&(r.positionUsing=n.getPositioningCSS()),l(c,a(e,u,d)),1===e?(l(i,{transition:"none",opacity:1}),i.offsetWidth,setTimeout((function(){l(i,{transition:"all "+u+"ms linear",opacity:0}),setTimeout((function(){n.remove(),t()}),u)}),u)):setTimeout(t,u)})),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)*o(Math.random()*t,.1,.95)),t=o(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");u(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=r.template;var o,a=t.querySelector(r.barSelector),s=e?"-100":i(n.status||0),c=document.querySelector(r.parent);return l(a,{transition:"all 0 linear",transform:"translate3d("+s+"%,0,0)"}),r.showSpinner||(o=t.querySelector(r.spinnerSelector))&&f(o),c!=document.body&&u(c,"nprogress-custom-parent"),c.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&&f(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 s=function(){var e=[];function t(){var n=e.shift();n&&n(t)}return function(n){e.push(n),1==e.length&&t()}}(),l=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,o=e.length,i=t.charAt(0).toUpperCase()+t.slice(1);o--;)if((r=e[o]+i)in n)return r;return t}function o(e){return e=n(e),t[e]||(t[e]=r(e))}function i(e,t,n){t=o(t),e.style[t]=n}return function(e,t){var n,r,o=arguments;if(2==o.length)for(n in t)void 0!==(r=t[n])&&t.hasOwnProperty(n)&&i(e,n,r);else i(e,o[1],o[2])}}();function c(e,t){return("string"==typeof e?e:p(e)).indexOf(" "+t+" ")>=0}function u(e,t){var n=p(e),r=n+t;c(n,t)||(e.className=r.substring(1))}function d(e,t){var n,r=p(e);c(e,t)&&(n=r.replace(" "+t+" "," "),e.className=n.substring(1,n.length-1))}function p(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function f(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return n},void 0===(o="function"==typeof r?r.call(t,n,t,e):r)||(e.exports=o)},9901: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"},armasm:{title:"ARM Assembly",alias:"arm-asm",owner:"RunDevelopment"},arturo:{title:"Arturo",alias:"art",optional:["bash","css","javascript","markup","markdown","sql"],owner:"drkameleon"},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"},awk:{title:"AWK",alias:"gawk",aliasTitles:{gawk:"GAWK"},owner:"RunDevelopment"},bash:{title:"Bash",alias:["sh","shell"],aliasTitles:{sh:"Shell",shell:"Shell"},owner:"zeitgeist87"},basic:{title:"BASIC",owner:"Golmote"},batch:{title:"Batch",owner:"Golmote"},bbcode:{title:"BBcode",alias:"shortcode",aliasTitles:{shortcode:"Shortcode"},owner:"RunDevelopment"},bbj:{title:"BBj",owner:"hyyan"},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"},bqn:{title:"BQN",owner:"yewscion"},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"},cilkc:{title:"Cilk/C",require:"c",alias:"cilk-c",owner:"OpenCilk"},cilkcpp:{title:"Cilk/C++",require:"cpp",alias:["cilk-cpp","cilk"],owner:"OpenCilk"},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"},cooklang:{title:"Cooklang",owner:"ahue"},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"},cue:{title:"CUE",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"},gettext:{title:"gettext",alias:"po",owner:"RunDevelopment"},gherkin:{title:"Gherkin",owner:"hason"},git:{title:"Git",owner:"lgiraudel"},glsl:{title:"GLSL",require:"c",owner:"Golmote"},gn:{title:"GN",alias:"gni",owner:"RunDevelopment"},"linker-script":{title:"GNU Linker Script",alias:"ld",owner:"RunDevelopment"},go:{title:"Go",require:"clike",owner:"arnehormann"},"go-module":{title:"Go module",alias:"go-mod",owner:"RunDevelopment"},gradle:{title:"Gradle",require:"clike",owner:"zeabdelkhalek-badido18"},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","mustache"],aliasTitles:{mustache:"Mustache"},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"},mata:{title:"Mata",owner:"RunDevelopment"},matlab:{title:"MATLAB",owner:"Golmote"},maxscript:{title:"MAXScript",owner:"RunDevelopment"},mel:{title:"MEL",owner:"Golmote"},mermaid:{title:"Mermaid",owner:"RunDevelopment"},metafont:{title:"METAFONT",owner:"LaeriExNihilo"},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"},odin:{title:"Odin",owner:"edukisto"},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"},"plant-uml":{title:"PlantUML",alias:"plantuml",owner:"RunDevelopment"},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"},rescript:{title:"ReScript",alias:"res",owner:"vmarcosp"},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"},stata:{title:"Stata Ado",require:["mata","java","python"],owner:"RunDevelopment"},iecst:{title:"Structured Text (IEC 61131-3)",owner:"serhioromano"},stylus:{title:"Stylus",owner:"vkbansal"},supercollider:{title:"SuperCollider",alias:"sclang",owner:"RunDevelopment"},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"},wgsl:{title:"WGSL",owner:"Dr4gonthree"},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:(e,t,n)=>{const r=n(9901),o=n(9642),i=new Set;function a(e){void 0===e?e=Object.keys(r.languages).filter((e=>"meta"!=e)):Array.isArray(e)||(e=[e]);const t=[...i,...Object.keys(Prism.languages)];o(r,e,t).load((e=>{if(!(e in r.languages))return void(a.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),i.add(e)}))}a.silent=!1,e.exports=a},6854:()=>{!function(e){function t(e,t){return"___"+e.toUpperCase()+t+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,r,o,i){if(n.language===r){var a=n.tokenStack=[];n.code=n.code.replace(o,(function(e){if("function"==typeof i&&!i(e))return e;for(var o,s=a.length;-1!==n.code.indexOf(o=t(r,s));)++s;return a[s]=e,o})),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,r){if(n.language===r&&n.tokenStack){n.grammar=e.languages[r];var o=0,i=Object.keys(n.tokenStack);!function a(s){for(var l=0;l=i.length);l++){var c=s[l];if("string"==typeof c||c.content&&"string"==typeof c.content){var u=i[o],d=n.tokenStack[u],p="string"==typeof c?c:c.content,f=t(r,u),g=p.indexOf(f);if(g>-1){++o;var m=p.substring(0,g),h=new e.Token(r,e.tokenize(d,n.grammar),"language-"+r,d),b=p.substring(g+f.length),y=[];m&&y.push.apply(y,a([m])),y.push(h),b&&y.push.apply(y,a([b])),"string"==typeof c?s.splice.apply(s,[l,1].concat(y)):c.content=y}}else c.content&&a(c.content)}return s}(n.tokens)}}}})}(Prism)},6726:(e,t,n)=>{var r={"./":2885};function o(e){var t=i(e);return n(t)}function i(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}o.keys=function(){return Object.keys(r)},o.resolve=i,e.exports=o,o.id=6726},6500:(e,t,n)=>{var r={"./":2885};function o(e){var t=i(e);return n(t)}function i(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}o.keys=function(){return Object.keys(r)},o.resolve=i,e.exports=o,o.id=6500},9642: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 s={},l=e[r];if(l){function c(t){if(!(t in e))throw new Error(r+" depends on an unknown component "+t);if(!(t in s))for(var a in o(t,i),s[t]=!0,n[t])s[a]=!0}t(l.require,c),t(l.optional,c),t(l.modify,c)}n[r]=s,i.pop()}}return function(e){var t=n[e];return t||(o(e,r),t=n[e]),t}}function o(e){for(var t in e)return!0;return!1}return function(i,a,s){var l=function(e){var t={};for(var n in e){var r=e[n];for(var o in r)if("meta"!=o){var i=r[o];t[o]="string"==typeof i?{title:i}:i}}return t}(i),c=function(e){var n;return function(r){if(r in e)return r;if(!n)for(var o in n={},e){var i=e[o];t(i&&i.alias,(function(t){if(t in n)throw new Error(t+" cannot be alias for both "+o+" and "+n[t]);if(t in e)throw new Error(t+" cannot be alias of "+o+" because it is a component.");n[t]=o}))}return n[r]||r}}(l);a=a.map(c),s=(s||[]).map(c);var u=n(a),d=n(s);a.forEach((function e(n){var r=l[n];t(r&&r.require,(function(t){t in d||(u[t]=!0,e(t))}))}));for(var p,f=r(l),g=u;o(g);){for(var m in p={},g){var h=l[m];t(h&&h.modify,(function(e){e in d&&(p[e]=!0)}))}for(var b in d)if(!(b in u))for(var y in f(b))if(y in u){p[b]=!0;break}for(var v in g=p)u[v]=!0}var w={getIds:function(){var e=[];return w.load((function(t){e.push(t)})),e},load:function(t,n){return function(t,n,r,o){var i=o?o.series:void 0,a=o?o.parallel:e,s={},l={};function c(e){if(e in s)return s[e];l[e]=!0;var o,u=[];for(var d in t(e))d in n&&u.push(d);if(0===u.length)o=r(e);else{var p=a(u.map((function(e){var t=c(e);return delete l[e],t})));i?o=i(p,(function(){return r(e)})):r(e)}return s[e]=o}for(var u in n)c(u);var d=[];for(var p in l)d.push(s[p]);return a(d)}(f,u,t,n)}};return w}}();e.exports=t},2703:(e,t,n)=>{"use strict";var r=n(414);function o(){}function i(){}i.resetWarningCache=o,e.exports=function(){function e(e,t,n,o,i,a){if(a!==r){var s=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 s.name="Invariant Violation",s}}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:i,resetWarningCache:o};return n.PropTypes=n,n}},5697:(e,t,n)=>{e.exports=n(2703)()},414:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},4448:(e,t,n)=>{"use strict";var r=n(7294),o=n(3840);function i(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n