mirror of
https://github.com/vatesfr/xen-orchestra.git
synced 2026-10-11 22:50:01 +00:00
docs: full documentation revamp (#10212)
This commit is contained in:
@@ -5,3 +5,7 @@
|
||||
# Generated files
|
||||
/@xen-orchestra/web/src/route-map.d.ts
|
||||
/@xen-orchestra/lite/src/route-map.d.ts
|
||||
|
||||
# Docusaurus MDX content: prettier's markdown parser corrupts JSX
|
||||
# comments ({/* … */} becomes {/_ … _/}) and other MDX constructs
|
||||
/docs/docs/**/*.md
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
- [XO6/Host] Add possibility to shut down and start an host (PR [#10088](https://github.com/vatesfr/xen-orchestra/pull/10088))
|
||||
- [REST API] Add `hosts/:id/actions/scan_pifs` endpoint (PR [#10187](https://github.com/vatesfr/xen-orchestra/pull/10187))
|
||||
- [XO6/Host] Add possibility to scan PIFs directly from the host (PR [#10191](https://github.com/vatesfr/xen-orchestra/pull/10191))
|
||||
- [Docs] Improve doc, rename titles, and refactor menu (PR [#10212](https://github.com/vatesfr/xen-orchestra/pull/10212))
|
||||
|
||||
- [IPMI-plugin] Add GET plugins/ipmi-sensors/hosts/{id}/ipmi to get IPMI sensors (PR [#10003](https://github.com/vatesfr/xen-orchestra/pull/10003))
|
||||
|
||||
@@ -52,5 +53,4 @@
|
||||
- xo-server-ipmi-sensors minor
|
||||
- xo-server-netbox patch
|
||||
|
||||
|
||||
<!--packages-end-->
|
||||
|
||||
+4
-4
@@ -15,11 +15,11 @@ In this scenario, you will need a QA/pre-production XCP-ng pool with Internet ac
|
||||
|
||||
### Deployment
|
||||
|
||||
[Follow the standard procedure](./xo5/installation.md) to deploy the XOA on your pool with Internet access.
|
||||
[Follow the standard procedure](./installation.md) to deploy the XOA on your pool with Internet access.
|
||||
|
||||
Make sure that your appliance is [properly registered](./xo5/installation#registration) and [up-to-date](./xo5/updater).
|
||||
Make sure that your appliance is [properly registered](./installation.md#registration) and [up-to-date](./updater.md).
|
||||
|
||||
It's also good to take a quick look at [the XOA check](./xo5/xoa#xoa-check) to detect issues early.
|
||||
It's also good to take a quick look at [the XOA check](./troubleshooting.md#first-reflex-xoa-check) to detect issues early.
|
||||
|
||||
When everything is good, you can shutdown your XOA and export it:
|
||||
|
||||
@@ -50,7 +50,7 @@ To upgrade your XOA, you need to:
|
||||
1. shutdown the XOA on your airgapped pool
|
||||
2. export it to an XVA file
|
||||
3. move it to your connected pool and import it
|
||||
4. start it, run the [upgrade process](./xo5/updater)
|
||||
4. start it, run the [upgrade process](./updater.md)
|
||||
5. shutdown this XOA
|
||||
6. export it to an XVA file
|
||||
7. move it to your airgapped pool and import it
|
||||
|
||||
@@ -0,0 +1,228 @@
|
||||
# Architecture
|
||||
|
||||
Xen Orchestra (XO) is built as **one server and several clients**: the two web interfaces ([XO 6](xo6/gettingstarted.md) and XO 5), the command line client `xo-cli`, and anything speaking the [REST API](automation/restapi.md). The server, `xo-server`, is the only piece that talks to your infrastructure.
|
||||
|
||||
:::tip
|
||||
XO is totally agent-less: nothing to install on your hosts. `xo-server` speaks XAPI, the native toolstack of XCP-ng, directly over the network.
|
||||
:::
|
||||
|
||||
<Schema label="One server, several clients, your whole infrastructure" legend={[["#6aabf0", "XO"], ["#8e83fe", "XCP-ng"]]} maxWidth="720px">
|
||||
<svg viewBox="0 0 680 330" role="img" aria-label="XO 6, XO 5, xo-cli and REST API clients talk to xo-server, which connects to the master of every XCP-ng pool over XAPI">
|
||||
<g fill="rgba(255,255,255,0.04)" stroke="rgba(255,255,255,0.28)">
|
||||
<rect x="20" y="12" width="150" height="52" rx="8"/>
|
||||
<rect x="190" y="12" width="150" height="52" rx="8"/>
|
||||
<rect x="360" y="12" width="140" height="52" rx="8"/>
|
||||
<rect x="520" y="12" width="140" height="52" rx="8"/>
|
||||
</g>
|
||||
<g fontSize="12.5" fill="#c6d2e1" textAnchor="middle">
|
||||
<text x="95" y="34">XO 6</text>
|
||||
<text x="265" y="34">XO 5</text>
|
||||
<text x="430" y="34">xo-cli</text>
|
||||
<text x="590" y="34">REST API</text>
|
||||
</g>
|
||||
<g fontSize="10" fill="#7a8699" textAnchor="middle">
|
||||
<text x="95" y="52">web UI · Vue.js</text>
|
||||
<text x="265" y="52">web UI · React</text>
|
||||
<text x="430" y="52">command line</text>
|
||||
<text x="590" y="52">automation</text>
|
||||
</g>
|
||||
<g className="schema-flow" stroke="#7a8699" strokeWidth="1.4" strokeDasharray="5 4">
|
||||
<line x1="95" y1="64" x2="250" y2="120"/>
|
||||
<line x1="265" y1="64" x2="300" y2="120"/>
|
||||
<line x1="430" y1="64" x2="380" y2="120"/>
|
||||
<line x1="590" y1="64" x2="430" y2="120"/>
|
||||
</g>
|
||||
<rect x="190" y="120" width="300" height="60" rx="8" fill="rgba(106,171,240,0.12)" stroke="#6aabf0"/>
|
||||
<text x="340" y="145" fontSize="15" fill="#6aabf0" textAnchor="middle">xo-server</text>
|
||||
<text x="340" y="164" fontSize="10.5" fill="#7a8699" textAnchor="middle">Node.js daemon · events · cache · proxy</text>
|
||||
<g className="schema-flow" stroke="#6aabf0" strokeWidth="1.6" strokeDasharray="5 4">
|
||||
<line x1="270" y1="180" x2="170" y2="230"/>
|
||||
<line x1="410" y1="180" x2="510" y2="230"/>
|
||||
</g>
|
||||
<line className="schema-flow" x1="340" y1="180" x2="340" y2="230" stroke="#6aabf0" strokeOpacity="0.7" strokeWidth="1.6" strokeDasharray="5 4"/>
|
||||
<text x="272" y="212" fontSize="9.5" fill="#7a8699">XAPI</text>
|
||||
<rect x="328" y="230" width="24" height="88" rx="8" fill="none" stroke="rgba(255,255,255,0.22)" strokeDasharray="6 5"/>
|
||||
<text x="340" y="280" fontSize="16" fill="#7a8699" textAnchor="middle">…</text>
|
||||
<g fill="none" stroke="rgba(255,255,255,0.22)" strokeDasharray="6 5">
|
||||
<rect x="20" y="230" width="300" height="88" rx="10"/>
|
||||
<rect x="360" y="230" width="300" height="88" rx="10"/>
|
||||
</g>
|
||||
<text x="36" y="252" fontSize="12.5" fill="#7a8699">Pool 1</text>
|
||||
<text x="376" y="252" fontSize="12.5" fill="#7a8699">Pool 12</text>
|
||||
<g fill="rgba(142,131,254,0.14)" stroke="#8e83fe" strokeOpacity="0.85">
|
||||
<rect x="36" y="264" width="120" height="40" rx="5"/>
|
||||
<rect x="376" y="264" width="120" height="40" rx="5"/>
|
||||
</g>
|
||||
<g fill="rgba(142,131,254,0.08)" stroke="#8e83fe" strokeOpacity="0.4">
|
||||
<rect x="168" y="264" width="64" height="40" rx="5"/>
|
||||
<rect x="240" y="264" width="64" height="40" rx="5"/>
|
||||
<rect x="508" y="264" width="64" height="40" rx="5"/>
|
||||
<rect x="580" y="264" width="64" height="40" rx="5"/>
|
||||
</g>
|
||||
<g fontSize="11.5" fill="#8e83fe" textAnchor="middle">
|
||||
<text x="96" y="282">pool master</text>
|
||||
<text x="436" y="282">pool master</text>
|
||||
</g>
|
||||
<g fontSize="10" fill="#8e83fe" fillOpacity="0.6" textAnchor="middle">
|
||||
<text x="200" y="282">host</text>
|
||||
<text x="272" y="282">host</text>
|
||||
<text x="540" y="282">host</text>
|
||||
<text x="612" y="282">host</text>
|
||||
</g>
|
||||
<g fontSize="9.5" fill="#7a8699" textAnchor="middle">
|
||||
<text x="96" y="297">XCP-ng</text>
|
||||
<text x="436" y="297">XCP-ng</text>
|
||||
</g>
|
||||
<g fontSize="9" fill="#7a8699" fillOpacity="0.7" textAnchor="middle">
|
||||
<text x="200" y="297">XCP-ng</text>
|
||||
<text x="272" y="297">XCP-ng</text>
|
||||
<text x="540" y="297">XCP-ng</text>
|
||||
<text x="612" y="297">XCP-ng</text>
|
||||
</g>
|
||||
</svg>
|
||||
</Schema>
|
||||
|
||||
Note that `xo-server` only needs to reach the **master** of each pool: the master relays to the other hosts of its pool. One XO connects to any number of pools, on any site.
|
||||
|
||||
## XOA
|
||||
|
||||
The _Xen Orchestra Appliance_ (XOA) is a VM with the whole stack pre-installed, configured and QA validated. It is the way we recommend and support running XO: see [Installation](installation.md).
|
||||
|
||||
## xo-server
|
||||
|
||||
[`xo-server`](https://github.com/vatesfr/xen-orchestra/tree/master/packages/xo-server/) is the heart of Xen Orchestra: a Node.js daemon connected permanently to your pools. Its central position is what makes XO more than a mere client:
|
||||
|
||||
- **Always on**: as a daemon, it listens to and records every event of your infrastructure, around the clock, whether a client is watching or not. That is what makes always-up-to-date views, scheduled backup jobs and task history possible.
|
||||
- **Event driven**: `xo-server` subscribes to XAPI events instead of polling. Changes on a host or VM appear in your browser the moment they happen, and the server-side cache answers clients instantly, at any infrastructure size.
|
||||
- **A single connection point**: clients connect to `xo-server`, never to your hosts. Legacy thick clients opened connections from every admin workstation to every server; here one daemon holds one connection per pool, and any number of clients share it.
|
||||
- **A proxy for your hosts**: because everything flows through it, `xo-server` can expose VM consoles to clients that have no network access to the hosts, or stream a VM export from one pool straight into another (that is [warm migration](xo5/manage_infrastructure.md) territory) without a file stop in between.
|
||||
- **Pluggable**: features like LDAP authentication, load balancing, netbox synchronization or backup reports are [plugins](#plugins), not core patches.
|
||||
|
||||
### Events, not polling
|
||||
|
||||
Legacy clients ask the servers "anything new?" every few seconds: slow, and it collapses at scale. `xo-server` subscribes once to the XAPI event stream, and pushes every change to all connected clients the moment it happens:
|
||||
|
||||
<Schema label="Polling asks, events arrive" legend={[["#6aabf0", "XO"], ["#8e83fe", "XCP-ng"]]} maxWidth="680px">
|
||||
<svg viewBox="0 0 680 230" role="img" aria-label="Legacy polling asks the host for news every few seconds; with Xen Orchestra, XAPI events flow from the host through xo-server to every client the moment they happen">
|
||||
<g fill="none" stroke="rgba(255,255,255,0.22)" strokeDasharray="6 5">
|
||||
<rect x="20" y="14" width="290" height="200" rx="10"/>
|
||||
<rect x="370" y="14" width="290" height="200" rx="10"/>
|
||||
</g>
|
||||
<text x="36" y="38" fontSize="12" fill="#7a8699">polling · legacy clients</text>
|
||||
<text x="386" y="38" fontSize="12" fill="#7a8699">events · Xen Orchestra</text>
|
||||
{/* Polling side: client asks, waits, asks again. */}
|
||||
<rect x="95" y="52" width="140" height="34" rx="6" fill="rgba(255,255,255,0.04)" stroke="rgba(255,255,255,0.28)"/>
|
||||
<text x="165" y="73" fontSize="11.5" fill="#c6d2e1" textAnchor="middle">client</text>
|
||||
<rect x="95" y="164" width="140" height="34" rx="6" fill="rgba(142,131,254,0.14)" stroke="#8e83fe" strokeOpacity="0.85"/>
|
||||
<text x="165" y="185" fontSize="11.5" fill="#8e83fe" textAnchor="middle">host</text>
|
||||
<line x1="165" y1="86" x2="165" y2="164" stroke="rgba(255,255,255,0.22)" strokeDasharray="5 4"/>
|
||||
<text x="180" y="130" fontSize="9.5" fill="#7a8699">"anything new?" every x seconds</text>
|
||||
<g className="schema-packet" opacity="0">
|
||||
<rect x="-9" y="-8" width="18" height="16" rx="8" fill="rgba(255,255,255,0.08)" stroke="rgba(255,255,255,0.4)"/>
|
||||
<text x="0" y="3.5" fontSize="10" fill="#c6d2e1" textAnchor="middle">?</text>
|
||||
<animateMotion dur="6s" repeatCount="indefinite" calcMode="linear"
|
||||
path="M165,96 L165,154"
|
||||
keyPoints="0;0;1;1" keyTimes="0;0.55;0.75;1"/>
|
||||
<animate attributeName="opacity" dur="6s" repeatCount="indefinite"
|
||||
values="0;0;1;1;0;0" keyTimes="0;0.55;0.6;0.72;0.76;1"/>
|
||||
</g>
|
||||
{/* Events side: host pushes through xo-server to every client, instantly. */}
|
||||
<g fill="rgba(255,255,255,0.04)" stroke="rgba(255,255,255,0.28)">
|
||||
<rect x="390" y="52" width="115" height="30" rx="6"/>
|
||||
<rect x="525" y="52" width="115" height="30" rx="6"/>
|
||||
</g>
|
||||
<g fontSize="10.5" fill="#c6d2e1" textAnchor="middle">
|
||||
<text x="447" y="71">client</text>
|
||||
<text x="582" y="71">client</text>
|
||||
</g>
|
||||
<rect x="440" y="104" width="150" height="32" rx="6" fill="rgba(106,171,240,0.12)" stroke="#6aabf0"/>
|
||||
<text x="515" y="124" fontSize="11.5" fill="#6aabf0" textAnchor="middle">xo-server</text>
|
||||
<rect x="445" y="166" width="140" height="34" rx="6" fill="rgba(142,131,254,0.14)" stroke="#8e83fe" strokeOpacity="0.85"/>
|
||||
<text x="515" y="187" fontSize="11.5" fill="#8e83fe" textAnchor="middle">host</text>
|
||||
<g className="schema-flow" stroke="#6aabf0" strokeWidth="1.4" strokeDasharray="5 4">
|
||||
<line x1="515" y1="166" x2="515" y2="136"/>
|
||||
<line x1="497" y1="104" x2="450" y2="82"/>
|
||||
<line x1="533" y1="104" x2="580" y2="82"/>
|
||||
</g>
|
||||
<text x="600" y="150" fontSize="9.5" fill="#7a8699" textAnchor="middle">instant</text>
|
||||
<g className="schema-packet" opacity="0">
|
||||
<circle r="5" fill="#56c288"/>
|
||||
<animateMotion dur="5s" repeatCount="indefinite" calcMode="linear"
|
||||
path="M515,160 L515,140 L497,104 L452,84"
|
||||
keyPoints="0;0;1;1" keyTimes="0;0.1;0.32;1"/>
|
||||
<animate attributeName="opacity" dur="5s" repeatCount="indefinite"
|
||||
values="0;0;1;1;0;0" keyTimes="0;0.1;0.13;0.29;0.33;1"/>
|
||||
</g>
|
||||
<g className="schema-packet" opacity="0">
|
||||
<circle r="5" fill="#56c288"/>
|
||||
<animateMotion dur="5s" repeatCount="indefinite" calcMode="linear"
|
||||
path="M515,160 L515,140 L533,104 L578,84"
|
||||
keyPoints="0;0;1;1" keyTimes="0;0.1;0.32;1"/>
|
||||
<animate attributeName="opacity" dur="5s" repeatCount="indefinite"
|
||||
values="0;0;1;1;0;0" keyTimes="0;0.1;0.13;0.29;0.33;1"/>
|
||||
</g>
|
||||
</svg>
|
||||
</Schema>
|
||||
|
||||
## The web interfaces
|
||||
|
||||
Two web UIs currently ship with Xen Orchestra, served by `xo-server` and talking to it over WebSockets:
|
||||
|
||||
- **XO 6** (`@xen-orchestra/web`), the new default interface, built with Vue.js on a dedicated design system. See the [XO 6 documentation](xo6/gettingstarted.md).
|
||||
- **XO 5** (`xo-web`), the complete historical interface, built with React. See [the infrastructure management section](xo5/manage_infrastructure.md) for what you can do with it.
|
||||
|
||||
<UiShot light="/img/xo6/dashboard-light.png" dark="/img/xo6/dashboard-dark.png" alt="XO 6, the new default web interface" url="https://your-xo/v6/#/dashboard" />
|
||||
|
||||
Both run against the same server and the same data at the same time: see [XO 6 vs. XO 5](xo6/xo6vsxo5.md).
|
||||
|
||||
## xo-cli
|
||||
|
||||
[`xo-cli`](https://github.com/vatesfr/xen-orchestra/tree/master/packages/xo-cli) sends commands to `xo-server` from a shell. Thanks to introspection, it discovers every method the server exposes, plus a convenient wrapper around the REST API.
|
||||
|
||||
:::warning
|
||||
`xo-cli` is mainly a debug and power-user tool: there is no absolute guarantee on its stability. Prefer the [REST API](automation/restapi.md) for automation.
|
||||
:::
|
||||
|
||||
Register your XO instance first (only a token is stored):
|
||||
|
||||
<Terminal title="workstation — register your XO">{`
|
||||
xo-cli register http://xo.my-company.net [email protected] admin
|
||||
Successfully logged with [email protected]
|
||||
`}</Terminal>
|
||||
|
||||
Discover what the server exposes:
|
||||
|
||||
<Terminal shell title="workstation — explore the API">{`
|
||||
xo-cli list-commands # every available method
|
||||
xo-cli list-commands '{user,group}.*' # filtered by pattern
|
||||
xo-cli list-objects type=VM-template # objects, filterable by properties
|
||||
`}</Terminal>
|
||||
|
||||
Then call any method with `xo-cli <command> <param>=<value>`:
|
||||
|
||||
<Terminal title="workstation — add a server">{`
|
||||
xo-cli server.add host=my.server.net username=root password=secret-password
|
||||
42
|
||||
`}</Terminal>
|
||||
|
||||
Parameters are strings by default (`true`/`false` are parsed as booleans); prefix with `json:` for other types (`baz='json:[1, 2, 3]'`). `xo-cli help` documents everything, including the `xo-cli rest get|post|patch|del` subcommands that map directly onto the REST API.
|
||||
|
||||
:::note
|
||||
`xo-cli` imports XVA files only (`xo-cli vm.import sr=<SR UUID> @=vm.xva`). For OVA imports, use the web UI or [`xo-upload-ova`](https://github.com/vatesfr/xen-orchestra/blob/master/@xen-orchestra/upload-ova/README.md#xo-upload-ova).
|
||||
:::
|
||||
|
||||
## APIs
|
||||
|
||||
The public, supported API of Xen Orchestra is the **[REST API](automation/restapi.md)**: plain HTTP, easy to call from any language or tool, with its own documentation page and a live OpenAPI reference at `/rest/v0/docs/` on your XO.
|
||||
|
||||
Internally, the web UIs and `xo-cli` talk to `xo-server` over a JSON-RPC-over-WebSockets protocol: that connected mode is what lets clients subscribe to events and stay current in real time. This internal API is not designed for third parties: if you automate against XO, use the REST API.
|
||||
|
||||
## Plugins
|
||||
|
||||
Plugins extend Xen Orchestra without touching its core. They live in "Settings, then Plugins":
|
||||
|
||||
<UiDetail src="/img/xoa/plugins-menu.png" alt="The Plugins page in Settings" width={520} />
|
||||
|
||||
Each plugin can be activated or deactivated, loaded at startup, and configured entirely from the web interface:
|
||||
|
||||
<UiDetail src="/img/xoa/plugins-page.png" alt="Configuring a plugin from the web interface" width={520} />
|
||||
@@ -0,0 +1,207 @@
|
||||
# Ansible dynamic inventory
|
||||
|
||||
## Introduction
|
||||
|
||||
Dynamic inventory is a powerful Ansible feature that discovers the hosts to manage from an external source instead of a static file. The [`community.general.xen_orchestra`](https://docs.ansible.com/ansible/latest/collections/community/general/xen_orchestra_inventory.html) inventory plugin connects to your **Xen Orchestra** instance and builds an inventory from the virtual machines (VMs) it manages, so your automation always targets the real state of your infrastructure.
|
||||
|
||||
:::tip
|
||||
With dynamic inventory, there is no need to manually maintain static inventory files. Your VMs are automatically discovered and classified into groups based on their properties.
|
||||
:::
|
||||
|
||||
## Prerequisites {#installing-prerequisites}
|
||||
|
||||
- a running **Xen Orchestra** instance connected to an **XCP-ng** pool
|
||||
- Ansible with the `community.general` collection, version 4.1.0 or newer (the version that introduced the plugin)
|
||||
- the `websocket-client` Python library, version 1.0.0 or newer (the plugin talks to the XO JSON-RPC API over a websocket)
|
||||
- an XO **user account**: this plugin authenticates with a username and password (it does not support API tokens)
|
||||
|
||||
<Terminal shell title="install the requirements and check the plugin is available">{`
|
||||
ansible-galaxy collection install community.general
|
||||
pip install "websocket-client>=1.0.0"
|
||||
ansible-doc -t inventory community.general.xen_orchestra
|
||||
`}</Terminal>
|
||||
|
||||
## Configuring the inventory {#configuring-xen-orchestra-dynamic-inventory}
|
||||
|
||||
### Minimal configuration {#basic-configuration}
|
||||
|
||||
Create a configuration file for the dynamic inventory, for example `my.xen_orchestra.yml`:
|
||||
|
||||
```yaml
|
||||
# my.xen_orchestra.yml
|
||||
plugin: community.general.xen_orchestra
|
||||
api_host: your-xo-hostname
|
||||
user: your_username
|
||||
password: your_password
|
||||
use_ssl: true # connect over wss:// (set to false for plain ws://)
|
||||
validate_certs: true # set to false if XO uses a self-signed certificate
|
||||
```
|
||||
|
||||
:::tip
|
||||
The file name must end with `.xen_orchestra.yml` or `.xen_orchestra.yaml` for the plugin to load it.
|
||||
:::
|
||||
|
||||
:::note
|
||||
`api_host` takes a hostname or IP address, without a `ws://` or `wss://` prefix: the plugin builds the websocket URL itself from `use_ssl`. The connection settings can also come from the `ANSIBLE_XO_HOST`, `ANSIBLE_XO_USER`, and `ANSIBLE_XO_PASSWORD` environment variables.
|
||||
:::
|
||||
|
||||
### Securing credentials {#using-ansible-vault}
|
||||
|
||||
:::warning
|
||||
Never keep plain-text credentials in a file that reaches version control. In production, store them with Ansible Vault or pass them through the environment variables above.
|
||||
:::
|
||||
|
||||
Create an encrypted file for your secrets:
|
||||
|
||||
<Terminal shell title="create an encrypted secrets file">{`
|
||||
ansible-vault create vault.yml
|
||||
`}</Terminal>
|
||||
|
||||
with the following content:
|
||||
|
||||
```yaml
|
||||
# vault.yml
|
||||
xo_host: your-xo-hostname
|
||||
xo_user: your_username
|
||||
xo_password: your_password
|
||||
```
|
||||
|
||||
then reference these variables from the inventory configuration:
|
||||
|
||||
```yaml
|
||||
# my.xen_orchestra.yml
|
||||
plugin: community.general.xen_orchestra
|
||||
api_host: "{{ xo_host }}"
|
||||
user: "{{ xo_user }}"
|
||||
password: "{{ xo_password }}"
|
||||
use_ssl: true
|
||||
validate_certs: true
|
||||
```
|
||||
|
||||
:::tip
|
||||
When using Ansible Vault, add `--ask-vault-pass` (or `--vault-password-file ~/.vault_pass.txt`) and `-e @vault.yml` to your commands.
|
||||
:::
|
||||
|
||||
## Using the inventory {#using-dynamic-inventory}
|
||||
|
||||
<Terminal shell title="explore the inventory, then ping every VM">{`
|
||||
ansible-inventory -i my.xen_orchestra.yml --list
|
||||
ansible-inventory -i my.xen_orchestra.yml --graph
|
||||
ansible-inventory -i my.xen_orchestra.yml --host=uuid-of-your-vm
|
||||
ansible -i my.xen_orchestra.yml all -m ping
|
||||
`}</Terminal>
|
||||
|
||||
`--list` dumps the whole inventory, `--graph` displays the groups as a tree, and `--host` shows the variables of a single VM (identified by its UUID in XO). For each VM, the plugin exposes its XO properties as host variables:
|
||||
|
||||
```json
|
||||
{
|
||||
"ansible_host": "192.0.2.10",
|
||||
"cpus": 1,
|
||||
"has_ip": true,
|
||||
"ip": "192.0.2.10",
|
||||
"is_managed": true,
|
||||
"memory": 2147467264,
|
||||
"name_label": "XO Tutorial",
|
||||
"os_version": {
|
||||
"distro": "Ubuntu",
|
||||
"name": "Ubuntu 24.04",
|
||||
"uname": "6.8.0-57-generic"
|
||||
},
|
||||
"power_state": "running",
|
||||
"tags": [],
|
||||
"type": "VM",
|
||||
"uuid": "0ae54d06-e3e2-100c-00e8-46f67945e37c"
|
||||
}
|
||||
```
|
||||
|
||||
## Groups and host variables {#advanced-use-of-dynamic-inventory}
|
||||
|
||||
VMs are automatically grouped under their pool and host. On top of that, the plugin supports the standard constructed-inventory options: `groups` (conditional groups), `keyed_groups` (one group per property value), and `compose` (custom host variables), all evaluated against the host variables shown above.
|
||||
|
||||
```yaml
|
||||
plugin: community.general.xen_orchestra
|
||||
api_host: your-xo-hostname
|
||||
user: your_username
|
||||
password: your_password
|
||||
use_ssl: true
|
||||
validate_certs: true
|
||||
|
||||
# Conditional groups
|
||||
groups:
|
||||
running: power_state == "running"
|
||||
halted: power_state == "halted"
|
||||
ubuntu: "'Ubuntu' in name_label"
|
||||
critical: "'critical' in tags"
|
||||
|
||||
# One group per value of a property
|
||||
keyed_groups:
|
||||
- prefix: state
|
||||
key: power_state
|
||||
|
||||
# Custom host variables
|
||||
compose:
|
||||
ansible_user: "'ubuntu' if 'Ubuntu' in name_label else 'root'"
|
||||
xo_vm_name: name_label
|
||||
```
|
||||
|
||||
:::note
|
||||
`power_state` is lowercase in the inventory (`running`, `halted`), even though XO displays `Running` and `Halted` in its UI.
|
||||
:::
|
||||
|
||||
## Using it in playbooks {#use-in-ansible-playbooks}
|
||||
|
||||
Any group built by the inventory can be targeted in a playbook. This one updates every running Debian or Ubuntu VM, using the `running` group defined above:
|
||||
|
||||
```yaml
|
||||
# update-running-vms.yml
|
||||
---
|
||||
- name: Update all running Debian and Ubuntu VMs
|
||||
hosts: running
|
||||
gather_facts: true
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Update package index and upgrade packages
|
||||
ansible.builtin.apt:
|
||||
update_cache: true
|
||||
upgrade: dist
|
||||
when: ansible_distribution in ["Ubuntu", "Debian"]
|
||||
|
||||
- name: Check if a reboot is required
|
||||
ansible.builtin.stat:
|
||||
path: /var/run/reboot-required
|
||||
register: reboot_required
|
||||
when: ansible_distribution in ["Ubuntu", "Debian"]
|
||||
|
||||
- name: Reboot if required
|
||||
ansible.builtin.reboot:
|
||||
when: reboot_required.stat.exists | default(false)
|
||||
```
|
||||
|
||||
<Terminal shell title="run the playbook against the dynamic inventory">{`
|
||||
ansible-playbook -i my.xen_orchestra.yml update-running-vms.yml
|
||||
`}</Terminal>
|
||||
|
||||
## Troubleshooting {#troubleshooting-and-debugging}
|
||||
|
||||
1. **Connection problems**: check `api_host` (hostname only, no scheme), the credentials, and that `use_ssl` matches how your XO is exposed (HTTPS or plain HTTP).
|
||||
2. **Empty inventory**: make sure the XO account can actually see the VMs (an unprivileged user only sees the objects it has access to).
|
||||
3. **Missing `ansible_host`**: a VM without guest tools reports no IP address; `has_ip` is `false` and `ansible_host` stays empty.
|
||||
|
||||
For more detail, run the inventory in debug mode:
|
||||
|
||||
<Terminal shell title="dump the inventory with debug output">{`
|
||||
ANSIBLE_DEBUG=1 ansible-inventory -i my.xen_orchestra.yml --list
|
||||
`}</Terminal>
|
||||
|
||||
## Going further {#conclusion}
|
||||
|
||||
The [plugin documentation](https://docs.ansible.com/ansible/latest/collections/community/general/xen_orchestra_inventory.html) is the reference for every option (caching, `use_vm_uuid`, `use_host_uuid`, and more) and is always up to date with the collection, and the [plugin source code](https://github.com/ansible-collections/community.general/blob/main/plugins/inventory/xen_orchestra.py) is available in the `community.general` repository.
|
||||
|
||||
## Related links
|
||||
|
||||
- [xen_orchestra inventory plugin documentation](https://docs.ansible.com/ansible/latest/collections/community/general/xen_orchestra_inventory.html)
|
||||
- [Plugin source code](https://github.com/ansible-collections/community.general/blob/main/plugins/inventory/xen_orchestra.py)
|
||||
- [Ansible documentation on dynamic inventories](https://docs.ansible.com/ansible/latest/inventory_guide/intro_dynamic_inventory.html)
|
||||
- [VirtOps #3: Ansible with Xen Orchestra (blog post)](https://xen-orchestra.com/blog/virtops3-ansible-with-xen-orchestra/)
|
||||
- [XCP-ng Forum](https://xcp-ng.org/forum/)
|
||||
@@ -0,0 +1,223 @@
|
||||
# Deploy Kubernetes with recipes
|
||||
|
||||
## Introduction
|
||||
|
||||
Xen Orchestra includes a Kubernetes cluster [recipe](../xo5/advanced.md#recipes) that provides a simple way to deploy an official Kubernetes distribution called **MicroK8s** (maintained by Canonical).
|
||||
|
||||
:::tip
|
||||
One of the key benefits of MicroK8s is its automatic security updates. For example, patch releases (like 1.30.x to 1.30.x+1) are applied automatically. This saves Kubernetes admins a lot of time and effort.
|
||||
:::
|
||||
|
||||
### Networking and CNI
|
||||
|
||||
This recipe uses **Calico**, the default Container Network Interface (CNI) plugin included with MicroK8s, to handle container networking. Calico provides secure networking and network policies for Kubernetes, and its default configuration is ready for production: no additional setup required.
|
||||
|
||||
If you need to adjust the Calico setup, check the [MicroK8s documentation](https://microk8s.io/docs/change-cidr) for step-by-step instructions.
|
||||
|
||||
#### Configure the pod CIDR
|
||||
|
||||
Since version 5.113 of Xen Orchestra, the pod and service CIDR can be customized via the recipe form. There is no need to perform manual configuration to change them. See [Deployment steps](./kubernetes.md#deployment-steps).
|
||||
|
||||
:::note
|
||||
The default CIDR for pods is `10.1.0.0/16`. All pods are assigned an IP address in that range.
|
||||
|
||||
The default service CIDR is `10.152.183.0/24`. `10.152.183.1` is reserved for the Kubernetes API, and `10.152.183.10` is used by CoreDNS.
|
||||
:::
|
||||
|
||||
### Cloud Controller Manager
|
||||
|
||||
This recipe automatically deploys the [Xen Orchestra Cloud Controller Manager](https://github.com/vatesfr/xenorchestra-cloud-controller-manager) (CCM), a bridge between your Kubernetes cluster and the underlying Xen Orchestra instance. In short, it:
|
||||
|
||||
- **initializes nodes**: sets the `providerID`, node addresses, taints, and Xen Orchestra labels (pool, host) on each node
|
||||
- **manages the node lifecycle**: when a VM is deleted from Xen Orchestra, the associated node is automatically removed from the cluster
|
||||
- **keeps labels in sync**: XO metadata is periodically reconciled back to the Kubernetes nodes
|
||||
|
||||
The [CCM repository](https://github.com/vatesfr/xenorchestra-cloud-controller-manager) is the source of truth for its features, configuration and standalone installation (manifests and Helm chart).
|
||||
|
||||
For the CCM to function properly, the Xen Orchestra instance must be reachable by the cluster nodes (VMs) via either an FQDN or IP address (see [Deployment steps](./kubernetes.md#deployment-steps)).
|
||||
|
||||
The recipe automatically generates an API token for the current user with a validity of 6 months.
|
||||
|
||||
:::warning
|
||||
You will need to renew this token and update the `xenorchestra-cloud-controller-manager` secret in the Kubernetes cluster before it expires to maintain CCM functionality.
|
||||
:::
|
||||
|
||||
#### Viewing the Current Token
|
||||
|
||||
To view the current token configuration in the secret:
|
||||
|
||||
<Terminal shell title="control plane node — show the CCM configuration">{`
|
||||
kubectl get secret xenorchestra-cloud-controller-manager \\
|
||||
--namespace=kube-system \\
|
||||
-o json | jq -r '.data["config.yaml"]' | base64 -d
|
||||
`}</Terminal>
|
||||
|
||||
#### Refreshing the API Token
|
||||
|
||||
To refresh the token, generate a new one using the Xen Orchestra API and update the Kubernetes secret:
|
||||
|
||||
<Terminal shell title="renew the CCM token">{`
|
||||
# 1. Generate a new token (replace with your XO URL)
|
||||
# add -k if the certificate is self-signed
|
||||
NEW_TOKEN=$(curl -X 'POST' \\
|
||||
--header 'Cookie: authenticationToken=<current-token>' \\
|
||||
'https://your-xo-instance.example.com/rest/v0/users/me/authentication_tokens' \\
|
||||
-H 'accept: application/json' \\
|
||||
-H 'Content-Type: application/json' \\
|
||||
-d '{ "description": "token for CCM", "expiresIn": "6 months" }' | jq -r '.token.id')
|
||||
# 2. Update the secret with the new token
|
||||
kubectl get secret xenorchestra-cloud-controller-manager \\
|
||||
--namespace=kube-system \\
|
||||
-o json | \\
|
||||
jq --arg token "$NEW_TOKEN" '.data["config.yaml"] |= (@base64d | sub("token: .+"; "token: " + $token) | @base64)' | \\
|
||||
kubectl apply -f -
|
||||
`}</Terminal>
|
||||
|
||||
## Before you start
|
||||
|
||||
Make sure your infrastructure meets these requirements:
|
||||
|
||||
- A running Xen Orchestra instance connected to an XCP-ng pool
|
||||
- Enough resources to host the **control plane** and **worker nodes** (each node gets a 10 GB disk; CPU and RAM can be [adjusted after deployment](#adjusting-vm-resources))
|
||||
- Internet access from the pool and the node network: the recipe downloads its own **Debian 13** base image and the MicroK8s snap, so you do not need to prepare a VM template
|
||||
- The Xen Orchestra instance must be reachable by the cluster nodes (VMs), via an FQDN or an IP address, for the [Cloud Controller Manager](#cloud-controller-manager)
|
||||
|
||||
## Deployment steps
|
||||
|
||||
1. In Xen Orchestra 5, go to **Hub → Recipes**.\
|
||||
A list of recipes appears:
|
||||
|
||||
<UiShot light="/img/xo5/hub-recipes.png" alt="The Recipes view of the Hub, with the Kubernetes cluster recipe" url="https://your-xo/v5/#/hub/recipes" />
|
||||
|
||||
2. Go to the **Kubernetes cluster** recipe and click **Create**.\
|
||||
A cluster creation form appears:
|
||||
|
||||
<UiDetail src="/img/xo5/k8s-cluster-form.png" alt="The Kubernetes cluster creation form" width={420} />
|
||||
|
||||
3. Configure your cluster:
|
||||
1. Select a pool where you want to deploy your cluster.
|
||||
2. Select a storage repository, a network and a Kubernetes version.
|
||||
3. Enter a name for your cluster.\
|
||||
The name will be used to tag VMs (see [VM tagging](./kubernetes.md#vm-tagging)).
|
||||
4. Define the number of worker nodes.
|
||||
5. Choose the fault tolerance level for the control plane, which sets the number of control plane nodes (three or more enables high availability).
|
||||
6. Define the FQDN or IP address that the Cloud Controller Manager (CCM) will use to reach this Xen Orchestra instance.\
|
||||
_If the instance uses a self-signed HTTPS certificate, toggle "Allow insecure XO connection"._
|
||||
7. (Optional) To change the default CIDR for your cluster pods and services, check the **Use a custom cluster CIDR** box and specify the new IP ranges to use.
|
||||
|
||||
<UiDetail src="/img/xo5/k8s-custom-cidr.png" alt="The custom pod and service CIDR fields" width={480} />
|
||||
|
||||
8. (Optional) If you want your cluster to use static IP addresses, check the **Static IP addresses** box and specify the IP address parameters:
|
||||
|
||||
<UiDetail src="/img/xo5/k8s-static-ips.png" alt="The static IP address parameters" width={520} />
|
||||
|
||||
4. Click **OK** to start deploying the cluster.
|
||||
|
||||
Xen Orchestra handles the rest: cloning VMs, assigning IPs, bootstrapping Kubernetes and configuring internal networking.
|
||||
|
||||
### VM tagging
|
||||
|
||||
The name provided to the cluster is also used to tag its VMs, so that you can easily find them all:
|
||||
|
||||
<UiDetail src="/img/xo5/k8s-cluster-tags.png" alt="The cluster VMs, tagged with the cluster name" width={720} />
|
||||
|
||||
## During deployment
|
||||
|
||||
Follow the progress on the **Tasks** screen while the cluster is being created:
|
||||
|
||||
<UiDetail src="/img/xo5/k8s-deploy-tasks.png" alt="The recipe tasks running during cluster deployment" width={720} />
|
||||
|
||||
## Using your cluster
|
||||
|
||||
### Connecting to your cluster
|
||||
|
||||
Once the cluster and its VMs are ready, SSH into the first control plane node as the `debian` user (the nodes run Debian 13). From there, you can manage your Kubernetes cluster:
|
||||
|
||||
<Terminal title="control plane node — list the cluster nodes">{`
|
||||
microk8s kubectl get nodes
|
||||
NAME STATUS ROLES AGE VERSION
|
||||
cp-1 Ready <none> 40m v1.33.0
|
||||
cp-2 Ready <none> 30m v1.33.0
|
||||
cp-3 Ready <none> 31m v1.33.0
|
||||
worker-1 Ready <none> 31m v1.33.0
|
||||
worker-2 Ready <none> 31m v1.33.0
|
||||
worker-3 Ready <none> 31m v1.33.0
|
||||
`}</Terminal>
|
||||
|
||||
### Adjusting VM Resources
|
||||
|
||||
The VMs in your Kubernetes cluster are created with default CPU and RAM settings, but you can easily adjust these to match your workload needs. This gives you the flexibility to fine-tune performance or cut costs, depending on what your use case demands.
|
||||
|
||||
### Keeping your cluster updated
|
||||
|
||||
:::tip
|
||||
MicroK8s handles **patch releases** automatically by design, so you always benefit from the latest security fixes and improvements without manual intervention.
|
||||
:::
|
||||
|
||||
For **minor version upgrades** (for example, from `1.30.x` to `1.31.x`), follow the official [MicroK8s upgrade guide](https://microk8s.io/docs/upgrading). These upgrades typically involve checking the current version, refreshing the MicroK8s snap to the desired channel, and restarting the nodes if necessary:
|
||||
|
||||
<Terminal shell title="node — upgrade MicroK8s to a new minor release">{`
|
||||
# Check current version
|
||||
microk8s version
|
||||
# Upgrade to a new minor release
|
||||
sudo snap refresh microk8s --channel=1.31/stable
|
||||
`}</Terminal>
|
||||
|
||||
:::warning
|
||||
Always review the MicroK8s documentation for the most up-to-date instructions before performing a minor upgrade.
|
||||
:::
|
||||
|
||||
### Managing your cluster with external tools
|
||||
|
||||
To manage the cluster with external tools (`kubectl`, Lens, etc.), retrieve its `kubeconfig` from a control plane node:
|
||||
|
||||
<Terminal title="control plane node — print the kubeconfig">{`
|
||||
microk8s config
|
||||
apiVersion: v1
|
||||
clusters:
|
||||
- cluster:
|
||||
certificate-authority-data: [...]
|
||||
server: https://10.1.134.51:16443
|
||||
name: microk8s-cluster
|
||||
contexts:
|
||||
- context:
|
||||
cluster: microk8s-cluster
|
||||
user: admin
|
||||
name: microk8s
|
||||
current-context: microk8s
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users:
|
||||
- name: admin
|
||||
user:
|
||||
client-certificate-data: LS0tLS1CRU[...]
|
||||
client-key-data: LS0tLS1CRUdJ[...]
|
||||
`}</Terminal>
|
||||
|
||||
### Add-ons
|
||||
|
||||
In addition to the core components of the Kubernetes control plane, this recipe automatically installs the following add-ons:
|
||||
|
||||
- **DNS:** deploys CoreDNS for internal address resolution.
|
||||
- **Helm:** installs [Helm 3](https://helm.sh/), the Kubernetes package manager.
|
||||
- **RBAC:** enables [Role-based access control (RBAC)](https://kubernetes.io/docs/reference/access-authn-authz/rbac/) for authorization.
|
||||
|
||||
When **high availability (HA)** is enabled, the recipe also includes:
|
||||
|
||||
- **HA-cluster:** ensures high availability for clusters with three or more control plane nodes.
|
||||
- **[Kube-VIP](https://kube-vip.io/):** provides a virtual IP and load balancer for the control plane, deployed via the official Helm chart.
|
||||
|
||||
## Best Practices
|
||||
|
||||
When deploying Kubernetes clusters with recipes, it's important to plan for performance and reliability:
|
||||
|
||||
- Always allocate enough CPU and memory resources for both control plane and worker nodes. Using three control plane nodes ensures high availability in production environments.
|
||||
- Place the VMs on shared storage to allow live migration if needed.
|
||||
- For security, restrict SSH and API server access, and consider adding network policies once the cluster is running.
|
||||
|
||||
## Related links
|
||||
|
||||
- [Xen Orchestra Cloud Controller Manager](https://github.com/vatesfr/xenorchestra-cloud-controller-manager)
|
||||
- [Kubernetes official documentation](https://kubernetes.io/docs/home/)
|
||||
- [MicroK8s official documentation](https://microk8s.io/docs)
|
||||
- [CoreDNS official documentation](https://coredns.io/manual/toc/)
|
||||
@@ -0,0 +1,287 @@
|
||||
# Model Context Protocol (MCP)
|
||||
|
||||
## What is MCP?
|
||||
|
||||
[MCP](https://modelcontextprotocol.io/) (Model Context Protocol) is an open standard that lets AI assistants interact with external tools and data sources. Think of it as a universal adapter between AI assistants (like Claude) and your infrastructure.
|
||||
|
||||
With the [`@xen-orchestra/mcp`](https://github.com/vatesfr/xen-orchestra/tree/master/@xen-orchestra/mcp) package, your AI assistant can directly query your Xen Orchestra instance and answer questions about your virtualization infrastructure in natural language.
|
||||
|
||||
## Why MCP with Xen Orchestra?
|
||||
|
||||
MCP enables new ways to interact with your infrastructure:
|
||||
|
||||
- **Natural language queries**: ask "How many VMs are running?" instead of navigating dashboards
|
||||
- **AI-assisted monitoring**: get instant summaries of your infrastructure state
|
||||
- **Quick diagnostics**: ask about specific VMs, hosts, or pools without leaving your conversation
|
||||
- **Documentation at your fingertips**: search the XO documentation directly from the assistant
|
||||
|
||||
All operations are **read-only by default**, ensuring safe interaction with your production environment. Write operations can be enabled explicitly, see [Write operations](#write-operations).
|
||||
|
||||
## Installation
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- **Node.js** 20 or later
|
||||
- A **Xen Orchestra** instance, version **6.5 or later**, with [REST API](restapi.md) enabled
|
||||
- An **AI assistant** that supports MCP (Claude Desktop, Claude Code, etc.)
|
||||
|
||||
:::warning
|
||||
The MCP server requires **Xen Orchestra 6.5 or later**. On an older XO it stops at startup with an error such as `Unable to verify MCP status (HTTP 404)`. Upgrade your Xen Orchestra to use it.
|
||||
:::
|
||||
|
||||
### Install the MCP server
|
||||
|
||||
<Terminal shell title="install the MCP server globally">{`
|
||||
npm install -g @xen-orchestra/mcp
|
||||
`}</Terminal>
|
||||
|
||||
Or run it directly without installing:
|
||||
|
||||
<Terminal shell title="run without installing">{`
|
||||
npx @xen-orchestra/mcp
|
||||
`}</Terminal>
|
||||
|
||||
### Configure authentication
|
||||
|
||||
The MCP server connects to Xen Orchestra via the REST API. Two authentication modes are supported: **token** (recommended) or **username/password**.
|
||||
|
||||
| Variable | Required | Description |
|
||||
| ----------------------- | ----------------------- | --------------------------------------------------------------------------------------------- |
|
||||
| `XO_URL` | Yes | Xen Orchestra server URL (e.g. `https://xo.example.com`) |
|
||||
| `XO_TOKEN` | If no username/password | Authentication token |
|
||||
| `XO_USERNAME` | If no token | XO user with admin privileges |
|
||||
| `XO_PASSWORD` | If no token | XO password |
|
||||
| `XO_MCP_ENABLE_ACTIONS` | No | Set to `1` to expose write/destructive operations (see [Write operations](#write-operations)) |
|
||||
|
||||
To generate a token, go to the XO user page (`/user`) or run `xo-cli create-token`. If both `XO_TOKEN` and `XO_USERNAME`/`XO_PASSWORD` are set, token authentication takes priority.
|
||||
|
||||
:::tip
|
||||
Only admin users can currently use the REST API. See [REST API authentication](restapi.md#authentication) for details.
|
||||
:::
|
||||
|
||||
### Configure your AI assistant
|
||||
|
||||
#### Claude Desktop
|
||||
|
||||
Add the following to your Claude Desktop configuration file (`~/.config/claude-desktop/config.json` on Linux, `~/Library/Application Support/Claude/claude_desktop_config.json` on macOS):
|
||||
|
||||
Using a token (recommended):
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"xo": {
|
||||
"command": "npx",
|
||||
"args": ["@xen-orchestra/mcp"],
|
||||
"env": {
|
||||
"XO_URL": "https://your-xo-server",
|
||||
"XO_TOKEN": "your-token"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Using username/password:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"xo": {
|
||||
"command": "npx",
|
||||
"args": ["@xen-orchestra/mcp"],
|
||||
"env": {
|
||||
"XO_URL": "https://your-xo-server",
|
||||
"XO_USERNAME": "[email protected]",
|
||||
"XO_PASSWORD": "your-password"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Claude Code
|
||||
|
||||
<Terminal shell title="register the XO MCP server with Claude Code">{`
|
||||
# Using a token (recommended)
|
||||
claude mcp add xo \\
|
||||
-e XO_URL=https://your-xo-server \\
|
||||
-e XO_TOKEN=your-token \\
|
||||
-- npx @xen-orchestra/mcp
|
||||
`}</Terminal>
|
||||
|
||||
To use username/password instead, replace the `-e XO_TOKEN=…` line with `-e XO_USERNAME=…` and `-e XO_PASSWORD=…`.
|
||||
|
||||
#### Other MCP-compatible clients
|
||||
|
||||
Run the MCP server with the environment variables set:
|
||||
|
||||
<Terminal shell title="start the MCP server manually">{`
|
||||
XO_URL=https://your-xo-server \\
|
||||
XO_TOKEN=your-token \\
|
||||
npx @xen-orchestra/mcp
|
||||
`}</Terminal>
|
||||
|
||||
The server communicates via stdio using the MCP protocol (JSON-RPC), compatible with any MCP client.
|
||||
|
||||
#### Multiple XO instances
|
||||
|
||||
To manage several XO servers from the same assistant, add one entry per instance with a different name:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"xo-production": {
|
||||
"command": "npx",
|
||||
"args": ["@xen-orchestra/mcp"],
|
||||
"env": {
|
||||
"XO_URL": "https://xo-production.example.com",
|
||||
"XO_TOKEN": "prod-token"
|
||||
}
|
||||
},
|
||||
"xo-staging": {
|
||||
"command": "npx",
|
||||
"args": ["@xen-orchestra/mcp"],
|
||||
"env": {
|
||||
"XO_URL": "https://xo-staging.example.com",
|
||||
"XO_TOKEN": "staging-token"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Each entry starts its own process with its own credentials. The assistant gets a separate set of tools per instance, so you can ask about a specific environment by name ("list running VMs on xo-production").
|
||||
|
||||
:::tip
|
||||
Pick descriptive names (`xo-production`, `xo-dr-site`, ...) so the assistant knows which instance you're referring to.
|
||||
:::
|
||||
|
||||
### Behind a corporate proxy
|
||||
|
||||
The MCP server respects `HTTP_PROXY`, `HTTPS_PROXY`, and `NO_PROXY`. This matters in enterprise networks: your AI assistant may need an outbound proxy to reach the public internet, but your XOA is internal and must be reached directly. Without `NO_PROXY`, internal traffic gets sent through the proxy and rejected.
|
||||
|
||||
`NO_PROXY` takes a comma-separated list of hostnames that bypass the proxy: an exact host (`xoa.internal.example.com`), a suffix wildcard (`.example.com` or `*.example.com`, which matches subdomains but **not** the bare domain, so list both if needed), or `*` alone to bypass everything. CIDR ranges are not supported. Proxy credentials in the URL (`http://user:pass@proxy:3128`) work with Basic auth only; NTLM/Kerberos proxies need a sidecar like cntlm.
|
||||
|
||||
Example for Claude Desktop, with a corporate proxy and a XOA on the internal network:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"xo": {
|
||||
"command": "npx",
|
||||
"args": ["@xen-orchestra/mcp"],
|
||||
"env": {
|
||||
"XO_URL": "https://xoa.internal.example.com",
|
||||
"XO_TOKEN": "your-token",
|
||||
"HTTPS_PROXY": "http://proxy.corp.example:3128",
|
||||
"NO_PROXY": "xoa.internal.example.com"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
:::note
|
||||
`NO_PROXY` on its own does nothing. If you set it without `HTTP_PROXY` or `HTTPS_PROXY`, the MCP logs a warning at startup. A malformed proxy URL is reported on stderr but does not crash the server; it falls back to direct connections.
|
||||
:::
|
||||
|
||||
### Disabling MCP globally
|
||||
|
||||
Sometimes you need to shut MCP off across the board: during an incident, while reviewing an internal policy, or simply to keep AI access turned off until you've decided who should have it. The xo-server config has a flag for that:
|
||||
|
||||
```toml
|
||||
[mcp]
|
||||
enabled = false
|
||||
```
|
||||
|
||||
Restart xo-server and the change takes effect immediately:
|
||||
|
||||
- The `@xen-orchestra/mcp` binary refuses to start. It prints `MCP disabled by admin` on stderr and exits with code 1.
|
||||
- Any MCP client already running gets a `503` with `{ "error": "mcp_disabled" }` on its next request, so sessions shut down without leaving stale connections on the server.
|
||||
|
||||
The default is `enabled = true`; legacy configs without an `[mcp]` section behave the same way. Flip the value, restart, done: no other state to clean up.
|
||||
|
||||
:::note Detection caveat
|
||||
The kill-switch keys off the `X-XO-Client: mcp` header the official binary sends. A third-party MCP client, or an older `@xen-orchestra/mcp` version that predates this header, will bypass the gate. Pin to a recent release if you rely on the kill-switch as a hard control.
|
||||
:::
|
||||
|
||||
## How it works
|
||||
|
||||

|
||||
|
||||
1. On startup, the MCP server fetches the OpenAPI spec from your XO instance (`/rest/v0/docs/swagger.json`) and generates one tool per resource domain.
|
||||
2. You ask a question in natural language to your AI assistant.
|
||||
3. The assistant picks a tool (e.g. `pools_query`) and chooses an `operation` (e.g. `GetPools`, `GetPoolDashboard`).
|
||||
4. The MCP server calls the corresponding XO REST endpoint and returns a markdown-formatted response.
|
||||
|
||||
Because the tool surface is generated from the live OpenAPI spec, it always reflects the XO version you're connecting to: new endpoints become available automatically as XO evolves.
|
||||
|
||||
## Capabilities {#available-tools}
|
||||
|
||||
The server exposes:
|
||||
|
||||
- **Three utility tools**, always present: `check_connection` (validate your setup), `get_infrastructure_summary` (aggregate pools, hosts and VMs into a single overview), and `search_documentation` (look up the XO documentation by topic).
|
||||
- **One `{domain}_query` tool per REST resource domain**, generated from the live spec: pools, hosts, VMs, storage (SRs, VDIs), network, backup jobs and logs, users, tasks, alarms, and more. All query tools share the same arguments: `operation` (the OpenAPI `operationId` to invoke), `id`, an optional [`filter` expression](../xo5/manage_infrastructure.md#live-filter-search), `fields`, and `limit`.
|
||||
- **A built-in prompt**, `infrastructure-overview`, which turns the infrastructure summary into a readable report.
|
||||
|
||||
Stats endpoints and binary downloads (`.xva`, `.vhd`, ...) are deliberately not exposed: their payloads are unsuitable for LLM context. Use the REST API directly when you need them.
|
||||
|
||||
The exact tool list depends on your XO version, since it is generated at startup. For the complete, current reference (tool arguments, deny list, all environment variables), see the [`@xen-orchestra/mcp` README](https://github.com/vatesfr/xen-orchestra/tree/master/@xen-orchestra/mcp), which is the source of truth.
|
||||
|
||||
**Example questions:**
|
||||
|
||||
- "List all my pools"
|
||||
- "Show the dashboard for pool X"
|
||||
- "How many VMs are currently running?"
|
||||
- "List user VDIs larger than 100GB"
|
||||
|
||||
### Write operations
|
||||
|
||||
By default, the MCP server only exposes read-only tools. Set `XO_MCP_ENABLE_ACTIONS=1` in the server environment to also expose `{domain}_action` tools covering POST/PUT/PATCH/DELETE operations (start, stop or delete a VM, and so on).
|
||||
|
||||
Every action runs as a two-step handshake: the first call returns a preview of the request and a one-shot `confirm_token`; the assistant must call back with that token within 5 minutes to execute. A blunt "yes, delete everything" can't go through in one shot, so an accidental or hallucinated call stops at the preview. Use `XO_MCP_DENY_LIST` (a comma-separated list of `operationId`s, e.g. `DeleteVm,HardShutdownVm`) to drop specific operations from the surface entirely.
|
||||
|
||||
:::warning Only enable actions if you trust the caller
|
||||
Enabling `XO_MCP_ENABLE_ACTIONS` lets the assistant mutate your infrastructure. The confirm-token handshake means no action runs without a second, explicit call, but it's still write access. Keep the default read-only mode unless you have a specific need.
|
||||
:::
|
||||
|
||||
## Example Conversations
|
||||
|
||||
**Infrastructure overview:**
|
||||
|
||||
<UiDetail src="/img/xo5/mcp-infra.gif" alt="Asking Claude for an overview of the XO infrastructure via MCP" width={720} />
|
||||
|
||||
**Searching documentation:**
|
||||
|
||||
<UiDetail src="/img/xo5/mcp-doc.gif" alt="Searching the XO documentation from the assistant via MCP" width={720} />
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
:::note Connection refused
|
||||
Verify that `XO_URL` is correct and includes the protocol (`https://` or `http://`). Make sure the XO server is reachable from the machine running the MCP server.
|
||||
:::
|
||||
|
||||
:::note Authentication failed (401)
|
||||
If using token authentication, check that `XO_TOKEN` is valid: the token may have expired or been revoked. If using username/password, check `XO_USERNAME` and `XO_PASSWORD`. Only admin users can currently access the REST API.
|
||||
:::
|
||||
|
||||
:::note Timeout errors
|
||||
The MCP server has a 30-second timeout for API requests. If you experience timeouts, check network connectivity between the MCP server and your XO instance.
|
||||
:::
|
||||
|
||||
:::note Internal XOA blocked when behind a corporate proxy
|
||||
If your AI assistant injects `HTTPS_PROXY` into the MCP process and your XOA lives on the internal network, the proxy may silently drop or reject the requests. Add the XOA hostname to `NO_PROXY` so the traffic stays direct. See [Behind a corporate proxy](#behind-a-corporate-proxy).
|
||||
:::
|
||||
|
||||
:::note Missing required environment variables
|
||||
`XO_URL` is always required. You must also set either `XO_TOKEN` or both `XO_USERNAME` and `XO_PASSWORD`. When using Claude Desktop, make sure they are in the `env` section of the MCP server configuration.
|
||||
:::
|
||||
|
||||
:::note MCP disabled by admin
|
||||
The xo-server administrator has set `[mcp] enabled = false` in the server config. The binary won't start until that flag is removed or set back to `true`. See [Disabling MCP globally](#disabling-mcp-globally) for the server-side details.
|
||||
:::
|
||||
|
||||
:::note Unable to verify MCP status (HTTP 404)
|
||||
Your Xen Orchestra is older than **6.5**. Upgrade XO to 6.5 or later to use the MCP server, see [Prerequisites](#prerequisites).
|
||||
:::
|
||||
@@ -0,0 +1,79 @@
|
||||
# Packer plugin
|
||||
|
||||
## Introduction
|
||||
|
||||
[Packer](https://developer.hashicorp.com/packer) automates the creation of machine images: describe an image once in code, and rebuild it identically whenever needed. In an XCP-ng/Xen Orchestra environment, that means building **golden VM templates** (base OS, updates, guest tools, your provisioning) instead of preparing them by hand.
|
||||
|
||||
Vates maintains the [XenServer Packer plugin](https://github.com/vatesfr/packer-plugin-xenserver), a builder that installs an OS from an ISO on an XCP-ng host and turns the result into a reusable image. It was revived from an abandoned upstream project and is developed alongside the [Terraform provider](./terraform-provider.md) to ensure interoperability: templates built with Packer can then be cloned into VMs through the Terraform provider, the [REST API](restapi.md), or the Xen Orchestra web interface.
|
||||
|
||||
:::note
|
||||
The plugin talks **directly to an XCP-ng host** (via XAPI and SSH), not to the Xen Orchestra API. You point it at a host with its credentials; Xen Orchestra then sees and manages the resulting templates like any other.
|
||||
:::
|
||||
|
||||
## Installation
|
||||
|
||||
Declare the plugin in your template and let `packer init` download it:
|
||||
|
||||
```hcl
|
||||
packer {
|
||||
required_plugins {
|
||||
xenserver = {
|
||||
version = ">= v0.9.0"
|
||||
source = "github.com/vatesfr/xenserver"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<Terminal shell title="download the declared plugins">{`
|
||||
packer init .
|
||||
`}</Terminal>
|
||||
|
||||
:::tip
|
||||
Version `0.9.0` and later are validated against **XCP-ng 8.3**. Check the [releases page](https://github.com/vatesfr/packer-plugin-xenserver/releases) for the current version.
|
||||
:::
|
||||
|
||||
## Minimal example
|
||||
|
||||
The plugin provides the `xenserver-iso` builder: it creates a VM on the target host, boots it from an ISO, runs the OS installation, then captures the result. A skeleton looks like this:
|
||||
|
||||
```hcl
|
||||
source "xenserver-iso" "example" {
|
||||
# The XCP-ng host to build on
|
||||
remote_host = "your-xcpng-host"
|
||||
remote_username = "root"
|
||||
remote_password = "your-password"
|
||||
|
||||
# Installation media and VM shape
|
||||
iso_url = "https://example.com/path/to/installer.iso"
|
||||
iso_checksum = "sha256:..."
|
||||
sr_name = "Local storage"
|
||||
vm_name = "packer-golden-image"
|
||||
vm_memory = 4096
|
||||
disk_size = 20480
|
||||
|
||||
# How Packer connects to the VM to provision it
|
||||
ssh_username = "packer"
|
||||
ssh_password = "your-vm-password"
|
||||
}
|
||||
|
||||
build {
|
||||
sources = ["xenserver-iso.example"]
|
||||
}
|
||||
```
|
||||
|
||||
<Terminal shell title="build the image">{`
|
||||
packer build .
|
||||
`}</Terminal>
|
||||
|
||||
A real template also needs the OS installer automated (kickstart, preseed, or cloud-init autoinstall, served to the VM during boot). Rather than duplicating that here, start from the maintained, complete [Ubuntu example](https://github.com/vatesfr/packer-plugin-xenserver/tree/master/examples) in the plugin repository.
|
||||
|
||||
## Going further
|
||||
|
||||
The [plugin repository](https://github.com/vatesfr/packer-plugin-xenserver) is the source of truth for the builder's options (ISO handling, storage and network selection, output formats, HTTP-served install files, and so on), its examples, and its releases. See also the [Packer documentation](https://developer.hashicorp.com/packer/docs) for general concepts like provisioners and variables.
|
||||
|
||||
## Related links
|
||||
|
||||
- [packer-plugin-xenserver on GitHub](https://github.com/vatesfr/packer-plugin-xenserver) (source of truth for options and examples)
|
||||
- [Packer official documentation](https://developer.hashicorp.com/packer/docs)
|
||||
- [Terraform provider](./terraform-provider.md), to deploy VMs from the templates you build
|
||||
@@ -0,0 +1,133 @@
|
||||
# PowerShell module
|
||||
|
||||
## Introduction
|
||||
|
||||
Xen Orchestra (XO) is a powerful tool for managing XCP-ng and XenServer virtualization environments. However, relying solely on the web interface can result in repetitive manual tasks. For system administrators, particularly those working in Windows-centric environments, **PowerShell** is the go-to automation tool. The [`xo-powershell`](https://github.com/vatesfr/xo-powershell) module combines the strengths of these two tools by offering PowerShell's scripting capabilities to interact directly with the Xen Orchestra API.
|
||||
|
||||
## What the module provides
|
||||
|
||||
The module covers the whole infrastructure, not just VMs:
|
||||
|
||||
| Area | Cmdlets (examples) |
|
||||
| :------------- | :----------------------------------------------------------------------- |
|
||||
| Session | `Connect-XoSession`, `Test-XoSession`, `Disconnect-XoSession` |
|
||||
| VM lifecycle | `Get-XoVm`, `Start-XoVm`, `Stop-XoVm`, `Restart-XoVm`, `Suspend-XoVm` |
|
||||
| Snapshots | `New-XoVmSnapshot`, `Get-XoVmSnapshot` |
|
||||
| Storage | `Get-XoSr`, `Get-XoVdi`, `Get-XoVmVdi`, `Get-XoVdiSnapshot` |
|
||||
| Disk export | `Export-XoVdi`, `Export-XoVdiSnapshot` (to VHD or raw) |
|
||||
| Infrastructure | `Get-XoServer`, `Get-XoHost` |
|
||||
| Tasks | `Get-XoTask`, `Wait-XoTask` |
|
||||
|
||||
For the full, current cmdlet reference, see the [xo-powershell GitHub repository](https://github.com/vatesfr/xo-powershell): it is the source of truth for the module's capabilities and options.
|
||||
|
||||
## Installation and connection {#single-line-installation-and-connection}
|
||||
|
||||
The `xo-powershell` module is installed from the [PowerShell Gallery](https://www.powershellgallery.com/packages/xo-powershell/) in a single command:
|
||||
|
||||
<Terminal shell title="install from the PowerShell Gallery">{`
|
||||
Install-Module -Name xo-powershell -AllowPrerelease
|
||||
`}</Terminal>
|
||||
|
||||
:::note Prerequisites
|
||||
PowerShell **7.0 or later**, on Windows, Linux or macOS. Windows PowerShell 5.1 is not supported. The module is currently published as a prerelease (`1.0.0-beta`), hence the `-AllowPrerelease` flag (or `Install-PSResource -Name xo-powershell -Prerelease` with PSResourceGet).
|
||||
:::
|
||||
|
||||
Connecting to your Xen Orchestra instance is just as straightforward, requiring only the host address and an API token:
|
||||
|
||||
<Terminal shell title="connect to your XO instance">{`
|
||||
Connect-XoSession -HostName "https://your-xo-server" -Token "your-api-token"
|
||||
`}</Terminal>
|
||||
|
||||
:::tip Obtaining the API token
|
||||
In Xen Orchestra, go to your user page and generate an authentication token. See [REST API authentication](restapi.md#authentication) for details.
|
||||
:::
|
||||
|
||||
## Pipeline-driven automation {#the-power-of-the-pipeline-for-advanced-automation}
|
||||
|
||||
What distinguishes this module from a simple API wrapper is its deep integration with the PowerShell pipeline. Most commands are designed to pass objects to one another, allowing the creation of single-line commands that are both powerful and expressive.
|
||||
|
||||
### Simple usage examples {#example-simple-usage-examples}
|
||||
|
||||
<Terminal shell title="query your infrastructure">{`
|
||||
# List XCP-ng servers
|
||||
Get-XoServer
|
||||
# Monitor ongoing tasks
|
||||
Get-XoTask
|
||||
# Get information about virtual disks
|
||||
Get-XoVdi
|
||||
`}</Terminal>
|
||||
|
||||
<UiDetail src="/img/xo6/powershell-servers.png" alt="Get-XoServer returns your connected XCP-ng servers as PowerShell objects" width={720} />
|
||||
|
||||
To stop all virtual machines whose name contains `Test`, one line suffices:
|
||||
|
||||
<Terminal shell title="filter and act through the pipeline">{`
|
||||
Get-XoVm | Where-Object { $_.Name -like "*Test*" } | Stop-XoVm
|
||||
`}</Terminal>
|
||||
|
||||
This command first retrieves the list of all VMs, filters it to keep only those whose name matches the criteria, and then passes only these VMs to `Stop-XoVm`. This is possible because `Get-XoVm` does not return text but a collection of PowerShell objects: each VM object has properties (`.Name`, `.Memory`, etc.) that can be inspected by `Where-Object` before the complete object is passed to the next command.
|
||||
|
||||
The same principle applies to more complex filtering, such as suspending running VMs with more than 4 GB of memory:
|
||||
|
||||
<Terminal shell title="suspend running VMs with more than 4 GB of RAM">{`
|
||||
Get-XoVm -PowerState Running | Where-Object { $_.Memory.size -gt 4294967296 } | Suspend-XoVm
|
||||
`}</Terminal>
|
||||
|
||||
:::tip
|
||||
This capability transforms script writing, moving from a series of disconnected commands to a fluid flow of data and actions.
|
||||
:::
|
||||
|
||||
## Beyond VM management {#extended-environment-control-vm-management}
|
||||
|
||||
Some practical combinations:
|
||||
|
||||
| Scenario | Command sequence | Benefit |
|
||||
| :----------------------- | :------------------------------------------------------ | :----------------------------------- |
|
||||
| **Storage audit** | `Get-XoSr` → `Get-XoVdi` → `Get-XoVmVdi` | Comprehensive storage utilization view |
|
||||
| **Maintenance planning** | `Get-XoHost` → `Get-XoVm` → `Stop-XoVm` → `Wait-XoTask` | Planned maintenance without data loss |
|
||||
| **Session verification** | `Test-XoSession` | Verify automation readiness |
|
||||
|
||||
`Wait-XoTask` deserves a mention: it enables robust scripts that wait for lengthy operations (such as creating a **snapshot**) to complete before continuing execution. This makes the module a true command-line interface for Xen Orchestra and not just a tool for a few common tasks.
|
||||
|
||||
### Example: Creating virtual machine snapshots
|
||||
|
||||
This demonstration shows how to create and verify a virtual machine snapshot.
|
||||
|
||||
**Step 1: identify a base VM.**
|
||||
|
||||
<Terminal shell title="list VMs with their UUID and power state">{`
|
||||
Get-XoVm | Format-Table Name, Uuid, PowerState
|
||||
`}</Terminal>
|
||||
|
||||
<UiDetail src="/img/xo6/powershell-install-vms.png" alt="Installing the module, then listing VMs with Get-XoVm | Format-Table" width={720} />
|
||||
|
||||
**Step 2: create a snapshot.**
|
||||
|
||||
<Terminal shell title="snapshot a VM by UUID">{`
|
||||
New-XoVmSnapshot -VmUuid "993d84c2-2571-8451-8073-afa8ef510a8d" -SnapshotName "your-snapshot-name"
|
||||
`}</Terminal>
|
||||
|
||||
<UiDetail src="/img/xo6/powershell-snapshot-new.png" alt="New-XoVmSnapshot returns the created snapshot object" width={720} />
|
||||
|
||||
**Step 3: verify the snapshot creation.**
|
||||
|
||||
<Terminal shell title="find the snapshot by name">{`
|
||||
Get-XoVmSnapshot -Filter "name_label:your-snapshot-name"
|
||||
`}</Terminal>
|
||||
|
||||
<UiDetail src="/img/xo6/powershell-snapshot-verify.png" alt="Get-XoVmSnapshot confirms the snapshot exists" width={720} />
|
||||
|
||||
The snapshot also shows up in the Xen Orchestra web interface:
|
||||
|
||||
<UiShot light="/img/xo6/powershell-snapshot-xo.png" alt="The snapshot created from PowerShell, visible in the VM's Snapshots tab" url="https://your-xo/v5/#/vms/…/snapshots" />
|
||||
|
||||
## Conclusion: Rethink your XCP-ng management {#conclusion-rethink-your-xcp-ng-management}
|
||||
|
||||
The `xo-powershell` module is much more than just a collection of commands: it is a gateway to powerful, scalable and efficient automation within the XCP-ng/Xen Orchestra ecosystem. Leveraging the PowerShell pipeline and a comprehensive set of commands aligns it with the DevOps philosophy, bringing automation practices closer to Windows administrators and helping them save valuable time while reducing the risk of human error.
|
||||
|
||||
## Related links
|
||||
|
||||
- [xo-powershell on GitHub](https://github.com/vatesfr/xo-powershell) (source of truth for cmdlets and options)
|
||||
- [xo-powershell on the PowerShell Gallery](https://www.powershellgallery.com/packages/xo-powershell/)
|
||||
- [Infrastructure as Code category on the XCP-ng forum](https://xcp-ng.org/forum/category/29/infrastructure-as-code)
|
||||
- [REST API authentication](restapi.md#authentication)
|
||||
@@ -0,0 +1,260 @@
|
||||
# Pulumi provider
|
||||
|
||||
## Introduction
|
||||
|
||||
Manually managing infrastructure can lead to errors and increased complexity. With Infrastructure as Code (IaC), you describe your infrastructure in code, making it **predictable**, **reproducible**, and **version-controlled**.
|
||||
|
||||
Xen Orchestra has an official Pulumi provider, developed [on GitHub](https://github.com/vatesfr/pulumi-xenorchestra), with SDKs for **TypeScript/JavaScript**, **Python**, **Go**, and **.NET**. This guide walks you through deploying a virtual machine (VM) on your Xen Orchestra (XO) instance with **Pulumi**, then updating it.
|
||||
|
||||
:::note
|
||||
Pulumi supports several programming languages, but this guide uses TypeScript. For that language, you need Node.js 20 or newer.
|
||||
:::
|
||||
|
||||
:::tip
|
||||
Pulumi's approach lets you use real programming languages to define your infrastructure, offering more flexibility and power than traditional configuration languages.
|
||||
:::
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- a running **Xen Orchestra** instance connected to an **XCP-ng** pool (the provider drives the XO API)
|
||||
- the **Pulumi CLI** (3.x) and **Node.js** 20 or newer installed on your workstation
|
||||
- a VM **template** with cloud-init support
|
||||
- an XO **user account** or **API token** for the provider to authenticate with
|
||||
|
||||
### Installing Pulumi {#installing-pulumi}
|
||||
|
||||
If you haven't installed Pulumi yet, follow the [official Pulumi tutorial](https://www.pulumi.com/docs/install/) to install it on your system.
|
||||
|
||||
### VM templates in Xen Orchestra {#using-vm-templates-in-xen-orchestra}
|
||||
|
||||
Pulumi needs a starting point to create a VM: a template that already contains an installed operating system with **cloud-init** capabilities (or **Cloudbase-init** for Windows), as well as **Xen/Guest Tools** for better integration with Xen Orchestra.
|
||||
|
||||
:::info
|
||||
We recommend the pre-built cloud-init-ready templates from the **XOA Hub** (Debian, Ubuntu, and others) for optimal results. For more information about templates:
|
||||
|
||||
- [Creating VM templates](https://docs.xen-orchestra.com/vm-templates#creating-templates)
|
||||
- [Cloud-init and Cloudbase-init](https://docs.xen-orchestra.com/vm-templates#cloud-init-and-cloudbase-init)
|
||||
:::
|
||||
|
||||
## Installing the provider
|
||||
|
||||
Create a new directory and initialize a TypeScript project, then add the Xen Orchestra package:
|
||||
|
||||
<Terminal shell title="create the Pulumi project and install the provider">{`
|
||||
mkdir xo-pulumi-project
|
||||
cd xo-pulumi-project
|
||||
pulumi new typescript
|
||||
npm install @vates/pulumi-xenorchestra
|
||||
`}</Terminal>
|
||||
|
||||
:::info
|
||||
The provider is also available for the other Pulumi languages: `pulumi-xenorchestra` on PyPI for Python, `github.com/vatesfr/pulumi-xenorchestra/sdk` for Go, and `Pulumi.Xenorchestra` on NuGet for .NET. See the [provider repository](https://github.com/vatesfr/pulumi-xenorchestra) for the details and the latest release.
|
||||
:::
|
||||
|
||||
## Authentication
|
||||
|
||||
The provider talks to the XO API over a websocket connection (`ws://`, or `wss://` behind TLS) and supports two methods: an **API token** (recommended) or a **username and password**.
|
||||
|
||||
:::tip
|
||||
Any XO user can create their own API token: see [REST API authentication](restapi.md#authentication) for how to create one.
|
||||
:::
|
||||
|
||||
:::warning
|
||||
Never store credentials directly in your code. The recommended method is to use environment variables.
|
||||
:::
|
||||
|
||||
Create a file `~/.xoa` in your home directory:
|
||||
|
||||
```bash
|
||||
# ~/.xoa
|
||||
export XOA_URL=wss://your-xo-hostname
|
||||
export XOA_TOKEN=YOUR_TOKEN
|
||||
# or, with a username and password:
|
||||
# export XOA_USERNAME=YOUR_USERNAME
|
||||
# export XOA_PASSWORD=YOUR_PASSWORD
|
||||
```
|
||||
|
||||
Then, before running Pulumi, load these variables into your terminal session:
|
||||
|
||||
<Terminal shell title="load the XO credentials into the current session">{`
|
||||
source ~/.xoa
|
||||
`}</Terminal>
|
||||
|
||||
:::tip
|
||||
Alternatively, store the settings in the Pulumi configuration of your stack, with the token encrypted as a secret:
|
||||
|
||||
<Terminal shell title="store the XO connection settings in the stack configuration">{`
|
||||
pulumi config set xenorchestra:url wss://your-xo-hostname
|
||||
pulumi config set xenorchestra:token YOUR_TOKEN --secret
|
||||
`}</Terminal>
|
||||
:::
|
||||
|
||||
## Deploying your first VM {#launching-virtual-machines-in-xo-with-pulumi}
|
||||
|
||||
### Describe your infrastructure {#provisioning-your-vm-with-pulumi}
|
||||
|
||||
Pulumi needs to know about the existing resources in XO (your pool, template, storage, network). To achieve this, we use the provider's data functions, so you never hardcode UUIDs. Edit the `index.ts` file and replace its contents with the following, using the exact names of your resources in Xen Orchestra:
|
||||
|
||||
```typescript
|
||||
import * as pulumi from "@pulumi/pulumi";
|
||||
import * as xenorchestra from "@vates/pulumi-xenorchestra";
|
||||
|
||||
// Retrieve the pool
|
||||
const pool = xenorchestra.getXoaPool({
|
||||
nameLabel: "Main pool",
|
||||
});
|
||||
|
||||
// Retrieve the template
|
||||
const template = xenorchestra.getXoaTemplate({
|
||||
nameLabel: "Ubuntu 24.04 Cloud-Init",
|
||||
});
|
||||
|
||||
// Retrieve the storage repository
|
||||
const storageRepository = pool.then(p =>
|
||||
xenorchestra.getXoaStorageRepository({
|
||||
nameLabel: "ZFS",
|
||||
poolId: p.id,
|
||||
})
|
||||
);
|
||||
|
||||
// Retrieve the network
|
||||
const network = pool.then(p =>
|
||||
xenorchestra.getXoaNetwork({
|
||||
nameLabel: "Pool-wide network",
|
||||
poolId: p.id,
|
||||
})
|
||||
);
|
||||
```
|
||||
|
||||
:::tip
|
||||
Using explicit `nameLabel` values is fine for this tutorial. In real-world environments, prefer **unique names** to avoid conflicts when multiple resources share similar labels.
|
||||
:::
|
||||
|
||||
Now add the VM definition at the end of `index.ts`:
|
||||
|
||||
```typescript
|
||||
// Create the VM
|
||||
const vm = new xenorchestra.Vm("xo-pulumi-tutorial", {
|
||||
memoryMax: 2 * 1024 * 1024 * 1024, // 2 GiB
|
||||
cpus: 1,
|
||||
nameLabel: "XO Pulumi Tutorial",
|
||||
template: template.then(t => t.id),
|
||||
networks: [
|
||||
{
|
||||
networkId: network.then(n => n.id),
|
||||
},
|
||||
],
|
||||
disks: [
|
||||
{
|
||||
srId: storageRepository.then(sr => sr.id),
|
||||
nameLabel: "VM root volume",
|
||||
size: 50 * 1024 * 1024 * 1024, // 50 GiB
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
// Export
|
||||
export const vmId = vm.id;
|
||||
export const vmName = vm.nameLabel;
|
||||
export const ipv4 = vm.ipv4Addresses;
|
||||
```
|
||||
|
||||
This code describes the VM to be created (its name, memory, and CPUs) and wires it to the template, network, and storage retrieved above.
|
||||
|
||||
:::tip
|
||||
If your template uses multiple disks, declare the same number of disks in your VM resource, in the same order. Each disk must be at least the same size as its counterpart in the template.
|
||||
:::
|
||||
|
||||
### Deploy the VM
|
||||
|
||||
It's time to bring the VM to life:
|
||||
|
||||
<Terminal shell title="preview and deploy the stack">{`
|
||||
pulumi up
|
||||
`}</Terminal>
|
||||
|
||||
Pulumi analyzes your code, shows a preview of the changes (`+ 2 to create`: the stack and the VM), and asks for confirmation. Select `yes`, and after a few seconds the VM is created on your pool, with the `vmId` and `vmName` outputs displayed at the end of the run.
|
||||
|
||||
<UiShot light="/img/xo5/pulumi-vm-general.png" alt="The freshly deployed VM, seen from its General tab in Xen Orchestra" url="https://your-xo/#/vms/…/general" />
|
||||
|
||||
Congratulations! Your VM is now deployed via Pulumi on XO, and any future modification can be **reviewed** and **version-controlled**.
|
||||
|
||||
## Updating an existing infrastructure {#updating-existing-infrastructure}
|
||||
|
||||
One of Pulumi's greatest strengths is its ability to manage changes throughout your infrastructure's lifecycle. To demonstrate it, let's add a second network interface to the VM we just created: simply add a second entry to the `networks` array in `index.ts`.
|
||||
|
||||
```typescript
|
||||
const vm = new xenorchestra.Vm("xo-pulumi-tutorial", {
|
||||
// ... same attributes as before ...
|
||||
networks: [
|
||||
{
|
||||
networkId: network.then(n => n.id),
|
||||
},
|
||||
// Second network interface
|
||||
{
|
||||
networkId: network.then(n => n.id),
|
||||
},
|
||||
],
|
||||
// ... same disks as before ...
|
||||
});
|
||||
```
|
||||
|
||||
The workflow is exactly the same as for the creation:
|
||||
|
||||
<Terminal shell title="preview and apply the change">{`
|
||||
pulumi up
|
||||
`}</Terminal>
|
||||
|
||||
This time, Pulumi detects that the resource already exists and needs to be modified, not created: the preview shows an `update` plan with `[diff: ~networks]`. After you confirm with `yes`, the new interface is attached to the existing VM.
|
||||
|
||||
<UiShot light="/img/xo5/pulumi-vm-network-single.png" alt="Before the change: the VM's Network tab shows a single interface" url="https://your-xo/#/vms/…/network" />
|
||||
|
||||
<UiShot light="/img/xo5/pulumi-vm-network-dual.png" alt="After pulumi up: a second VIF appeared on the VM" url="https://your-xo/#/vms/…/network" />
|
||||
|
||||
## Debugging and logs
|
||||
|
||||
Pulumi supports detailed logging for troubleshooting; the provider's own logs appear in the Pulumi output when debug mode is enabled:
|
||||
|
||||
<Terminal shell title="run Pulumi with debug output (increase -v for more detail)">{`
|
||||
pulumi up --debug
|
||||
pulumi up --logtostderr -v=9
|
||||
`}</Terminal>
|
||||
|
||||
:::note
|
||||
Only enable debug logging when troubleshooting, as it significantly increases log verbosity and may impact performance.
|
||||
:::
|
||||
|
||||
## Best practices
|
||||
|
||||
### State management
|
||||
|
||||
:::warning
|
||||
Pulumi state contains sensitive information about your infrastructure. Always use a secure backend, such as a self-hosted solution or local encrypted storage.
|
||||
:::
|
||||
|
||||
<Terminal shell title="choose a state backend">{`
|
||||
pulumi login --local # local storage in your home directory
|
||||
pulumi login s3://my-pulumi-state # or any self-hosted backend (s3, gs, azblob)
|
||||
`}</Terminal>
|
||||
|
||||
## Going further {#conclusion}
|
||||
|
||||
This guide only scratches the surface: the provider also manages cloud-init configuration, extra disks, tags, networks, and more. The [provider repository](https://github.com/vatesfr/pulumi-xenorchestra) is the reference for all resources, data functions, and releases, and its [examples directory](https://github.com/vatesfr/pulumi-xenorchestra/tree/main/examples) covers each supported language.
|
||||
|
||||
:::note
|
||||
**Commercial support**: contact our support team through your customer portal.
|
||||
|
||||
**Community support**:
|
||||
|
||||
- [XCP-ng Forum](https://xcp-ng.org/forum/)
|
||||
- [Discord Community](https://discord.com/invite/ZpNq8ez)
|
||||
- [GitHub Issues](https://github.com/vatesfr/pulumi-xenorchestra/issues)
|
||||
:::
|
||||
|
||||
## Related links
|
||||
|
||||
- [Provider source code and documentation on GitHub](https://github.com/vatesfr/pulumi-xenorchestra)
|
||||
- [Provider package on npm (@vates/pulumi-xenorchestra)](https://www.npmjs.com/package/@vates/pulumi-xenorchestra)
|
||||
- [Provider code examples](https://github.com/vatesfr/pulumi-xenorchestra/tree/main/examples)
|
||||
- [Official Pulumi documentation](https://www.pulumi.com/docs)
|
||||
- [Official XCP-ng documentation](https://docs.xcp-ng.org/)
|
||||
@@ -0,0 +1,210 @@
|
||||
# REST API
|
||||
|
||||
The Xen Orchestra REST API is the modern, public way to automate your infrastructure. We built it from scratch, next to [our historical JSON-RPC API](../architecture.md#apis), to be [REST-like](https://en.wikipedia.org/wiki/Representational_state_transfer) and usable with a plain `curl` command. It is now almost complete: nearly all of Xen Orchestra's capabilities are exposed through it, and it is ready to be used in production. It is also the API we are building the future of Xen Orchestra on, so it is the right choice for any new automation.
|
||||
|
||||
This page teaches the principles: how to authenticate, then how each HTTP verb behaves, with one example per pattern. For the complete, always up-to-date list of endpoints, use the [built-in Swagger UI](#openapiswagger) shipped with your Xen Orchestra: it documents every route and lets you try them from your browser.
|
||||
|
||||
## Versioning
|
||||
|
||||
The REST API is versioned, and the current version is `/v0` (all URLs start with `/rest/v0`). We avoid breaking changes within a version. If a major change is ever required, we will release a new version (e.g. `/v1`) while keeping `/v0` available to minimize the impact.
|
||||
|
||||
## Authentication
|
||||
|
||||
Endpoints require authentication. Two forms are accepted, and you must pick exactly one per request (sending both returns a `400` error):
|
||||
|
||||
- an authentication token, passed as the `authenticationToken` cookie
|
||||
- your username and password, passed as a [Basic Authorization header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Authorization)
|
||||
|
||||
An invalid token or invalid credentials get a `401 Unauthorized` response.
|
||||
|
||||
:::tip
|
||||
Admin users have access to all REST API endpoints. Non-admin users can use the REST API according to the [RBAC](../rbac.md) permissions defined on their account.
|
||||
:::
|
||||
|
||||
For scripts and integrations, prefer a token: it does not expose your password and it can be revoked at any time.
|
||||
|
||||
<Terminal shell title="the two authentication forms, with curl">{`
|
||||
curl -b authenticationToken=KQxQdm2vMiv7jBIK0hgkmgxKzemd8wSJ7ugFGKFkTbs https://xo.example.org/rest/v0/vms
|
||||
curl -u [email protected]:admin https://xo.example.org/rest/v0/vms
|
||||
`}</Terminal>
|
||||
|
||||
### Creating a token {#creation}
|
||||
|
||||
The simplest way is `xo-cli`:
|
||||
|
||||
<Terminal title="create a token with xo-cli">{`
|
||||
xo-cli create-token xo.example.org [email protected]
|
||||
Password: ********
|
||||
Successfully logged with [email protected]
|
||||
Authentication token created
|
||||
|
||||
DiYBFavJwf9GODZqQJs23eAx9eh3KlsRhBi8RcoX0KM
|
||||
`}</Terminal>
|
||||
|
||||
You can also do it through the API itself, with `POST /rest/v0/users/:id/authentication_tokens`:
|
||||
|
||||
<Terminal title="create a token for the current user">{`
|
||||
curl -X POST -u [email protected]:admin https://xo.example.org/rest/v0/users/me/authentication_tokens
|
||||
{
|
||||
"token": {
|
||||
"created_at": 1765187444219,
|
||||
"id": "UlTBEnFeL12XocK-7Qx-DKvOYbPn0eG7Z2oMvOniNjg",
|
||||
"user_id": "e531b8c9-3876-4ed9-8fd2-0476d5f825c9",
|
||||
"expiration": 1767779444219
|
||||
}
|
||||
}
|
||||
`}</Terminal>
|
||||
|
||||
:::tip
|
||||
If you don't know your user ID, use the `me` alias, as above. Tokens expire (see the `expiration` timestamp): before that happens, renew by calling the same endpoint with your existing token to create a fresh one.
|
||||
:::
|
||||
|
||||
## Reading a collection {#collections-request}
|
||||
|
||||
Every object type lives in a collection at `/rest/v0/<name>` (e.g. `/rest/v0/vms`, `/rest/v0/hosts`, `/rest/v0/srs`). A plain `GET` returns the objects' URLs, and the following query parameters shape the result:
|
||||
|
||||
- `fields`: return objects containing the requested fields, instead of plain URLs
|
||||
- `filter`: select only matching objects, using [the live filter search syntax](../xo5/manage_infrastructure.md#live-filter-search)
|
||||
- `limit`: maximum number of objects returned
|
||||
- `ndjson`: if `true`, the result is streamed in [NDJSON format](https://github.com/ndjson/ndjson-spec), one object per line
|
||||
|
||||
<Terminal title="running VMs, two fields, at most two results">{`
|
||||
curl -b authenticationToken=KQxQdm2vMiv7jBIK0hgkmgxKzemd8wSJ7ugFGKFkTbs 'https://xo.example.org/rest/v0/vms?fields=name_label,power_state&filter=power_state:running&limit=2'
|
||||
[
|
||||
{
|
||||
"name_label": "Debian 12 web frontend",
|
||||
"power_state": "Running",
|
||||
"href": "/rest/v0/vms/770aa52a-fd42-8faf-f167-8c5c4a237cac"
|
||||
},
|
||||
{
|
||||
"name_label": "FreeNAS",
|
||||
"power_state": "Running",
|
||||
"href": "/rest/v0/vms/0fc14abc-ae7a-4209-79c4-d20ca1f0e567"
|
||||
}
|
||||
]
|
||||
`}</Terminal>
|
||||
|
||||
The same request as NDJSON, convenient for large collections and line-by-line processing:
|
||||
|
||||
<Terminal title="the same collection, streamed as NDJSON">{`
|
||||
curl -b authenticationToken=KQxQdm2vMiv7jBIK0hgkmgxKzemd8wSJ7ugFGKFkTbs 'https://xo.example.org/rest/v0/vms?fields=name_label,power_state&ndjson=true'
|
||||
{"name_label":"Debian 12 web frontend","power_state":"Running","href":"/rest/v0/vms/770aa52a-fd42-8faf-f167-8c5c4a237cac"}
|
||||
{"name_label":"FreeNAS","power_state":"Running","href":"/rest/v0/vms/0fc14abc-ae7a-4209-79c4-d20ca1f0e567"}
|
||||
`}</Terminal>
|
||||
|
||||
## Reading a single object
|
||||
|
||||
`GET` the object's URL (the `href` returned by its collection) to get the full record:
|
||||
|
||||
<Terminal title="fetch one VM">{`
|
||||
curl -b authenticationToken=KQxQdm2vMiv7jBIK0hgkmgxKzemd8wSJ7ugFGKFkTbs https://xo.example.org/rest/v0/vms/770aa52a-fd42-8faf-f167-8c5c4a237cac
|
||||
{
|
||||
"type": "VM",
|
||||
"id": "770aa52a-fd42-8faf-f167-8c5c4a237cac",
|
||||
"name_label": "Debian 12 web frontend",
|
||||
"name_description": "Production web frontend",
|
||||
"power_state": "Running",
|
||||
"addresses": { "0/ipv4/0": "192.168.1.55" },
|
||||
"other": "many more fields, see the Swagger UI for the full schema"
|
||||
}
|
||||
`}</Terminal>
|
||||
|
||||
## Running an action {#actions}
|
||||
|
||||
Operations that *do* something (start, snapshot, migrate, rolling pool update...) are exposed as actions: `POST /rest/v0/<type>/<uuid>/actions/<action>`. Parameters, when an action takes some, are passed as a JSON body:
|
||||
|
||||
<Terminal title="snapshot a VM, with a parameter">{`
|
||||
curl -X POST -b authenticationToken=KQxQdm2vMiv7jBIK0hgkmgxKzemd8wSJ7ugFGKFkTbs -H 'Content-Type: application/json' -d '{"name_label": "Before upgrade"}' https://xo.example.org/rest/v0/vms/770aa52a-fd42-8faf-f167-8c5c4a237cac/actions/snapshot
|
||||
{"taskId":"0m7kl0j9l"}
|
||||
`}</Terminal>
|
||||
|
||||
### Actions are asynchronous: tasks {#task-monitoring}
|
||||
|
||||
By default an action returns immediately with a `202 Accepted` status: the work continues server-side as a **task**. The response contains the task ID, and a `Location` header points to the task's URL:
|
||||
|
||||
```http
|
||||
HTTP/1.1 202 Accepted
|
||||
Location: /rest/v0/tasks/0m7kl0j9l
|
||||
|
||||
{"taskId":"0m7kl0j9l"}
|
||||
```
|
||||
|
||||
Fetch the task to follow it. The `wait=true` query parameter makes the request block until the task reaches a final state, so a single call gives you the outcome:
|
||||
|
||||
<Terminal shell title="wait for the task to finish">{`
|
||||
curl -b authenticationToken=KQxQdm2vMiv7jBIK0hgkmgxKzemd8wSJ7ugFGKFkTbs 'https://xo.example.org/rest/v0/tasks/0m7kl0j9l?wait=true'
|
||||
`}</Terminal>
|
||||
|
||||
If you prefer a blocking call from the start, add `?sync=true` to the action itself: the request only returns once the action is done, with its result as JSON, and no task monitoring is needed:
|
||||
|
||||
<Terminal title="synchronous action: the result is returned directly">{`
|
||||
curl -X POST -b authenticationToken=KQxQdm2vMiv7jBIK0hgkmgxKzemd8wSJ7ugFGKFkTbs 'https://xo.example.org/rest/v0/vms/770aa52a-fd42-8faf-f167-8c5c4a237cac/actions/clean_reboot?sync=true'
|
||||
`}</Terminal>
|
||||
|
||||
## Updating an object {#properties-update}
|
||||
|
||||
Editable objects support `PATCH` on their URL: send only the fields you want to change (JSON body, camelCase field names) and everything else is left untouched. A successful update returns `204 No Content`. VMs, VDIs, VIFs, users, groups, backup repositories and more can be patched; the Swagger UI lists the accepted fields for each type.
|
||||
|
||||
<Terminal shell title="rename a VM and update its description">{`
|
||||
curl -X PATCH -b authenticationToken=KQxQdm2vMiv7jBIK0hgkmgxKzemd8wSJ7ugFGKFkTbs -H 'Content-Type: application/json' -d '{"nameLabel": "web-prod-01", "nameDescription": "Production web frontend"}' https://xo.example.org/rest/v0/vms/770aa52a-fd42-8faf-f167-8c5c4a237cac
|
||||
`}</Terminal>
|
||||
|
||||
## Deleting an object {#vm-and-vdi-destruction}
|
||||
|
||||
`DELETE` on the object's URL destroys it:
|
||||
|
||||
<Terminal shell title="delete a VM">{`
|
||||
curl -X DELETE -b authenticationToken=KQxQdm2vMiv7jBIK0hgkmgxKzemd8wSJ7ugFGKFkTbs https://xo.example.org/rest/v0/vms/770aa52a-fd42-8faf-f167-8c5c4a237cac
|
||||
`}</Terminal>
|
||||
|
||||
## Watching for changes {#events}
|
||||
|
||||
For live automation, the API exposes a [Server-Sent Events (SSE)](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events) endpoint at `/rest/v0/events`, which notifies you in real time when objects change (VMs, hosts, SRs...). The first event, `init`, gives you a connection ID, and a `ping` is sent every 30 seconds to keep the connection alive:
|
||||
|
||||
<Terminal title="open the event stream">{`
|
||||
curl -N -b authenticationToken=KQxQdm2vMiv7jBIK0hgkmgxKzemd8wSJ7ugFGKFkTbs https://xo.example.org/rest/v0/events
|
||||
event: init
|
||||
data: {"id":"0d8b28c6-e9bf-4c9d-a382-3c9e0d7cfbff"}
|
||||
`}</Terminal>
|
||||
|
||||
A new connection has no subscriptions. Use the connection ID to subscribe to a collection, optionally restricting the fields you receive (events that do not touch the watched fields are then suppressed):
|
||||
|
||||
<Terminal shell title="subscribe to VM events on this connection">{`
|
||||
curl -X POST -b authenticationToken=KQxQdm2vMiv7jBIK0hgkmgxKzemd8wSJ7ugFGKFkTbs -H 'Content-Type: application/json' -d '{"collection": "VM", "fields": ["id", "name_label", "power_state"]}' https://xo.example.org/rest/v0/events/0d8b28c6-e9bf-4c9d-a382-3c9e0d7cfbff/subscriptions
|
||||
`}</Terminal>
|
||||
|
||||
The stream then emits `add`, `update` and `remove` events for that collection, each carrying the object's fields plus a `$subscription` property naming the collection:
|
||||
|
||||
```
|
||||
event: update
|
||||
data: {"$subscription":"VM","id":"770aa52a-fd42-8faf-f167-8c5c4a237cac","name_label":"web-prod-01","power_state":"Running"}
|
||||
```
|
||||
|
||||
A `DELETE` on `/rest/v0/events/<connection id>/subscriptions/VM` unsubscribes.
|
||||
|
||||
:::note
|
||||
|
||||
- Collections also support a pull-based alternative: `GET` with both `ndjson=true` and `watch=true` streams `[event, object]` entries as changes happen.
|
||||
- The server buffers events for slow consumers, up to `maxRamAllocatedPerSseClient` (MiB, set in the `[rest-api]` section of `xo-server`'s configuration, 20 by default). A client exceeding it is disconnected and must reconnect.
|
||||
|
||||
:::
|
||||
|
||||
## The built-in Swagger UI {#openapiswagger}
|
||||
|
||||
The five patterns above are all you need to know: everything else is endpoint details, and those are documented where they can never go stale, in the [OpenAPI (Swagger)](https://swagger.io/specification/) documentation autogenerated from the API code itself. It ships with your Xen Orchestra at:
|
||||
|
||||
```
|
||||
https://your-xo/rest/v0/docs
|
||||
```
|
||||
|
||||
It is also one click away from the XO 5 web UI, via the **REST API doc** entry in the main menu (and `https://your-xo/rest/v0` redirects there too).
|
||||
|
||||
<UiShot light="/img/xo5/swagger-example.png" alt="The Swagger UI documenting the VM endpoints, with the full VM schema and a Try it out button" url="https://your-xo/rest/v0/docs" />
|
||||
|
||||
The Swagger UI doesn't just document every route, parameter and schema: the **Try it out** button lets you run requests directly from your browser, authenticated by your existing Xen Orchestra session, so you can experiment with the API without writing any code. You will find there everything not shown on this page, including the binary streaming endpoints (XVA export/import for VMs, VHD and raw export/import for VDIs) and the backup, pool, host, SR, network and user routes.
|
||||
|
||||
The raw OpenAPI specification is available at `https://your-xo/rest/v0/docs/swagger.json`, ready to feed a client generator for your favorite language.
|
||||
|
||||
## Missing an endpoint? {#ongoing-improvements}
|
||||
|
||||
Almost all endpoints you may need are already covered by the REST API, and we keep expanding it. If something you need is missing, please tell us: open a request on [our feedback portal](https://feedback.vates.tech/) or start a discussion on [the Xen Orchestra forum](https://xcp-ng.org/forum/category/12/xen-orchestra). Real use cases are what drive the API's roadmap.
|
||||
@@ -0,0 +1,256 @@
|
||||
# Terraform provider
|
||||
|
||||
## Introduction
|
||||
|
||||
Managing infrastructure by hand is error prone and hard to audit. With Infrastructure as Code (IaC), you describe your infrastructure in configuration files to make it **predictable**, **reproducible**, and **version-controlled**.
|
||||
|
||||
Xen Orchestra has an official Terraform provider, [`vatesfr/xenorchestra`](https://registry.terraform.io/providers/vatesfr/xenorchestra/latest), published on the Terraform registry and developed [on GitHub](https://github.com/vatesfr/terraform-provider-xenorchestra). This guide walks you through deploying a VM on your Xen Orchestra (XO) instance with **Terraform**, then updating it.
|
||||
|
||||
:::note
|
||||
This guide works with both **Terraform** and **OpenTofu**, the community-driven fork that maintains compatibility with Terraform.
|
||||
:::
|
||||
|
||||
:::tip
|
||||
Terraform's two-step workflow (`plan` then `apply`) gives you full control: you preview every change before applying it, for safe and predictable deployments.
|
||||
:::
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- a running **Xen Orchestra** instance (5.50.1 or newer) connected to an **XCP-ng** pool
|
||||
- **Terraform** or **OpenTofu** installed on your workstation
|
||||
- a VM **template** with cloud-init support
|
||||
- an XO **user account** or **API token** for the provider to authenticate with
|
||||
|
||||
### Installing Terraform {#installing-terraform}
|
||||
|
||||
If you haven't installed Terraform yet, follow the [official HashiCorp tutorial](https://developer.hashicorp.com/terraform/install), or the [OpenTofu installation guide](https://opentofu.org/docs/intro/install/). Any recent release works: the provider itself supports Terraform 0.12 and newer.
|
||||
|
||||
### VM templates in Xen Orchestra {#using-vm-templates-in-xen-orchestra}
|
||||
|
||||
Terraform needs a starting point to create a VM: a template that already contains an installed operating system with **cloud-init** capabilities (or **Cloudbase-init** for Windows), as well as **Xen/Guest Tools** for better integration with Xen Orchestra. This enables automatic customization during deployment: IP assignment, hostname configuration, and so on.
|
||||
|
||||
:::info
|
||||
We recommend the pre-built cloud-init-ready templates from the **XOA Hub** (Debian, Ubuntu, and others) for optimal results. For more information about templates:
|
||||
|
||||
- [Creating VM templates](https://docs.xen-orchestra.com/vm-templates#creating-templates)
|
||||
- [Cloud-init and Cloudbase-init](https://docs.xen-orchestra.com/vm-templates#cloud-init-and-cloudbase-init)
|
||||
- [Windows templates with Cloudbase-init](https://xen-orchestra.com/blog/windows-templates-with-cloudbase-init-step-by-step-guide-best-practices/)
|
||||
:::
|
||||
|
||||
## Installing the provider
|
||||
|
||||
Declare the provider in a file named `provider.tf`:
|
||||
|
||||
```tf
|
||||
# provider.tf
|
||||
terraform {
|
||||
required_providers {
|
||||
xenorchestra = {
|
||||
source = "vatesfr/xenorchestra"
|
||||
version = "~> 0.40"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
:::info
|
||||
Version `0.40.0` is the latest at the time of writing. Check the [registry page](https://registry.terraform.io/providers/vatesfr/xenorchestra/latest) for the current version and release notes.
|
||||
:::
|
||||
|
||||
Then initialize your working directory:
|
||||
|
||||
<Terminal shell title="download the provider and set up the working directory">{`
|
||||
terraform init
|
||||
`}</Terminal>
|
||||
|
||||
Terraform downloads the provider from the registry and ends with `Terraform has been successfully initialized!`. It also creates a `.terraform.lock.hcl` lock file: commit it to version control so every run uses the same provider version.
|
||||
|
||||
## Authentication
|
||||
|
||||
The provider talks to the XO API over a websocket connection (`ws://`, or `wss://` behind TLS) and supports two methods: an **API token** (recommended) or a **username and password**. When a token is provided, it takes precedence and the username and password are ignored.
|
||||
|
||||
:::tip
|
||||
Any XO user can create their own API token: see [REST API authentication](restapi.md#authentication) for how to create one.
|
||||
:::
|
||||
|
||||
:::warning
|
||||
Never store credentials directly in your code. The recommended method is to use environment variables.
|
||||
:::
|
||||
|
||||
Create a file `~/.xoa` in your home directory:
|
||||
|
||||
```bash
|
||||
# ~/.xoa
|
||||
export XOA_URL=wss://your-xo-hostname
|
||||
export XOA_TOKEN=YOUR_TOKEN
|
||||
# or, with a username and password:
|
||||
# export XOA_USER=YOUR_USERNAME
|
||||
# export XOA_PASSWORD=YOUR_PASSWORD
|
||||
```
|
||||
|
||||
Then, before running Terraform, load these variables into your terminal session:
|
||||
|
||||
<Terminal shell title="load the XO credentials into the current session">{`
|
||||
source ~/.xoa
|
||||
`}</Terminal>
|
||||
|
||||
:::tip
|
||||
The same settings can be passed in the provider block instead, which is useful when the values come from Terraform variables or a secrets manager:
|
||||
|
||||
```tf
|
||||
provider "xenorchestra" {
|
||||
url = "wss://your-xo-hostname" # must be ws:// or wss://, or set XOA_URL
|
||||
token = var.xoa_token # or set XOA_TOKEN
|
||||
# username/password authentication is also supported (username/password
|
||||
# arguments, or the XOA_USER and XOA_PASSWORD environment variables),
|
||||
# and insecure = true skips TLS verification (XOA_INSECURE)
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
## Deploying your first VM {#launching-virtual-machines-in-xo-with-terraform}
|
||||
|
||||
### Describe your infrastructure {#provisioning-your-vm-with-terraform}
|
||||
|
||||
Terraform needs to know about the existing resources in XO (your pool, network, storage, template). For that, we use `data` blocks: read-only queries that fetch existing information, so you never hardcode UUIDs.
|
||||
|
||||
Create a file named `vm.tf` and add the following code, replacing the `name_label` values with the exact names of your pool, template, storage repository, and network in Xen Orchestra:
|
||||
|
||||
```tf
|
||||
# vm.tf
|
||||
|
||||
data "xenorchestra_pool" "pool" {
|
||||
name_label = "Main pool"
|
||||
}
|
||||
|
||||
data "xenorchestra_template" "vm_template" {
|
||||
name_label = "Ubuntu 24.04 Cloud-Init"
|
||||
}
|
||||
|
||||
data "xenorchestra_sr" "sr" {
|
||||
name_label = "ZFS"
|
||||
pool_id = data.xenorchestra_pool.pool.id
|
||||
}
|
||||
|
||||
data "xenorchestra_network" "network" {
|
||||
name_label = "Pool-wide network"
|
||||
pool_id = data.xenorchestra_pool.pool.id
|
||||
}
|
||||
```
|
||||
|
||||
:::tip
|
||||
At this stage you can already run `terraform plan`: it should end with `No changes. Your infrastructure matches the configuration.`, which confirms that Terraform can reach XO and found every declared resource. In real environments, prefer **unique names** for your resources to prevent conflicts when several share similar labels.
|
||||
:::
|
||||
|
||||
Now add the VM definition at the end of `vm.tf` (or in a separate `resources.tf`):
|
||||
|
||||
```tf
|
||||
resource "xenorchestra_vm" "vm" {
|
||||
memory_max = 2147467264
|
||||
cpus = 1
|
||||
name_label = "XO terraform tutorial"
|
||||
template = data.xenorchestra_template.vm_template.id
|
||||
|
||||
network {
|
||||
network_id = data.xenorchestra_network.network.id
|
||||
}
|
||||
|
||||
disk {
|
||||
sr_id = data.xenorchestra_sr.sr.id
|
||||
name_label = "VM root volume"
|
||||
size = 50214207488
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This `resource` block describes the VM to be created (its name, memory, and CPUs) and wires it to the template, network, and storage found by the data sources.
|
||||
|
||||
:::tip
|
||||
If your template uses multiple disks, declare the same number of disks in your VM resource, in the same order. Each disk must be at least the same size as its counterpart in the template.
|
||||
:::
|
||||
|
||||
### Plan and apply
|
||||
|
||||
It's time to bring the VM to life:
|
||||
|
||||
<Terminal shell title="preview the changes, then apply them">{`
|
||||
terraform plan
|
||||
terraform apply
|
||||
`}</Terminal>
|
||||
|
||||
`terraform plan` analyzes your code and shows what it is about to do: the run should end with `Plan: 1 to add, 0 to change, 0 to destroy.`, with the full detail of the `xenorchestra_vm.vm` resource to be created. If the plan looks good, `terraform apply` shows it again and asks for confirmation: type `yes` and press `Enter`, and the VM is created on your pool.
|
||||
|
||||
<UiShot light="/img/xo5/terraform-vm-console.png" alt="The freshly deployed VM booting, seen from its Console tab in Xen Orchestra" url="https://your-xo/#/vms/…/console" />
|
||||
|
||||
Congratulations! Your VM is now deployed via Terraform on XO, and any future modification can be **reviewed** and **version-controlled**.
|
||||
|
||||
## Updating an existing infrastructure
|
||||
|
||||
One of Terraform's greatest advantages is its ability to manage changes throughout the entire lifecycle of your infrastructure. To demonstrate it, let's add a second network interface to the VM we just created: simply add a second `network` block to the VM definition in `vm.tf`.
|
||||
|
||||
```tf
|
||||
resource "xenorchestra_vm" "vm" {
|
||||
# ... same attributes as before ...
|
||||
|
||||
# First network interface
|
||||
network {
|
||||
network_id = data.xenorchestra_network.network.id
|
||||
}
|
||||
|
||||
# Second network interface
|
||||
network {
|
||||
network_id = data.xenorchestra_network.network.id
|
||||
}
|
||||
|
||||
# ... same disk block as before ...
|
||||
}
|
||||
```
|
||||
|
||||
The workflow is exactly the same as for the creation:
|
||||
|
||||
<Terminal shell title="preview the change, then apply it">{`
|
||||
terraform plan
|
||||
terraform apply
|
||||
`}</Terminal>
|
||||
|
||||
This time, Terraform detects that the resource already exists and needs to be **modified**, not created: the plan shows the new `network` block with a `~ update in-place` action and ends with `Plan: 0 to add, 1 to change, 0 to destroy.`. After you confirm with `yes`, the new interface is attached to the running VM.
|
||||
|
||||
<UiShot light="/img/xo5/terraform-vm-network-single.png" alt="Before the change: the VM's Network tab shows a single interface" url="https://your-xo/#/vms/…/network" />
|
||||
|
||||
<UiShot light="/img/xo5/terraform-vm-network-dual.png" alt="After terraform apply: a second VIF appeared on the VM" url="https://your-xo/#/vms/…/network" />
|
||||
|
||||
## Debugging and logs
|
||||
|
||||
The provider supports detailed logging for troubleshooting, controlled by the `TF_LOG_PROVIDER` environment variable (valid levels: `TRACE`, `DEBUG`, `INFO`, `WARN`, `ERROR`). Add `TF_LOG_PATH` to save the logs to a file:
|
||||
|
||||
<Terminal shell title="run Terraform with provider debug logs written to a file">{`
|
||||
export TF_LOG_PROVIDER=DEBUG
|
||||
export TF_LOG_PATH=./terraform.log
|
||||
terraform apply
|
||||
`}</Terminal>
|
||||
|
||||
:::note
|
||||
Only enable debug logging when troubleshooting, as it significantly increases log verbosity and may impact performance.
|
||||
:::
|
||||
|
||||
## Going further {#conclusion}
|
||||
|
||||
This guide only scratches the surface: the provider also manages cloud-init configuration, extra disks and VDIs, networks, ACLs, resource sets, and more. The [provider documentation on the Terraform registry](https://registry.terraform.io/providers/vatesfr/xenorchestra/latest/docs) is the reference for every resource and data source, and is always up to date with the latest release.
|
||||
|
||||
:::note
|
||||
**Commercial support**: contact our support team through your customer portal.
|
||||
|
||||
**Community support**:
|
||||
|
||||
- [XCP-ng Forum](https://xcp-ng.org/forum/)
|
||||
- [Discord Community](https://discord.com/invite/ZpNq8ez)
|
||||
- [GitHub Issues](https://github.com/vatesfr/terraform-provider-xenorchestra/issues)
|
||||
:::
|
||||
|
||||
## Related links
|
||||
|
||||
- [Provider documentation on the Terraform registry](https://registry.terraform.io/providers/vatesfr/xenorchestra/latest/docs)
|
||||
- [Provider source code on GitHub](https://github.com/vatesfr/terraform-provider-xenorchestra)
|
||||
- [Official Terraform documentation](https://developer.hashicorp.com/terraform/docs)
|
||||
- [OpenTofu documentation](https://opentofu.org/docs/)
|
||||
- [Official XCP-ng documentation](https://docs.xcp-ng.org/)
|
||||
@@ -0,0 +1,230 @@
|
||||
# Backup strategy guide
|
||||
|
||||
This guide explains how to design and implement a backup strategy in Xen Orchestra.
|
||||
|
||||
Instead of a simple list of questions and answers, it walks you through **key decisions** and **best practices** before, during, and after setting up backups.
|
||||
|
||||
|
||||
## Glossary
|
||||
|
||||
This part explains the terminology of backup types and features.
|
||||
|
||||
- [**Backup sequence**](xo5/backups.md#sequences): A feature that allows you to chain multiple backup jobs to run one after the other, automatically.
|
||||
- [**Backup repository (BR)**](xo5/backups.md#remotes): Formerly called _Remote_. A storage location for backups. For instance:
|
||||
- Local storage (not recommended)
|
||||
- NFS
|
||||
- SMB
|
||||
- Amazon S3 and compatible
|
||||
- Microsoft Azure
|
||||
- Azurite
|
||||
- [**File restore**](xo5/backups.md#restore-a-file): A feature that allows you to restore individual files from a VM backup without restoring the full VM.
|
||||
- [**Full backup**](full_backups.md): Copies the entire VM to backup repositories each time, regardless of previous backups.
|
||||
- [**Full replication**](full_replication.md): Creates a replica of a VM on other storage repositories (on the same pool or on another) by copying it completely on each run.
|
||||
- [**Incremental backup**](xo5/incremental_backups.md): Transfers and stores only the changes since the last backup to backup repositories, reducing storage and network needs. The first run transfers the VM completely.
|
||||
- [**Incremental replication**](xo5/incremental_replication.md): Transfers and stores only the changes since the last backup to storage repositories (on the same pool or on another), reducing network needs. The first run transfers the VM completely.
|
||||
- [**Long-term retention**](xo5/backups.md#long-term-backup-retention-with-gfs-strategy): Keeps backups over extended periods (weeks, months, or years) for compliance or archival purposes.
|
||||
- [**Mirror backup**](mirror_backup.md): Mirror a backup repository to another. Retention and encryption of source and destination can be different.
|
||||
- [**Distributed backup and replication**](distributed_backups.md): Distribute the backups and replications across multiple targets.
|
||||
|
||||
|
||||
## What should I do before setting up my backup?
|
||||
|
||||
Before creating your first backup job in Xen Orchestra, consider the following:
|
||||
|
||||
### Backup repository {#remote}
|
||||
|
||||
Choose and configure your backup repository (BR).
|
||||
|
||||
- Supported types: NFS, SMB/CIFS, S3-compatible object storage, Microsoft Azure, or local storage.
|
||||
- Ensure proper permissions and network connectivity.
|
||||
- Test write/read performance before relying on it.
|
||||
- If you're using block storage, check whether your solution supports encryption (for data-at-rest protection) and immutability (to prevent backups from being modified or deleted, even by mistake or maliciously).
|
||||
|
||||
### Resources available
|
||||
|
||||
- **Storage**: Calculate how much space will be required based on your backup type and retention.
|
||||
- **Network**: Backups are network-intensive; ensure sufficient bandwidth.
|
||||
- **Compute**: Avoid backup schedules that overlap with heavy VM workloads.
|
||||
|
||||
### Criticality
|
||||
|
||||
Identify which VMs are business-critical. These should have more frequent backups and possibly replications for minimal downtime.
|
||||
|
||||
### Retention
|
||||
|
||||
Determine how long backups should be kept. This depends on:
|
||||
|
||||
- Compliance requirements
|
||||
- Recovery Point Objective (RPO)
|
||||
- Recovery Time Objective (RTO)
|
||||
- Storage capacity
|
||||
|
||||
|
||||
## What kind of backup should I set up?
|
||||
|
||||
Here is the whole toolbox at a glance. Most infrastructures combine several of these: for example incremental backups for everything, plus incremental replication for the critical VMs, plus a mirror to an offsite repository.
|
||||
|
||||
| Type | What you get | Storage & network cost | Restore | Typical use |
|
||||
| ---------------------------------------------------------- | ------------------------------------------- | --------------------------- | -------------------------------- | -------------------------------------- |
|
||||
| [Rolling snapshots](rolling_snapshots.md) | Instant restore points, on the same storage | SR space only | Instant revert | Oops protection, before risky changes |
|
||||
| [Full backup](full_backups.md) | Complete standalone archive on a BR | High, every run | Simple, anywhere | Small fleets, simplicity first |
|
||||
| [Incremental backup](xo5/incremental_backups.md) | Compact archives after the first full | Low per run | Whole VM or single files | The default choice for most VMs |
|
||||
| [Full replication (DR)](full_replication.md) | Boot-ready copy on another host/SR | High, every run | Start the copy | DR with a modest RPO |
|
||||
| [Incremental replication (CR)](xo5/incremental_replication.md) | Boot-ready copy, updated by deltas | Low per run | Clone and start | Low-RPO DR for critical VMs |
|
||||
| [Mirror backup](mirror_backup.md) | A second copy of a backup repository | Follows the source | Same as the source backups | 3-2-1 strategies, offsite archives |
|
||||
| [Metadata backup](xo5/metadata_backup.md) | XO config and pool metadata | Tiny | Rebuild your orchestration | Always: it protects the tool itself |
|
||||
|
||||
:::note The two replication modes have been renamed
|
||||
**Full replication** used to be called **Disaster Recovery (DR)**, and **incremental replication** used to be called **Continuous Replication (CR)**. Only the names changed. The old ones are kept in parentheses here because you will still meet them: the XO 5 interface labels the two buttons **Disaster Recovery** and **Continuous Replication**, and XO tags replicas accordingly. XO 6 uses the current names.
|
||||
:::
|
||||
|
||||
### Rolling snapshots
|
||||
|
||||
Scheduled snapshots with a retention, kept on the VM's own storage.
|
||||
|
||||
- **Pros**: instant creation and instant revert, no repository needed.
|
||||
- **Watch out**: snapshots live on the same storage as the VM. Lose the SR, lose the snapshots: this is **not** a backup on its own.
|
||||
- **First steps**: schedule a nightly snapshot with a retention of 7 on the VMs you touch often.
|
||||
|
||||
### Full backup
|
||||
|
||||
A complete export of each VM to a backup repository, on every run.
|
||||
|
||||
- **Pros**: each archive is independent and self-contained, restores are trivial, only allocated blocks are transferred, and Zstd compression is available (XCP-ng 8.1 and newer).
|
||||
- **Watch out**: the most storage- and bandwidth-hungry option; no deduplication between runs.
|
||||
- **First steps**: configure a reliable repository with generous capacity, and schedule runs during low I/O periods.
|
||||
|
||||
### Incremental backup
|
||||
|
||||
After an initial full, only the changed blocks are exported.
|
||||
|
||||
- **Pros**: fast runs, small transfers, restore to any date, [file-level restore](xo5/backups.md#file-level-restore), works well at high frequency.
|
||||
- **Watch out**: restores rely on a chain (full + deltas): set a [full backup interval](xo5/incremental_backups.md#key-backup-interval) to keep chains short, or enable health checks.
|
||||
- **First steps**: this is the right default for most VMs; start here if in doubt.
|
||||
|
||||
### Full replication (formerly Disaster Recovery, DR) {#full-replication-dr}
|
||||
|
||||
A complete, boot-ready copy of the VM on another host or SR, refreshed on each run.
|
||||
|
||||
- **Pros**: the standby VM is ready to start; ideal for straightforward disaster recovery.
|
||||
- **Watch out**: full transfer each time: run it less frequently than incremental replication, and mind SR space on the destination.
|
||||
- **First steps**: configure the destination storage (same pool or another), then **test the failover** for real.
|
||||
|
||||
### Incremental replication (formerly Continuous Replication, CR) {#incremental-replication-cr}
|
||||
|
||||
The same standby copy, kept up to date by sending only the deltas.
|
||||
|
||||
- **Pros**: low RPO (down to minutes), quick failover, no vendor lock-in, no intermediate storage.
|
||||
- **Watch out**: needs a secondary host or pool; keep the chain short (full backup interval < 10); not an archival method.
|
||||
- **First steps**: reserve it for the VMs whose data loss tolerance is measured in minutes.
|
||||
|
||||
### Mirror backup
|
||||
|
||||
Replicates an existing backup repository to another one, possibly with different retention, encryption or compression.
|
||||
|
||||
- **Pros**: the natural building block of a [3-2-1 strategy](#long-term-retention-strategy); the second copy can live on slower, cheaper storage.
|
||||
- **Watch out**: one job mirrors either full or incremental backups, not both: two jobs if your source repository holds both.
|
||||
- **First steps**: set up a dedicated destination repository, then test a restore from the mirror itself.
|
||||
|
||||
### Sequence
|
||||
|
||||
Not a backup type, but the way to chain the jobs above: a [sequence](xo5/backups.md#sequences) runs several schedules one after the other, in a fixed order.
|
||||
|
||||
- **Pros**: deterministic ordering (backup first, then replication), no overlapping jobs competing for resources.
|
||||
- **First steps**: identify the right order, and test the sequence on non-critical VMs first.
|
||||
|
||||
## What settings are available?
|
||||
|
||||
### Advanced settings
|
||||
|
||||
- **Compression**: Reduces backup size at the cost of CPU usage and backup speed.
|
||||
- **Encryption**: Protects backup data at rest.
|
||||
- **Concurrency**: Controls how many VMs run in parallel in this backup job.
|
||||
- **Retention policy**: Fine-tunes how many backups to keep over certain periods of time.
|
||||
- **Full backup interval**: Defines the maximum backup chain size (only for delta backups and incremental replications).
|
||||
|
||||
:::tip
|
||||
|
||||
- **Compression** is configured at the backup job level, and applies only to full backups. For full backups, prefer [Zstandard (Zstd)](https://en.wikipedia.org/wiki/Zstd) if your host supports it.
|
||||
- **Encryption** is configured at the backup repository level, not per individual backup job. To use encryption with incremental backups, the **use VHD blocks** setting must be enabled.
|
||||
- Setting a **Full backup interval** prevents infinite backup chains, which may degrade resilience against block corruption over time. We recommend either defining a regular interval or enabling health checks for your incremental backup and incremental replication jobs.
|
||||
:::
|
||||
|
||||
|
||||
## Restore options
|
||||
|
||||
### VM restore
|
||||
|
||||
- Restore a VM to the same host/pool or another location.
|
||||
- When restoring, Xen Orchestra can attempt a **differential restore**, which reuses the current VM disk to speed up the process.
|
||||
|
||||
### File restore
|
||||
|
||||
- Access individual files within a VM backup
|
||||
- Ideal for quick recovery of deleted or corrupted files without a full VM restore
|
||||
|
||||
### Limitations
|
||||
|
||||
The file restore feature includes the following constraints:
|
||||
|
||||
- **Supported partition types** are limited to those compatible with Debian systems and NTFS. ReFS and Windows dynamic disks are not supported.
|
||||
- **LVM support** is limited and may fail in certain edge cases.
|
||||
- File restore is designed for **small file sets** and is not suitable for large-scale recovery.
|
||||
|
||||
:::tip
|
||||
For **advanced scenarios**, you can use the `fuse-vhd` helper script to manually mount backup chains as raw disks and perform partition discovery:
|
||||
[View fuse-vhd on GitHub](https://github.com/vatesfr/xen-orchestra/tree/master/%40vates/fuse-vhd).
|
||||
:::
|
||||
|
||||
|
||||
## Long-term retention strategy
|
||||
|
||||
For compliance or archival needs, you rarely want *every* daily backup kept for years: you want something like 7 dailies, 4 weeklies, 12 monthlies, a few yearlies. This is the **GFS (Grandfather-Father-Son)** scheme, configured directly in the retention settings of a backup job: see [Long-term backup retention with GFS](xo5/backups.md#long-term-backup-retention-with-gfs-strategy).
|
||||
|
||||
- Define retention periods based on compliance and operational needs
|
||||
- Size the required storage with the [retention calculator](calculator.md)
|
||||
- Regularly test restore from long-term backups
|
||||
|
||||
:::warning
|
||||
To prevent backup duplication, do not mix long-term retention with multiple schedules.
|
||||
:::
|
||||
|
||||
|
||||
## Putting it all together
|
||||
|
||||
When designing your backup strategy with Xen Orchestra:
|
||||
|
||||
1. Assess criticality and resources.
|
||||
2. Choose backup types that match your RPO/RTO goals.
|
||||
3. Configure backup repositories and test them.
|
||||
4. Set up schedules to avoid peak loads.
|
||||
5. Apply retention policies.
|
||||
6. Test restores regularly.
|
||||
|
||||
|
||||
## How to ensure XOA is always available
|
||||
|
||||
Making sure XOA is always available should be a top priority for every administrator. Here’s how you can maximize its reliability:
|
||||
|
||||
Since XOA runs as a virtual machine, you can apply standard VM protection measures:
|
||||
|
||||
- Back up regularly (full or incremental).
|
||||
- Replicate the VM (full replication or incremental replication).
|
||||
- Take snapshots for quick rollback if needed.
|
||||
|
||||
### Specific steps for the XOA VM
|
||||
|
||||
- **Back up XO backup metadata:** This is the most efficient way to ensure you can quickly restore your XOA environment. If you lose your XOA VM: download and install a new XOA, restore the XO backup metadata, and you’ll be able to restore all other backups and settings.
|
||||
- Use the **XO Config** feature to back up your XOA settings. This lets you restore them to any XOA VM if necessary.
|
||||
|
||||
### Managing the loss of your XOA VM
|
||||
|
||||
If you lose the host running your XOA VM:
|
||||
|
||||
- **If the XOA VM was on shared storage**, you can restart it on another host in your pool.
|
||||
- **If the XOA VM was stored locally** or your host was alone in its pool, deploy a new XOA VM. You can do this proactively, as there’s no limit to the number of XOA VMs in your infrastructure. Register the new VM with the same Vates account, update it, and migrate your XOA license from the old VM if needed.
|
||||
- **If you are running XCP-ng 8.3**, you can use XO-lite by connecting to your master host’s IP address to manage your VMs.
|
||||
|
||||
:::warning
|
||||
Avoid using multiple XOAs to back up the same VMs, as this can cause backup failures.
|
||||
:::
|
||||
@@ -1,5 +1,6 @@
|
||||
---
|
||||
title: Backup retention calculator
|
||||
sidebar_label: Retention calculator
|
||||
---
|
||||
|
||||
import LtrBackupCalculator from '@site/src/components/LtrBackupCalculator'
|
||||
@@ -0,0 +1,47 @@
|
||||
# Community support
|
||||
|
||||
We do our best to assist users running Xen Orchestra from the sources on [our community forum](https://xcp-ng.org/forum/category/12/xen-orchestra) (you can also chat with the community on [Discord](https://discord.gg/Hr98F6wRvx)). However there's no guarantee you will receive a solution (from us or the community), nor any guarantee on a timeframe. Usually we are responsive, but keep in mind that if you need production level support, you should consider subscribing to our [XOA offers](https://vates.tech/pricing-and-support/).
|
||||
|
||||
:::warning
|
||||
If you installed your XO from a 3rd party script (any method outside [our official documentation](install-from-sources.md)), please report your issue **first** on the 3rd party script repository. We can't waste time debugging 3rd party installers that very often lag behind our own deployment methods and fall out of date.
|
||||
:::
|
||||
|
||||
## Current version
|
||||
|
||||
With Xen Orchestra from the sources, you can check your current commit hash in the **About** section. It compares your commit to the tip of `master`, and tells you directly if you are behind:
|
||||
|
||||
<UiShot light="/img/xo5/xo5-about.png" alt="The About view of a sources install: your commit, the current master commit, and a warning when you are behind" url="https://your-xo/v5/#/about" />
|
||||
|
||||
:::tip
|
||||
You can also compare your hash to the current commit list in [our GitHub repository](https://github.com/vatesfr/xen-orchestra/commits/master).
|
||||
:::
|
||||
|
||||
## Report a bug
|
||||
|
||||
:::warning
|
||||
Before reporting a bug, please check that your **current version is up-to-date with the latest commit on `master`!** See the [Current version](#current-version) section above.
|
||||
:::
|
||||
|
||||
If you have issues with XO installed from the sources (via GitHub), please **always** first:
|
||||
|
||||
1. update your XO to the latest `master` commit (see how-to in the [dedicated section](install-from-sources.md#updating)) and retest again
|
||||
2. if the issue persists, double check you have all the requirements checked from the [installation section](install-from-sources.md) and test again
|
||||
3. then, if you still experience problems, [remove and rebuild from scratch](install-from-sources.md#troubleshooting)
|
||||
|
||||
Only after that, you can go to the [dedicated forum](https://xcp-ng.org/forum/category/12/xen-orchestra) to ask about your problem.
|
||||
|
||||
:::tip
|
||||
If you want a consistent and tested solution for using Xen Orchestra, we strongly advise using our preconfigured and validated [Xen Orchestra Virtual Appliance](installation.md#xoa).
|
||||
:::
|
||||
|
||||
## Feature requests
|
||||
|
||||
The best way to submit a feature request is to:
|
||||
|
||||
1. Post your idea on [feedback.vates.tech](https://feedback.vates.tech/), explaining **why you need it**.
|
||||
2. Discuss it on [the forum](https://xcp-ng.org/forum/category/12/xen-orchestra) to gather feedback and support from other users.
|
||||
3. Wait for the feature to be released!
|
||||
|
||||
:::tip
|
||||
Obviously, XOA users get a higher priority to get new features, since they contribute directly to the project with a subscription. However, your feedback/ideas are always welcome, and the more popular the feature request is, the higher the chances it will be added!
|
||||
:::
|
||||
@@ -6,7 +6,7 @@ Once Xen Orchestra is installed, you can configure some parameters in the config
|
||||
The configuration file is located at `/etc/xo-server/config.toml`.
|
||||
:::
|
||||
|
||||
If you need to do any configuration on the system itself (firewall, SSH…), check the [XOA dedicated section](xoa.md).
|
||||
If you need to do any configuration on the system itself (firewall, NTP, service restart…), see [the XOA appliance settings](#xoa-appliance) at the end of this page.
|
||||
|
||||
## Using XO 5 as the Default Interface
|
||||
|
||||
@@ -76,9 +76,9 @@ The update feature of XOA can reset any `local` config. Use `/etc/xo-server/conf
|
||||
|
||||
After updating the configuration, restart the XO server process:
|
||||
|
||||
```sh
|
||||
<Terminal shell title="xoa — apply the configuration">{`
|
||||
sudo systemctl restart xo-server
|
||||
```
|
||||
`}</Terminal>
|
||||
|
||||
XO 5 will now be served as the default UI.
|
||||
|
||||
@@ -91,7 +91,7 @@ user = 'nobody'
|
||||
group = 'nogroup'
|
||||
```
|
||||
|
||||
**Warning!** A non-privileged user requires the use of `sudo` to mount NFS shares. See [installation from the sources](installation.md#from-the-sources).
|
||||
**Warning!** A non-privileged user requires the use of `sudo` to mount NFS shares. See [installation from the sources](install-from-sources.md).
|
||||
|
||||
## HTTP listen address and port
|
||||
|
||||
@@ -146,14 +146,14 @@ The SDN Controller plugin has 2 modes for the OpenFlow rule management. The defa
|
||||
For this kind of setting, we recommend using something like `/etc/xo-server/config.sdncontroller.toml` and not to modify the main configuration file.
|
||||
:::
|
||||
|
||||
```
|
||||
```toml
|
||||
[plugins.sdn-controller]
|
||||
useDirectChannel = false
|
||||
```
|
||||
|
||||
Changing the mode is only supported forward : from direct OpenFlow Protocol channel to XAPI Plugin communication.
|
||||
A migration script is provided to automatically convert the traffic rules.
|
||||
See [XO 5 > Management > SDN Controller > OpenFlow rules](sdn_controller#migration-path) for details.
|
||||
See [SDN Controller: OpenFlow rules](xo5/sdn_controller.md#migration-path) for details.
|
||||
|
||||
## Custom certificate authority
|
||||
|
||||
@@ -168,12 +168,17 @@ Environment=NODE_EXTRA_CA_CERTS=/usr/local/share/ca-certificates/my-cert.crt
|
||||
|
||||
Don't forget to reload `systemd` conf and restart `xo-server`:
|
||||
|
||||
```sh
|
||||
<Terminal shell title="xoa — reload systemd">{`
|
||||
systemctl daemon-reload
|
||||
systemctl restart xo-server.service
|
||||
```
|
||||
`}</Terminal>
|
||||
|
||||
> For XO Proxy, the process is almost the same except the file to create is `/etc/systemd/system/xo-proxy.service.d/ca.conf` and the service to restart is `xo-proxy.service`.
|
||||
<Terminal shell title="xoa — restart xo-server">{`
|
||||
systemctl restart xo-server.service
|
||||
`}</Terminal>
|
||||
|
||||
:::note
|
||||
For XO Proxy, the process is almost the same: the file to create is `/etc/systemd/system/xo-proxy.service.d/ca.conf` and the service to restart is `xo-proxy.service`.
|
||||
:::
|
||||
|
||||
### Let's Encrypt support
|
||||
|
||||
@@ -205,7 +210,7 @@ In order for XOA to work with Let's Encrypt, follow these prerequisites:
|
||||
|
||||
- In `xo-server`, to prevent HTTP access, enable the redirection to HTTPs:
|
||||
|
||||
```
|
||||
```toml
|
||||
[http]
|
||||
redirectToHttps = true
|
||||
```
|
||||
@@ -213,7 +218,7 @@ redirectToHttps = true
|
||||
- Your server must be reachable using the configured domain by the certificate provider (e.g., Let's Encrypt). This typically means it needs to be publicly accessible.
|
||||
- Add the following entries to your HTTPS configuration:
|
||||
|
||||
```
|
||||
```toml
|
||||
# Must be set to true for this feature
|
||||
autoCert = true
|
||||
|
||||
@@ -375,4 +380,111 @@ location /[<path>] {
|
||||
}
|
||||
```
|
||||
|
||||
### Caddy
|
||||
|
||||
[Caddy](https://caddyserver.com/) is the simplest option: WebSockets are proxied natively (no module or upgrade headers to configure) and HTTPS certificates are obtained and renewed automatically. Serving Xen Orchestra on a dedicated domain takes two lines:
|
||||
|
||||
```
|
||||
xo.company.net {
|
||||
reverse_proxy <XOA ip address>:80
|
||||
}
|
||||
```
|
||||
|
||||
To serve it under a sub-path instead:
|
||||
|
||||
```
|
||||
company.net {
|
||||
handle_path /xo/* {
|
||||
reverse_proxy <XOA ip address>:80
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
:::note
|
||||
Caddy applies no request body size limit by default, so large VM imports work without extra configuration.
|
||||
:::
|
||||
|
||||
## The XOA appliance {#xoa-appliance}
|
||||
|
||||
System-level settings of the appliance itself, all managed from its console or SSH.
|
||||
|
||||
### Firewall {#firewall}
|
||||
|
||||
By default XOA is firewalled, with only ports 22, 80 and 443 opened. You can see the current status of the firewall:
|
||||
|
||||
<Terminal title="check the firewall status">{`
|
||||
sudo ufw status verbose
|
||||
Status: active
|
||||
Logging: on (low)
|
||||
Default: deny (incoming), allow (outgoing)
|
||||
New profiles: skip
|
||||
|
||||
To Action From
|
||||
-- ------ ----
|
||||
22 ALLOW IN Anywhere
|
||||
80 ALLOW IN Anywhere
|
||||
443 ALLOW IN Anywhere
|
||||
22/tcp LIMIT IN Anywhere
|
||||
`}</Terminal>
|
||||
|
||||
If you want to open or close ports, please check the [documentation of UFW](https://help.ubuntu.com/community/UFW).
|
||||
|
||||
### Timezone {#timezone}
|
||||
|
||||
You can verify that your time is correctly set with the `date` command. To set XOA to your current timezone:
|
||||
|
||||
<Terminal shell title="set the timezone">{`
|
||||
sudo dpkg-reconfigure tzdata
|
||||
`}</Terminal>
|
||||
|
||||
### Setting a custom NTP server {#setting-a-custom-ntp-server}
|
||||
|
||||
By default, XOA is configured to use the `systemd-timesyncd` daemon, along with the standard Debian NTP servers:
|
||||
|
||||
```
|
||||
pool 0.debian.pool.ntp.org iburst
|
||||
pool 1.debian.pool.ntp.org iburst
|
||||
pool 2.debian.pool.ntp.org iburst
|
||||
pool 3.debian.pool.ntp.org iburst
|
||||
```
|
||||
|
||||
To change the NTP servers, use the `xoa` helper:
|
||||
|
||||
<Terminal title="change the NTP servers">{`
|
||||
xoa network ntp
|
||||
? NTP servers (space separated)
|
||||
`}</Terminal>
|
||||
|
||||
Alternatively, edit `/etc/systemd/timesyncd.conf` (as root): we recommend adding your custom server to the top of the list, leaving the Debian server entries if possible.
|
||||
|
||||
For changes to take effect, restart the time synchronization service:
|
||||
|
||||
<Terminal shell title="apply the NTP change">{`
|
||||
systemctl restart systemd-timesyncd.service
|
||||
`}</Terminal>
|
||||
|
||||
### Restart the service {#restart-the-service}
|
||||
|
||||
You can restart Xen Orchestra by accessing XOA via SSH (or console):
|
||||
|
||||
<Terminal shell title="restart xo-server">{`
|
||||
systemctl restart xo-server.service
|
||||
`}</Terminal>
|
||||
|
||||
To check the status of `xo-server`:
|
||||
|
||||
<Terminal title="check the service">{`
|
||||
systemctl status xo-server.service
|
||||
xo-server.service - XO Server
|
||||
Loaded: loaded (/etc/systemd/system/xo-server.service; enabled)
|
||||
Active: active (running) since Thu 2014-08-14 10:59:46 BST; 21min ago
|
||||
Main PID: 394 (node)
|
||||
CGroup: /system.slice/xo-server.service
|
||||
└─394 node /usr/local/bin/xo-server
|
||||
|
||||
Aug 14 10:59:46 xoa systemd[1]: Starting XO Server...
|
||||
Aug 14 10:59:46 xoa systemd[1]: Started XO Server.
|
||||
Aug 14 10:59:48 xoa xo-server[394]: WebServer listening on http://0.0.0.0:80
|
||||
`}</Terminal>
|
||||
|
||||
That's all!
|
||||
+26
-10
@@ -2,26 +2,42 @@
|
||||
|
||||
XO is an Open Source project released under the [AGPL v3](http://www.gnu.org/licenses/agpl-3.0-standalone.html) license, contributions are therefore very welcome.
|
||||
|
||||
This page is a summary: the source of truth is the [CONTRIBUTING.md](https://github.com/vatesfr/xen-orchestra/blob/master/CONTRIBUTING.md) file at the root of the repository, and the project is governed by its [Code of Conduct](https://github.com/vatesfr/xen-orchestra/blob/master/CODE_OF_CONDUCT.md).
|
||||
|
||||
## Questions
|
||||
|
||||
If you have a question, do not open a GitHub issue: search the [Xen Orchestra section of our forum](https://xcp-ng.org/forum/category/12/xen-orchestra) first, and open a new topic there if needed, with as much context as you can (versions, platform, what you are trying to do).
|
||||
|
||||
## Bug reports
|
||||
|
||||
You can [open bug reports here](https://github.com/vatesfr/xen-orchestra/issues) (issues, enhancements, ideas etc.).
|
||||
Bugs are tracked as [GitHub issues](https://github.com/vatesfr/xen-orchestra/issues). Before opening one:
|
||||
|
||||
:::tip
|
||||
Before creating an issue, please take a look [into this section](xo6/community.md) for more details.
|
||||
- Make sure you are using the latest version.
|
||||
- Check the [documentation](https://docs.xen-orchestra.com/) and the [forum](https://xcp-ng.org/forum/category/12/xen-orchestra) to rule out a configuration problem.
|
||||
- Search [existing bug reports](https://github.com/vatesfr/xen-orchestra/issues?q=label%3Abug) to avoid duplicates.
|
||||
- Collect the relevant information: stack trace, OS and platform, versions, reproduction steps.
|
||||
|
||||
In your report, explain the behavior you expected, the actual behavior, and the reproduction steps someone else can follow.
|
||||
|
||||
:::warning
|
||||
Never report security vulnerabilities or bugs containing sensitive information in the public issue tracker. Use the [dedicated security advisories page](https://github.com/vatesfr/xen-orchestra/security/advisories/new) instead.
|
||||
:::
|
||||
|
||||
## Suggesting enhancements
|
||||
|
||||
Enhancement suggestions (new features and improvements) are also tracked as [GitHub issues](https://github.com/vatesfr/xen-orchestra/issues). Search existing suggestions first, use a clear title, describe the current behavior and the behavior you expected, and explain why the change would be useful to most Xen Orchestra users. For more general product feedback, see the [About page](intro_project.md#feedback-and-issues).
|
||||
|
||||
## Translations
|
||||
|
||||
[Help us translate Xen Orchestra in more languages!](http://translate.vates.tech/engage/xen-orchestra/)
|
||||
|
||||
## Documentation / Code
|
||||
|
||||
Using the GitHub fork/pull-request feature, you may send us fixes or enhancements.
|
||||
:::note
|
||||
By contributing, you confirm that you authored 100% of the content, that you have the necessary rights to it, and that it may be provided under the project license.
|
||||
:::
|
||||
|
||||
Please, do explain:
|
||||
|
||||
- what you are fixing (issue number if available);
|
||||
- how you did it.
|
||||
Using the GitHub fork/pull-request feature, you may send us fixes or enhancements. Please explain what you are fixing (issue number if available) and how you did it.
|
||||
|
||||
### Pull requests
|
||||
|
||||
@@ -29,13 +45,13 @@ The best way to propose a change to the documentation or code is
|
||||
to create a [GitHub pull request](https://help.github.com/articles/using-pull-requests/).
|
||||
|
||||
1. Fork the [Xen Orchestra repository](https://github.com/vatesfr/xen-orchestra) using the Fork button
|
||||
2. Follow [the documentation](./xo5/installation.md#from-the-sources) to install and run Xen Orchestra from the sources
|
||||
2. Follow [the documentation](./install-from-sources.md) to install and run Xen Orchestra from the sources
|
||||
3. Create a branch for your work
|
||||
4. Edit the source files
|
||||
5. Add a summary of your changes to `CHANGELOG.unreleased.md`, if your changes do not relate to an existing changelog item and update the list of packages that must be released to take your changes into account
|
||||
6. [Create a pull request](https://github.com/vatesfr/xen-orchestra/compare) for this branch against the `master` branch
|
||||
7. Push into the branch until the pull request is ready to merge
|
||||
8. Avoid unnecessary merges: keep you branch up to date by regularly rebasing `git rebase origin/master`
|
||||
8. Avoid unnecessary merges: keep your branch up to date by regularly rebasing `git rebase origin/master`
|
||||
9. When ready to merge, clean up the history (reorder commits, squash some of them together, rephrase messages): `git rebase -i origin/master`
|
||||
|
||||
### Issue triage
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
# Credential Database Encryption
|
||||
|
||||
Xen Orchestra stores its records (server connections, backup jobs and remotes, schedules, users, groups, authentication tokens, ACLs, tags, cloud configs, proxy registrations and plugin configurations) in Redis. When credential encryption is enabled, every record is encrypted at rest with AES-256-GCM (encrypted values carry an `enc:` prefix), and index keys are replaced with HMAC-SHA256 blind indexes so indexed field values (emails, hostnames, etc.) are never stored as plaintext. The performance impact is negligible for typical deployments.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- XO must run as a VM on a XenServer/XCP-ng host with Xen tools available: one of the two key halves lives in XenStore, accessed through the `xenstore-read` and `xenstore-write` commands. This requires running xo-server as root or granting it access to the xenstored socket.
|
||||
- The path `/var/lib/xo-server/data/` must be writable by the xo-server process.
|
||||
|
||||
## Enabling Encryption
|
||||
|
||||
Add the following to your [configuration file](configuration.md):
|
||||
|
||||
```toml
|
||||
[redis]
|
||||
encryptCredentialDatabase = true
|
||||
```
|
||||
|
||||
On the next startup, XO will:
|
||||
|
||||
1. Generate two random 32-byte key halves
|
||||
2. Store one half in XenStore (`vm-data/xo-encryption-key`) and one in `/var/lib/xo-server/data/xo-encryption-key` (mode `0400`)
|
||||
3. Derive an AES-256 encryption key and an HMAC key from the two halves using HKDF-SHA256
|
||||
4. Encrypt all existing Redis records and rebuild the indexes as HMAC blind indexes
|
||||
5. Verify the migration and delete the plaintext backup on success
|
||||
|
||||
A plaintext backup is written to `/var/lib/xo-server/data/encryption-backup.json` before the migration begins and deleted on success (if that file already exists, a numbered variant such as `encryption-backup_1.json` is used instead). If the migration fails, the file is preserved for manual recovery.
|
||||
|
||||
## Key Management
|
||||
|
||||
The encryption key is split across two locations, so the compromise of one alone is not sufficient to decrypt the database:
|
||||
|
||||
| Half | Location |
|
||||
| ---- | ------------------------------------------- |
|
||||
| A | XenStore: `vm-data/xo-encryption-key` |
|
||||
| B | `/var/lib/xo-server/data/xo-encryption-key` |
|
||||
|
||||
Both halves are required to derive the actual encryption and HMAC keys. Neither half should be backed up in plaintext.
|
||||
|
||||
:::warning
|
||||
If either key half is lost while encryption is enabled, **do not restart xo-server**: at startup, XO treats a missing key half as a fresh setup, generates two new halves (overwriting the one that survived) and re-runs the encryption migration, which skips records that are already encrypted. Those records become permanently undecryptable. Put the missing half back in place before the next restart, or restore a config backup. Keep a fresh config backup at all times.
|
||||
:::
|
||||
|
||||
## Config Backup
|
||||
|
||||
When credential encryption is enabled, exporting the XO configuration **requires a passphrase**. The export is then encrypted with OpenPGP using that passphrase. Export from the web interface (Settings > Config, which prompts for a passphrase) or with `xo-cli`:
|
||||
|
||||
<Terminal shell title="export the XO config, protected by a passphrase">{`
|
||||
xo-cli xo.exportConfig passphrase=<your-passphrase> @=/path/to/xo-config.bin
|
||||
`}</Terminal>
|
||||
|
||||
The export contains the decrypted credential data (hence the mandatory passphrase). When restored on any XO instance, records are re-encrypted with that instance's own keys automatically, no manual key transfer is needed:
|
||||
|
||||
<Terminal shell title="import a passphrase-protected config backup">{`
|
||||
xo-cli xo.importConfig passphrase=<your-passphrase> @=/path/to/xo-config.bin
|
||||
`}</Terminal>
|
||||
|
||||
See also [Back up XO metadata](./backup_howto.md#specific-steps-for-the-xoa-vm).
|
||||
|
||||
:::tip
|
||||
Always export a fresh config backup after enabling encryption and store it securely.
|
||||
:::
|
||||
|
||||
## Disabling Encryption
|
||||
|
||||
Set `encryptCredentialDatabase = false` (or remove the option) and restart. XO detects the existing key files, decrypts all records, rebuilds plaintext indexes, then deletes both key halves. The process is automatic.
|
||||
|
||||
An encrypted backup is written to `/var/lib/xo-server/data/encryption-backup.json` before the migration begins and deleted on success. If the migration fails, both key halves are kept and the file is preserved for manual recovery.
|
||||
|
||||
## Recovering from a Failed Migration
|
||||
|
||||
Both the encryption and decryption migrations write a backup of all Redis records to `/var/lib/xo-server/data/encryption-backup.json` before touching any data. The backup is deleted only on success. On failure, XO logs:
|
||||
|
||||
```
|
||||
xo:crypto-credentials ERROR Credential database migration failed - running in degraded mode { backupPath: '/var/lib/xo-server/data/encryption-backup.json' }
|
||||
```
|
||||
|
||||
### Failed Encryption Migration
|
||||
|
||||
The backup file contains the original **plaintext** Redis records.
|
||||
|
||||
**Option 1: restart.** If the failure was transient (for example a temporary Redis error), restart xo-server. The key files already exist, so XO loads them and serves data normally. The encrypted values are written to Redis in a single atomic operation, so if that write never happened the data is still plaintext and readable. Note that the interrupted migration is not retried on restart: records still in plaintext stay in plaintext until they are next written. To force a full re-encryption, disable encryption (see Option 2), let the decryption migration finish and remove the keys, then enable it again.
|
||||
|
||||
**Option 2: roll back to plaintext.** To abandon the migration, set `encryptCredentialDatabase = false` (or remove the option) and restart, **leaving the key files in place**. XO detects the keys and runs the decryption migration: any record that was encrypted is decrypted back to plaintext, then both key halves are deleted automatically. Never remove the key halves manually while encrypted records may remain in Redis: they would become impossible to decrypt. If the rollback fails too, restore a pre-encryption config backup with `xo-cli xo.importConfig` (safest path); the backup file keeps the raw plaintext records for manual recovery otherwise.
|
||||
|
||||
**Option 3: restore a config backup.** If you exported a config backup before enabling encryption:
|
||||
|
||||
<Terminal shell title="restore a pre-encryption config backup">{`
|
||||
xo-cli xo.importConfig @=/path/to/xo-config.json
|
||||
`}</Terminal>
|
||||
|
||||
This re-imports all records, and XO re-encrypts them with the current instance's keys automatically.
|
||||
|
||||
### Failed Decryption Migration
|
||||
|
||||
The backup file contains the **encrypted** Redis records (the pre-decryption snapshot).
|
||||
|
||||
**Option 1: retry.** Both key halves (XenStore entry and key file) are kept in place after a decryption failure. Restart xo-server with `encryptCredentialDatabase` still unset or `false`: XO detects the key files and retries the decryption migration automatically.
|
||||
|
||||
**Option 2: re-enable encryption, export, then disable cleanly.** If retrying does not work:
|
||||
|
||||
1. Set `encryptCredentialDatabase = true` again and restart. XO loads the existing keys and serves the encrypted data normally, without triggering any migration.
|
||||
2. Export your configuration with a passphrase (interface or CLI):
|
||||
|
||||
<Terminal shell title="export the config with a passphrase">{`
|
||||
xo-cli xo.exportConfig passphrase=<your-passphrase> @=/path/to/xo-config.bin
|
||||
`}</Terminal>
|
||||
|
||||
3. Set `encryptCredentialDatabase = false`, remove both key halves and flush Redis:
|
||||
|
||||
<Terminal shell title="remove the keys and flush Redis">{`
|
||||
xenstore-rm vm-data/xo-encryption-key
|
||||
rm /var/lib/xo-server/data/xo-encryption-key
|
||||
redis-cli FLUSHALL
|
||||
`}</Terminal>
|
||||
|
||||
4. Restart: XO starts with an empty database. Import the config backup:
|
||||
|
||||
<Terminal shell title="import the config backup">{`
|
||||
xo-cli xo.importConfig passphrase=<your-passphrase> @=/path/to/xo-config.bin
|
||||
`}</Terminal>
|
||||
|
||||
The records are re-imported in plaintext with no encryption active.
|
||||
|
||||
## Degraded Mode
|
||||
|
||||
If XO cannot safely use the credential database at startup, it enters degraded mode. This happens when the Xen tools are unavailable while a key half must be read, when key generation or loading fails, when a migration fails, or when encryption has been disabled but only the file key half is found (the XenStore half is missing). Note that with encryption **enabled**, a missing key half does not trigger degraded mode: XO regenerates the keys instead (see the warning in [Key Management](#key-management)). In degraded mode:
|
||||
|
||||
- The HTTP server remains available (a support tunnel can still connect)
|
||||
- API calls are rejected with an explicit error: `XO is running in degraded mode: credential decryption failed.`
|
||||
- No server connections, logins or remote access are possible
|
||||
|
||||
Check the server logs for the exact cause:
|
||||
|
||||
```
|
||||
xo:crypto-credentials ERROR Credential database encryption failed - running in degraded mode
|
||||
xo:crypto-credentials ERROR Credential database decryption failed - running in degraded mode
|
||||
xo:crypto-credentials ERROR Credential database migration failed - running in degraded mode
|
||||
xo:crypto-credentials ERROR Only one encryption key half found - running in degraded mode
|
||||
xo:crypto-credentials ERROR Xenstore tools not available, credential database encryption failed - running in degraded mode
|
||||
xo:crypto-credentials ERROR Xenstore tools not available, credential database decryption failed - running in degraded mode
|
||||
xo:crypto-credentials ERROR Existing key loading failed, decryption migration impossible - running in degraded mode
|
||||
```
|
||||
|
||||
**Recovery options:**
|
||||
|
||||
- Fix the reported cause and restart: repair the Xen tools or their access rights, or put the missing XenStore key half back in place
|
||||
- Restore a config backup made before the keys were lost: `xo-cli xo.importConfig`
|
||||
- Contact support: the HTTP server being available means a support tunnel can be established
|
||||
@@ -1,8 +1,43 @@
|
||||
---
|
||||
sidebar_label: Distributed backups
|
||||
---
|
||||
|
||||
# Distributed Backups
|
||||
|
||||
Distributed backups let you spread backup and replication workloads across multiple storage targets, treating them as a pool rather than independent destinations.
|
||||
|
||||
By default, when a backup job has several remotes or storage repositories (SRs) configured, each VM backup is written to **every** target. With distributed mode enabled, each VM backup is written to **exactly one** target per run, selected automatically based on available space.
|
||||
By default, when a backup job has several backup repositories (BR) or storage repositories (SRs) configured, each VM backup is written to **every** target. With distributed mode enabled, each VM backup is written to **exactly one** target per run, selected automatically based on available space.
|
||||
|
||||
<Schema label="Distributed mode: one backup job, and each VM backup lands on a single BR, picked for its free space at run time" legend={[["#56c288", "VM backup"], ["#5ac8c8", "Transfer"], ["#e0a94a", "BR"]]} maxWidth="640px">
|
||||
<svg viewBox="0 0 640 220" role="img" aria-label="Three VMs in one backup job each send their backup to exactly one of three backup repositories of different sizes, instead of every backup going to every target">
|
||||
<text x="32" y="26" fill="#c6d2e1" fontSize="12">Backup job</text>
|
||||
<rect x="24" y="34" width="170" height="170" rx="10" fill="none" stroke="rgba(255,255,255,0.22)" strokeDasharray="6 5" />
|
||||
<rect x="40" y="54" width="138" height="36" rx="6" fill="rgba(255,255,255,0.04)" stroke="#56c288" />
|
||||
<text x="109" y="76" fill="#c6d2e1" fontSize="12" textAnchor="middle">VM 1</text>
|
||||
<rect x="40" y="104" width="138" height="36" rx="6" fill="rgba(255,255,255,0.04)" stroke="#56c288" />
|
||||
<text x="109" y="126" fill="#c6d2e1" fontSize="12" textAnchor="middle">VM 2</text>
|
||||
<rect x="40" y="154" width="138" height="36" rx="6" fill="rgba(255,255,255,0.04)" stroke="#56c288" />
|
||||
<text x="109" y="176" fill="#c6d2e1" fontSize="12" textAnchor="middle">VM 3</text>
|
||||
<text x="440" y="26" fill="#c6d2e1" fontSize="12">Backup repositories (BR)</text>
|
||||
<rect x="440" y="34" width="120" height="44" rx="6" fill="rgba(255,255,255,0.04)" stroke="#e0a94a" />
|
||||
<text x="500" y="53" fill="#c6d2e1" fontSize="12" textAnchor="middle">BR 1</text>
|
||||
<text x="500" y="68" fill="#7a8699" fontSize="10" textAnchor="middle">500 GiB free</text>
|
||||
<rect x="440" y="94" width="180" height="52" rx="6" fill="rgba(255,255,255,0.04)" stroke="#e0a94a" />
|
||||
<text x="530" y="116" fill="#c6d2e1" fontSize="12" textAnchor="middle">BR 2</text>
|
||||
<text x="530" y="132" fill="#7a8699" fontSize="10" textAnchor="middle">2 TiB free (most)</text>
|
||||
<rect x="440" y="160" width="150" height="44" rx="6" fill="rgba(255,255,255,0.04)" stroke="#e0a94a" />
|
||||
<text x="515" y="179" fill="#c6d2e1" fontSize="12" textAnchor="middle">BR 3</text>
|
||||
<text x="515" y="194" fill="#7a8699" fontSize="10" textAnchor="middle">1.2 TiB free</text>
|
||||
<line x1="178" y1="72" x2="428" y2="112" stroke="#5ac8c8" strokeWidth="1.5" className="schema-flow" strokeDasharray="5 4" />
|
||||
<polygon points="437,113 427,109 428,119" fill="#5ac8c8" />
|
||||
<line x1="178" y1="122" x2="428" y2="178" stroke="#5ac8c8" strokeWidth="1.5" className="schema-flow" strokeDasharray="5 4" />
|
||||
<polygon points="437,180 427,175 428,185" fill="#5ac8c8" />
|
||||
<line x1="178" y1="172" x2="428" y2="60" stroke="#5ac8c8" strokeWidth="1.5" className="schema-flow" strokeDasharray="5 4" />
|
||||
<polygon points="437,56 427,55 429,65" fill="#5ac8c8" />
|
||||
<text x="308" y="46" fill="#7a8699" fontSize="10" textAnchor="middle">1 VM backup, 1 target</text>
|
||||
<text x="308" y="216" fill="#7a8699" fontSize="10" textAnchor="middle">default mode: every backup goes to every target</text>
|
||||
</svg>
|
||||
</Schema>
|
||||
|
||||
This is useful to:
|
||||
|
||||
@@ -21,7 +56,7 @@ Distributed backups are about **capacity spreading**, not redundancy. A VM's bac
|
||||
|
||||
## Setup
|
||||
|
||||
### Distributed backups (remotes)
|
||||
### Distributed backups (backup repositories) {#distributed-backups-remotes}
|
||||
|
||||
1. Go to **Backup → New backup job** or edit an existing one.
|
||||
2. Configure at least two backup repositories in the **Backup repositories** section.
|
||||
@@ -35,7 +70,7 @@ This applies to both **Full backup** and **Incremental (Delta) backup** job type
|
||||
2. Configure at least two storage repositories in the **Replication** section.
|
||||
3. In the **Advanced** settings, enable **Distribute replications across storage repositories**.
|
||||
|
||||
This applies to both **Disaster Recovery (DR)** and **Continuous Replication (CR)** job types.
|
||||
This applies to both **Full replication** and **Incremental replication** job types (the XO 5 interface still labels them **Disaster Recovery** and **Continuous Replication**).
|
||||
|
||||
## How target storage is selected
|
||||
|
||||
@@ -71,7 +106,7 @@ When a health check is scheduled, it runs only against the target that holds the
|
||||
| Limitation | Details |
|
||||
| ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Cannot mix storage classes | A pool cannot combine limited-capacity targets (NFS, Local, SMB) with unlimited targets (S3, Azure Blob). Xen Orchestra will throw an error at the start of the backup run. |
|
||||
| Minimum 2 targets required | The option is greyed out in the UI unless at least 2 remotes or SRs are selected. |
|
||||
| Not usable as mirror source | A job with distributed backup enabled cannot be used as the source for a [Mirror Backup](./xo5/mirror_backup.md) job. |
|
||||
| Minimum 2 targets required | The option is greyed out in the UI unless at least 2 BRs or SRs are selected. |
|
||||
| Not usable as mirror source | A job with distributed backup enabled cannot be used as the source for a [Mirror Backup](./mirror_backup.md) job. |
|
||||
| No duplication | Distributed mode and per-target duplication are mutually exclusive in the same job. Each VM backup lands on exactly one target. |
|
||||
| No cross-target restore dependency | Each VM backup is self-contained on its target. Restoring from one target does not require any other target to be available. |
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
# Full backups
|
||||
|
||||
A full backup exports the complete VM, all of its disks and its configuration, to a backup repository (BR) on every run. Each run produces a single, self-contained XVA archive: no chain, no dependencies between runs. The mental model is simple, and so is the restore, since any one archive is enough to bring the whole VM back.
|
||||
|
||||
:::note
|
||||
In the XO 5 interface, backup repositories are still labeled **Remotes**. A BR can be local to XOA, or an NFS or SMB share.
|
||||
:::
|
||||
|
||||
<Schema label="Full backup: snapshot the VM, export it as an XVA archive to the BR, rotate out the oldest archive" legend={[["#56c288", "VM"], ["#e0a94a", "XVA archive"], ["#ef6a5f", "Deleted by retention"]]} maxWidth="640px">
|
||||
<svg viewBox="0 0 640 240" role="img" aria-label="A VM on an XCP-ng host is snapshotted, exported as an XVA archive to the backup repository, then the snapshot is deleted; on the backup repository, dated archives accumulate and the oldest one is deleted by retention">
|
||||
<text x="32" y="38" fill="#8e83fe" fontSize="12">XCP-ng host</text>
|
||||
<rect x="24" y="46" width="216" height="130" rx="10" fill="none" stroke="rgba(255,255,255,0.22)" strokeDasharray="6 5" />
|
||||
<rect x="44" y="70" width="80" height="42" rx="6" fill="rgba(255,255,255,0.04)" stroke="#56c288" />
|
||||
<text x="84" y="95" fill="#c6d2e1" fontSize="12" textAnchor="middle">VM</text>
|
||||
<line x1="124" y1="91" x2="148" y2="91" stroke="rgba(255,255,255,0.28)" />
|
||||
<polygon points="152,91 145,87 145,95" fill="rgba(255,255,255,0.28)" />
|
||||
<rect x="152" y="70" width="74" height="42" rx="6" fill="rgba(255,255,255,0.04)" stroke="rgba(255,255,255,0.28)" />
|
||||
<text x="189" y="95" fill="#c6d2e1" fontSize="12" textAnchor="middle">Snapshot</text>
|
||||
<text x="189" y="130" fill="#7a8699" fontSize="10" textAnchor="middle">deleted after export</text>
|
||||
<line x1="226" y1="91" x2="336" y2="91" stroke="#e0a94a" strokeWidth="1.5" className="schema-flow" strokeDasharray="5 4" />
|
||||
<polygon points="344,91 335,86 335,96" fill="#e0a94a" />
|
||||
<text x="285" y="80" fill="#e0a94a" fontSize="11" textAnchor="middle">XVA export</text>
|
||||
<text x="356" y="52" fill="#c6d2e1" fontSize="12">Backup repository (BR)</text>
|
||||
<rect x="344" y="60" width="280" height="150" rx="10" fill="none" stroke="rgba(255,255,255,0.22)" strokeDasharray="6 5" />
|
||||
<g opacity="0.45">
|
||||
<rect x="364" y="100" width="54" height="56" rx="6" fill="rgba(255,255,255,0.04)" stroke="#ef6a5f" />
|
||||
<text x="391" y="125" fill="#c6d2e1" fontSize="11" textAnchor="middle">.xva</text>
|
||||
<text x="391" y="142" fill="#7a8699" fontSize="10" textAnchor="middle">day 1</text>
|
||||
</g>
|
||||
<text x="391" y="176" fill="#ef6a5f" fontSize="10" textAnchor="middle">rotated out</text>
|
||||
<rect x="430" y="100" width="54" height="56" rx="6" fill="rgba(255,255,255,0.04)" stroke="#e0a94a" />
|
||||
<text x="457" y="125" fill="#c6d2e1" fontSize="11" textAnchor="middle">.xva</text>
|
||||
<text x="457" y="142" fill="#7a8699" fontSize="10" textAnchor="middle">day 2</text>
|
||||
<rect x="496" y="100" width="54" height="56" rx="6" fill="rgba(255,255,255,0.04)" stroke="#e0a94a" />
|
||||
<text x="523" y="125" fill="#c6d2e1" fontSize="11" textAnchor="middle">.xva</text>
|
||||
<text x="523" y="142" fill="#7a8699" fontSize="10" textAnchor="middle">day 3</text>
|
||||
<rect x="562" y="100" width="54" height="56" rx="6" fill="rgba(255,255,255,0.04)" stroke="#e0a94a" />
|
||||
<text x="589" y="125" fill="#c6d2e1" fontSize="11" textAnchor="middle">.xva</text>
|
||||
<text x="589" y="142" fill="#7a8699" fontSize="10" textAnchor="middle">day 4</text>
|
||||
</svg>
|
||||
</Schema>
|
||||
|
||||
## How it works
|
||||
|
||||
1. **Snapshot first.** Xen Orchestra takes a snapshot of the VM, so the VM keeps running during the whole backup.
|
||||
2. **Export as XVA.** The snapshot is exported to the BR as an XVA archive. Only allocated blocks are transferred, not the full virtual size of the disks.
|
||||
3. **Snapshot cleanup.** Once the export is complete, the snapshot is deleted from the host.
|
||||
4. **Retention.** Each schedule has a retention setting: when the number of archives on the BR exceeds it, the oldest export is deleted.
|
||||
|
||||
### Compression
|
||||
|
||||
You can optionally compress the export in the backup job settings:
|
||||
|
||||
- **gzip**: works everywhere, slower.
|
||||
- **Zstd**: faster and more efficient, available when the host supports it (XCP-ng 8.1 and later).
|
||||
|
||||
Compression reduces the size of each archive on the BR at the cost of some CPU time on the host during the export.
|
||||
|
||||
## Restore
|
||||
|
||||
Every archive is self-contained, so any backup restores on its own: there is no chain to rebuild and no dependency on other backups. Pick the archive you want in the Restore view and import it on the pool and SR of your choice.
|
||||
|
||||
Since the result is a plain XVA file, it can also be imported anywhere, even without the backup job: download the file from the BR and use the **Import** menu in Xen Orchestra (or any other XVA import method) to recreate the VM.
|
||||
|
||||
## Backup without snapshot
|
||||
|
||||
In some cases you need to back up a VM without taking a snapshot first. The most common use case is a large VM stored on a small or thickly provisioned SR, where there simply isn't enough free space to hold a snapshot.
|
||||
|
||||
For this, open the advanced settings of your backup job and enable the **Offline backup** checkbox. The VM is then exported directly, without a snapshot.
|
||||
|
||||
:::warning
|
||||
With offline backup enabled, the VM is shut down for the whole duration of the export, then started again once it completes. Plan for this downtime when scheduling the job.
|
||||
:::
|
||||
|
||||
:::tip
|
||||
Full backups are storage and bandwidth hungry: each run transfers and stores a complete copy of the VM, with no deduplication between runs. In exchange, you get the simplest possible restore. To use less space and transfer less data, look at [incremental backups](xo5/incremental_backups.md), and see the [backup strategy guide](./backup_howto.md) to choose the right approach for your infrastructure.
|
||||
:::
|
||||
@@ -0,0 +1,100 @@
|
||||
---
|
||||
sidebar_label: Full replication (DR)
|
||||
---
|
||||
|
||||
# Full Replication
|
||||
|
||||
:::note
|
||||
**Full replication** is the current name of the job type formerly called **Disaster Recovery (DR)**. Both names describe the same thing, and you will still meet the old one: XO 6 labels this mode **Full replication**, while the XO 5 interface still labels it **Disaster Recovery**, and replicas keep a `Disaster Recovery` tag.
|
||||
|
||||
Don't confuse it with disaster recovery in the general sense (the practice of surviving the loss of a site), which is used throughout this page and which both replication modes serve.
|
||||
:::
|
||||
|
||||
Full replication keeps a complete, ready-to-boot copy of your VMs on another storage repository: in the same pool, in a different pool, even on another site. At each run, the whole VM is exported and streamed directly into the destination SR, so a fresh standby copy is always waiting there, powered off and protected against accidental start.
|
||||
|
||||
If the production side is lost (hosts, storage or the entire site), you start the replicas on the destination and you are back in business.
|
||||
|
||||
<Schema label="Full replication: a ready-to-boot copy of your production VMs, refreshed at each run" legend={[["#56c288", "Production VM"], ["#e0a94a", "Standby replica"], ["#6aabf0", "Xen Orchestra"], ["#8e83fe", "XCP-ng pool"]]} maxWidth="640px">
|
||||
<svg viewBox="0 0 640 270" role="img" aria-label="Xen Orchestra orchestrates a full replication job: the production VM is streamed to a DR pool where dated standby replicas are kept, with start blocked">
|
||||
<rect x="250" y="12" width="140" height="34" rx="6" fill="rgba(255,255,255,0.04)" stroke="#6aabf0" strokeWidth="1.5" />
|
||||
<text x="320" y="34" fill="#6aabf0" fontSize="13" textAnchor="middle" fontWeight="600">Xen Orchestra</text>
|
||||
|
||||
<line x1="285" y1="46" x2="150" y2="88" stroke="#6aabf0" strokeWidth="1" strokeDasharray="3 4" opacity="0.7" />
|
||||
<line x1="355" y1="46" x2="490" y2="88" stroke="#6aabf0" strokeWidth="1" strokeDasharray="3 4" opacity="0.7" />
|
||||
|
||||
<rect x="30" y="90" width="240" height="150" rx="8" fill="none" stroke="rgba(255,255,255,0.22)" strokeDasharray="6 5" />
|
||||
<text x="42" y="112" fill="#7a8699" fontSize="11">Production pool</text>
|
||||
|
||||
<rect x="50" y="124" width="200" height="98" rx="6" fill="rgba(255,255,255,0.04)" stroke="#8e83fe" strokeWidth="1.5" />
|
||||
<text x="60" y="143" fill="#8e83fe" fontSize="11">XCP-ng host</text>
|
||||
<rect x="70" y="156" width="160" height="46" rx="5" fill="rgba(255,255,255,0.04)" stroke="#56c288" strokeWidth="1.5" />
|
||||
<text x="150" y="176" fill="#56c288" fontSize="12" textAnchor="middle" fontWeight="600">VM "web01"</text>
|
||||
<text x="150" y="192" fill="#7a8699" fontSize="10" textAnchor="middle">running</text>
|
||||
|
||||
<line x1="270" y1="165" x2="368" y2="165" stroke="#56c288" strokeWidth="1.5" strokeDasharray="5 4" className="schema-flow" />
|
||||
<path d="M368 165 l-8 -4 v8 z" fill="#56c288" />
|
||||
<text x="320" y="152" fill="#c6d2e1" fontSize="10" textAnchor="middle">full export, streamed</text>
|
||||
|
||||
<rect x="370" y="90" width="240" height="150" rx="8" fill="none" stroke="rgba(255,255,255,0.22)" strokeDasharray="6 5" />
|
||||
<text x="382" y="112" fill="#7a8699" fontSize="11">DR pool (destination SR)</text>
|
||||
|
||||
<rect x="390" y="124" width="200" height="42" rx="5" fill="rgba(255,255,255,0.04)" stroke="#e0a94a" strokeWidth="1.5" />
|
||||
<text x="490" y="141" fill="#e0a94a" fontSize="11" textAnchor="middle" fontWeight="600">web01 - DR job - (20260801)</text>
|
||||
<text x="490" y="157" fill="#7a8699" fontSize="10" textAnchor="middle">halted, start blocked</text>
|
||||
|
||||
<rect x="390" y="176" width="200" height="42" rx="5" fill="rgba(255,255,255,0.04)" stroke="#e0a94a" strokeWidth="1" opacity="0.6" />
|
||||
<text x="490" y="193" fill="#e0a94a" fontSize="11" textAnchor="middle" opacity="0.7">web01 - DR job - (20260731)</text>
|
||||
<text x="490" y="209" fill="#7a8699" fontSize="10" textAnchor="middle" opacity="0.7">previous copy (retention: 2)</text>
|
||||
</svg>
|
||||
</Schema>
|
||||
|
||||
## Best practices
|
||||
|
||||
Disaster recovery is a vast topic and we strongly encourage you to read some literature about it. In short: define the maximum data loss you can accept (RPO) and the maximum downtime you can accept (RTO), then pick the replication frequency and infrastructure that match those numbers.
|
||||
|
||||
Full replication helps on the RTO side. There is no restore phase: the export and the import happen at the same time, in one streaming pass, with no intermediate file. [Streaming allows exporting and importing simultaneously](https://xen-orchestra.com/blog/vm-streaming-export-in-xenserver/), so as soon as a run completes, the replica sits on the destination SR, ready to boot.
|
||||
|
||||
**The goal is to have your DR VMs ready to boot on a dedicated host or site. A replica that boots is also living proof that the export worked.**
|
||||
|
||||
:::tip
|
||||
You don't have to test replicas by hand: the backup health check feature can automatically clone a replica, boot it and verify that the guest OS comes up, then discard the clone.
|
||||
:::
|
||||
|
||||
## Schedule a full replication job {#schedule-a-dr-task}
|
||||
|
||||
Planning a full replication job is very similar to planning a backup or a snapshot: create a new backup job, select the **Full replication** mode (still labelled **Disaster Recovery** in the XO 5 interface), pick the VMs, set a schedule, and choose the destination storage repository (any SR that XO can reach, on any connected pool).
|
||||
|
||||
Your replicated VMs will be visible "on the other side" as soon as the first run is done, named after the original VM, the job and the run date, for example: `web01 - DR job - (20260801T040000Z)`.
|
||||
|
||||
### Retention
|
||||
|
||||
The retention setting (historically called **depth**) is the number of copies kept per replicated VM. At each run, a new copy is imported and the oldest ones beyond the retention count are removed.
|
||||
|
||||
Replicas are identified by the backup metadata XO stores on them and by their blocked start operation. Each one also carries a `Disaster Recovery` tag (the tag value kept the former name of the job type), and HA is disabled on it (with an extra **HA disabled** tag when the source VM used HA). A replica you clone, or whose start block you remove, leaves the rotation: you can play with it without the fear of losing it at the next run.
|
||||
|
||||
:::warning
|
||||
Each retained copy is a full VM on the destination SR: a high retention number will lead to huge space usage. Size your DR storage accordingly.
|
||||
:::
|
||||
|
||||
## Network conflicts
|
||||
|
||||
If you boot a copy of your production VM while the original is still running, be careful: if they share the same static IP, you'll have trouble.
|
||||
|
||||
A good way to test a replica without this kind of problem is to clone it, remove the network interfaces from the clone, and boot it to check that the export went well.
|
||||
|
||||
## Protection against accidental start
|
||||
|
||||
:::warning
|
||||
For each replicated VM, XO adds **start** and **start on** as blocked operations. Even a replica with "Auto power on" enabled will not be started if your DR host reboots, and neither HA nor a distracted admin can boot it behind your back.
|
||||
:::
|
||||
|
||||
When you actually need to run a replica, you have two options, and both take it out of the retention rotation:
|
||||
|
||||
- **Clone it** (recommended): the clone is instant, boots normally, and the original replica stays in place for the next runs. This is what the block message itself suggests: "Start operation for this vm is blocked, clone it if you want to use it."
|
||||
- **Remove the blocked operation** on the replica (in the VM advanced tab) and start it directly. XO will no longer treat it as a replica, so the job won't delete it, and the next run will create a fresh copy alongside it.
|
||||
|
||||
## Failover
|
||||
|
||||
The day the production side is gone, the procedure is short: go to the DR pool, take the most recent replica of each VM, clone it or unblock it, fix the network settings if needed, and start it. Your services are back without waiting for any restore.
|
||||
|
||||
Because full replication re-sends the entire VM at each run, its practical RPO is limited by how long a full export takes. If you need more frequent runs and a lower RPO, look at [incremental replication](xo5/incremental_replication.md), which only transfers the changed blocks. To decide how replication fits with your other backup jobs, see the [backup strategy guide](./backup_howto.md).
|
||||
+66
-33
@@ -2,59 +2,92 @@
|
||||
|
||||
## General
|
||||
|
||||
| Acronym | Meaning | Definition |
|
||||
| Term | Meaning | Definition |
|
||||
| ------- | ----------------------- | ------------------------------------------------------------- |
|
||||
| **CPU** | Central Processing Unit | Processor. |
|
||||
| **OS** | Operating System | Software environment running on a **VM** or physical machine. |
|
||||
|
||||
## Core infrastructure
|
||||
|
||||
| Acronym | Meaning | Definition |
|
||||
| -------- | ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **VM** | Virtual Machine | A guest machine (OS + virtual hardware) managed by the pool. |
|
||||
| **SR** | Storage Repository | A storage container (local LVM, NFS, iSCSI, etc.) where **VDIs** live. |
|
||||
| **VDI** | Virtual Disk Image | A virtual disk object on an **SR** (root disk, data disk, ISO, snapshot disk, etc.).<br/>Not to be confused with **Virtual Desktop Infrastructure**. |
|
||||
| **VBD** | Virtual Block Device | The attachment that connects a **VDI** to a **VM** (device number, bootable flag, mode). |
|
||||
| **VIF** | Virtual Network Interface | A virtual NIC on a **VM**, connected to a **network**. |
|
||||
| **PIF** | Physical Interface | A physical NIC on a **host**, used for management, storage, or guest networks. |
|
||||
| **PBD** | Physical Block Device | Binds an **SR** to a **host** (how the host reaches that storage). |
|
||||
| **Host** | — | A hypervisor server (XCP-ng / XenServer node) in the pool. |
|
||||
| **Pool** | — | A set of **hosts** sharing storage and network configuration. |
|
||||
| Term | Meaning | Definition |
|
||||
| --------------- | ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **Dom0** | Control domain | The privileged Linux VM started with each **host**: it runs XAPI and the storage/network drivers. Its resources are shared by all operations on the host. |
|
||||
| **Host** | | A hypervisor server (XCP-ng / XenServer node) in the pool. |
|
||||
| **PBD** | Physical Block Device | Binds an **SR** to a **host** (how the host reaches that storage). |
|
||||
| **PIF** | Physical Interface | A physical NIC on a **host**, used for management, storage, or guest networks. |
|
||||
| **Pool** | | A set of **hosts** sharing storage and network configuration. |
|
||||
| **Pool master** | | The **host** that coordinates the **pool** and exposes its XAPI: XO always talks to the pool through its master. |
|
||||
| **SR** | Storage Repository | A storage container (local LVM, NFS, iSCSI, etc.) where **VDIs** live. Not to be confused with a backup repository (**BR**). |
|
||||
| **VBD** | Virtual Block Device | The attachment that connects a **VDI** to a **VM** (device number, bootable flag, mode). |
|
||||
| **VDI** | Virtual Disk Image | A virtual disk object on an **SR** (root disk, data disk, ISO, snapshot disk, etc.).<br/>Not to be confused with **Virtual Desktop Infrastructure**. |
|
||||
| **VIF** | Virtual Network Interface | A virtual NIC on a **VM**, connected to a **network**. |
|
||||
| **VM** | Virtual Machine | A guest machine (OS + virtual hardware) managed by the pool. |
|
||||
|
||||
## Virtualization modes & hardware
|
||||
|
||||
| Acronym | Meaning | Definition |
|
||||
| Term | Meaning | Definition |
|
||||
| ---------------- | ------------------------------- | --------------------------------------------------------------------------- |
|
||||
| **GPU** | Graphics Processing Unit | Physical graphics hardware on a **host**. |
|
||||
| **HVM** | Hardware Virtual Machine | Full hardware-emulated guest (typical for Windows and many Linux installs). |
|
||||
| **PGPU** | Physical GPU | A physical GPU as seen by XAPI (grouping / passthrough context). |
|
||||
| **PV** / **PVM** | Paravirtualization | Guest uses paravirtualized drivers/interfaces (legacy Linux style on Xen). |
|
||||
| **vCPU** | Virtual CPU | A virtual processor presented to the **VM**. |
|
||||
| **GPU** | Graphics Processing Unit | Physical graphics hardware on a **host**. |
|
||||
| **vGPU** | Virtual GPU | A virtual GPU slice assigned to a **VM**. |
|
||||
| **PGPU** | Physical GPU | A physical GPU as seen by XAPI (grouping / passthrough context). |
|
||||
| **VTPM** | Virtual Trusted Platform Module | Software TPM device exposed to a **VM** (e.g. Windows 11 / BitLocker). |
|
||||
|
||||
## Networking & storage
|
||||
|
||||
| Acronym | Meaning | Definition |
|
||||
| ---------- | ---------------------------------------- | ----------------------------------------------------------------------------- |
|
||||
| **MTU** | Maximum Transmission Unit | Largest Ethernet payload size on a link (e.g. jumbo frames). |
|
||||
| **VLAN** | Virtual LAN | Logical LAN segment; often tied to **PIF** tagging in XAPI. |
|
||||
| **SR-IOV** | Single Root I/O Virtualization | Passing a virtual function of a physical NIC to a **VM** for near-native I/O. |
|
||||
| **NFS** | Network File System | File-based **SR** backed by an NFS export. |
|
||||
| **iSCSI** | Internet Small Computer System Interface | Block **SR** backed by an iSCSI LUN. |
|
||||
| **LVM** | Logical Volume Manager | Local volume–style **SR** (e.g. on host disks). |
|
||||
| **ISO SR** | ISO Storage | **SR** type used to store `.iso` images for VM install media. |
|
||||
| Term | Meaning | Definition |
|
||||
| ----------------- | ---------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **iSCSI** | Internet Small Computer System Interface | Block **SR** backed by an iSCSI LUN. |
|
||||
| **ISO SR** | ISO Storage | **SR** type used to store `.iso` images for VM install media. |
|
||||
| **LVM** | Logical Volume Manager | Local volume-style **SR** (e.g. on host disks). |
|
||||
| **MTU** | Maximum Transmission Unit | Largest Ethernet payload size on a link (e.g. jumbo frames). |
|
||||
| **NBD** | Network Block Device | Protocol XO uses to read disk data directly from hosts, for faster [NBD-enabled backups](xo5/incremental_backups.md#nbd-enabled-backups). Required for incremental backups of QCOW2 disks. |
|
||||
| **NFS** | Network File System | File-based **SR** backed by an NFS export. |
|
||||
| **QCOW2** | QEMU Copy On Write v2 | Disk format lifting the 2 TiB **VHD** limit (up to 16 TiB per disk), generally available since XO 6.5 and recent XCP-ng releases. |
|
||||
| **SR-IOV** | Single Root I/O Virtualization | Passing a virtual function of a physical NIC to a **VM** for near-native I/O. |
|
||||
| **Traffic rules** | | Firewall-like rules applied to networks and **VIFs** through the [SDN controller](xo5/sdn_controller.md). |
|
||||
| **VHD** | Virtual Hard Disk | Historical disk and backup format of the platform, limited to 2 TiB per disk (see **QCOW2**). |
|
||||
| **VLAN** | Virtual LAN | Logical LAN segment; often tied to **PIF** tagging in XAPI. |
|
||||
| **XVA** | XenServer Virtual Appliance | Archive format for a complete VM export, used by [full backups](full_backups.md). |
|
||||
|
||||
## High availability & resilience
|
||||
## High availability & operations
|
||||
|
||||
| Acronym | Meaning | Definition |
|
||||
| ------- | ----------------- | ------------------------------------------------------------------------------ |
|
||||
| **HA** | High Availability | Pool feature to restart **VM**s elsewhere if a **host** fails (policy-driven). |
|
||||
| Term | Meaning | Definition |
|
||||
| ------- | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **HA** | High Availability | Pool feature to restart **VM**s elsewhere if a **host** fails (policy-driven). |
|
||||
| **RPU** | Rolling Pool Update | XO-orchestrated [update of a whole pool](xo5/manage_infrastructure.md#rolling-pool-updates-rpu): hosts are patched and rebooted one by one while VMs are live migrated, with no VM downtime. |
|
||||
|
||||
## Backup & replication
|
||||
|
||||
| Term | Meaning | Definition |
|
||||
| -------------------------- | ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **BR** | Backup Repository | Storage where XO writes backups (NFS, SMB, S3, local...), formerly called a "remote". See [backup repositories](xo5/backups.md#remotes). |
|
||||
| **CBT** | Changed Block Tracking | XCP-ng/XenServer feature letting XO [purge snapshot data](xo5/incremental_backups.md#purge-snapshot-data-cbt): the reference snapshot keeps only small metadata on the **SR**. |
|
||||
| **Coalesce** | | The storage process merging a VDI chain after a snapshot is deleted. Backups create and delete snapshots, so [coalesce health](xo5/backup_troubleshooting.md) directly affects them. |
|
||||
| **CR** | Incremental replication | Regularly replays deltas of a VM to an **SR** on another pool or host, formerly "continuous replication". See [incremental replication](xo5/incremental_replication.md). |
|
||||
| **DR** | Full replication | Regularly streams a full copy of a VM to an **SR** on another pool or host, formerly "disaster recovery". See [full replication](full_replication.md). |
|
||||
| **Full backup interval** | | Also called [key backup interval](xo5/incremental_backups.md#key-backup-interval): forces a periodic new full (key) backup in an incremental backup job. |
|
||||
| **GFS** | Grandfather-Father-Son | [Long-term retention strategy](xo5/backups.md#long-term-backup-retention-with-gfs-strategy) keeping daily, weekly, monthly and yearly backups. |
|
||||
| **Health check** | | Automatic [restore test](xo5/backups.md#backup-health-check) after a backup: XO boots the restored VM to verify the backup is actually usable. |
|
||||
| **Immutability** | | Protection making backups [unmodifiable for a configured duration](immutability.md), even by XO itself (ransomware protection). |
|
||||
| **Mirror backup** | | A [backup of your backups](mirror_backup.md): copies the archives of one **BR** to another, the key to 3-2-1 strategies. |
|
||||
| **[NOBAK]** | | Marker added to a **VDI** name to [exclude that disk](xo5/backups.md#exclude-disks) from all backup jobs. |
|
||||
| **Rolling snapshot** | | Scheduled [automatic snapshots](rolling_snapshots.md) with retention. Snapshots live on the same **SR** as the VM: not a real backup. |
|
||||
| **Sequence** | | [Chains backup schedules](xo5/backups.md#sequences) so they run one after the other instead of competing in parallel. |
|
||||
| **Smart backup** | | [Selects VMs by criteria](xo5/backups.md#smart-backup) (pool, tags, power state) resolved at job runtime, instead of a fixed VM list. |
|
||||
|
||||
## XCP-ng/Xen Orchestra-specific
|
||||
|
||||
| Acronym | Meaning | Definition |
|
||||
| ------------------- | ----------------------- | --------------------------------------------------------------------- |
|
||||
| **XO** | Xen Orchestra | The management UI/API stack (`xo-server`, `xo-web`, etc.). |
|
||||
| **XOA** | Xen Orchestra Appliance | Prebuilt VM image that runs **XO** as a packaged appliance. |
|
||||
| **XAPI** / **xapi** | Xen API | The management API and service on each **host** that **XO** talks to. |
|
||||
| Term | Meaning | Definition |
|
||||
| ------------------- | ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **Guest tools** | | Drivers and agent [installed inside a VM](https://xcp-ng.org/docs/guests.html): they report the IP address and metrics, and enable clean shutdown and migration. |
|
||||
| **V2V** | Virtual to Virtual | Built-in [migration tool](xo5/v2v-migration-guide.md) importing VMs directly from VMware/ESXi to XCP-ng. |
|
||||
| **XAPI** / **xapi** | Xen API | The management API and service on each **host** that **XO** talks to. |
|
||||
| **XCP-ng** | | The open source, Xen-based hypervisor [managed by XO](supported_hosts.md), developed by Vates alongside Xen Orchestra. |
|
||||
| **XO** | Xen Orchestra | The management UI/API stack (`xo-server`, `xo-web`, etc.). |
|
||||
| **XO 5** / **XO 6** | | The two web interfaces served by the same XO backend: XO 6 is the current default, XO 5 the previous generation. See [XO 6 vs XO 5](xo6/xo6vsxo5.md). |
|
||||
| **XO Lite** | | [Lightweight web UI](https://docs.vates.tech/products/add-ons/xo-lite) embedded in every XCP-ng host (8.3+): basic management and XOA deployment, no installation needed. |
|
||||
| **XO Proxy** | | [Component deployed close to remote infrastructure](xo5/proxy.md) to run backups locally, without streaming all data through the main XOA. |
|
||||
| **XOA** | Xen Orchestra Appliance | Prebuilt VM image that runs **XO** as a packaged appliance. |
|
||||
|
||||
@@ -0,0 +1,193 @@
|
||||
# Immutability
|
||||
|
||||
This page covers the immutability feature: what it is, why it matters, and how to set it up, whether you rely on object storage like Amazon S3 or on the native on-prem service.
|
||||
|
||||
## What is immutability? {#what-is-immutability}
|
||||
|
||||
In backup systems, immutability means that once a backup is created, it cannot be altered or deleted for a set period. This safeguards your backups against ransomware attacks, accidental deletion, or data corruption.
|
||||
|
||||
Here is how it works: you designate a backup repository (BR) that Xen Orchestra can write to, but cannot modify during the specified immutability period. Even if an attacker compromises XO, your backups remain untouched. The goal is to ensure that your backup data cannot be deleted, encrypted, or tampered with, unless someone with direct physical or root access to the storage intervenes.
|
||||
|
||||
Immutability can be implemented using external services like AWS S3 Object Lock, but Xen Orchestra also offers a native, on-premises solution that doesn't rely on third-party infrastructure.
|
||||
|
||||
## Why it matters {#why-it-matters}
|
||||
|
||||
Immutability guarantees that your backups stay secure and verifiable over time. It acts as a critical defense against ransomware, human mistakes, or intentional tampering. Additionally, it helps organizations comply with legal requirements by ensuring that data remains unaltered for mandatory retention periods. In essence, immutability turns your BR into a write-once, read-many (WORM) archive, protecting your data when it matters most.
|
||||
|
||||
## Immutability approaches {#immutability-approaches}
|
||||
|
||||
<a id="data-protection-modes"></a>
|
||||
|
||||
Immutability offers two distinct approaches to data protection, to meet different security and operational needs.
|
||||
|
||||
### Object storage {#object-storage}
|
||||
|
||||
The first approach leverages **object storage solutions** like Amazon S3, where immutability is enforced using features such as [Object Lock](https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lock.html). In this setup, the storage provider itself manages the retention period. Once enabled, backups created by XO cannot be deleted or modified until the lock expires, providing an extra layer of security.
|
||||
|
||||
### On-prem immutability {#on-prem-immmutability}
|
||||
|
||||
The second model is an **on-premises immutable repository**. It uses a lightweight package, installed on the BR host itself. This service monitors the repository and enforces immutability at the filesystem level, ensuring that XO cannot delete or overwrite existing backups before the end of the protection period.
|
||||
|
||||
The protection follows a **governance** model: the local root account of the BR host can still lift immutability. This is by design, so that an administrator with direct access to the storage always keeps control.
|
||||
|
||||
:::tip
|
||||
The immutability engine was rewritten in 2026 on native filesystem APIs. It uses roughly 7 times less memory and locks and unlocks files much faster on large repositories, so it scales to BRs holding many VMs and disks. The new engine shipped with the XO 6.3 release.
|
||||
:::
|
||||
|
||||
## Configuring on-prem immutability {#configuring-on-prem-immutability}
|
||||
|
||||
To set up immutability on your local infrastructure, follow these steps:
|
||||
|
||||
### 1. Install the required package {#1-install-the-required-package}
|
||||
|
||||
1. Make sure **Node.js** (version 20 or later) is installed on your BR machine
|
||||
2. Install the dedicated XO package globally:
|
||||
|
||||
<Terminal shell title="On the backup repository host">{`npm install -g @xen-orchestra/immutable-backups`}</Terminal>
|
||||
|
||||
The host must also meet these requirements:
|
||||
|
||||
- `chattr` and `lsattr` must be available on the system.
|
||||
- The underlying filesystem must support the immutable attribute (ext4, btrfs, and other common Linux filesystems do).
|
||||
- The service must run as root, or as a user with the `CAP_LINUX_IMMUTABLE` capability.
|
||||
|
||||
### 2. Configure the immutability settings {#2-configure-the-immutability-settings}
|
||||
|
||||
Create a configuration file at `/etc/xo-immutable-backups/config.toml`, with the following structure:
|
||||
|
||||
```toml
|
||||
liftEvery = "1h"
|
||||
|
||||
[remotes.remote1]
|
||||
root = "/mnt/ssd/vhdblock/"
|
||||
immutabilityDuration = "7d"
|
||||
```
|
||||
|
||||
#### Mandatory parameters {#mandatory-parameters}
|
||||
|
||||
- **`liftEvery`**: Defines how often the service checks for expired protection and lifts immutability (e.g., `1h` for every hour).
|
||||
- Per backup repository (the `remotes` key in the configuration file keeps the legacy name):
|
||||
- **`root`**: Absolute path to the directory where Xen Orchestra stores backups.
|
||||
- **`immutabilityDuration`**: Defines how long files remain protected from deletion (e.g., `7d` for 7 days). The minimum accepted value is `1d`.
|
||||
|
||||
You can declare as many `[remotes.<id>]` sections as you have repositories to protect on the host.
|
||||
|
||||
### 3. Start the service {#3-start-the-service}
|
||||
|
||||
Launch the `xo-immutable-remote` daemon and check its logs (with `journalctl`, for example) to confirm it is running correctly. For persistent operation, configure it as a `systemd` service so it starts at boot and keeps running: the daemon must stay up to protect new backups as they are written.
|
||||
|
||||
## How it works {#how-it-works}
|
||||
|
||||
Once active, any backups written by Xen Orchestra to this repository will be protected for the specified duration. Even if Xen Orchestra is compromised, the immutability configuration remains secure, as it is managed entirely on the backup host. On startup, the service verifies that the filesystem actually supports the immutable attribute, then writes a locked `immutability.json` marker at the repository root before it starts watching for new backups.
|
||||
|
||||
<Schema label="A backup's life on an immutable BR: written, locked for immutabilityDuration, lifted, then rotated out by retention" legend={[["#56c288", "written, still mutable"], ["#e0a94a", "locked backup"], ["#ef6a5f", "deleted by retention"], ["#5ac8c8", "liftEvery scan"]]} maxWidth="640px">
|
||||
<svg viewBox="0 0 640 200" role="img" aria-label="Timeline of a backup on an immutable repository: written unlocked, locked with chattr +i for the immutability duration, lifted back to mutable, then deleted by retention, with periodic liftEvery scans ticking along the time axis">
|
||||
<rect x="14" y="44" width="132" height="56" rx="8" fill="rgba(255,255,255,0.04)" stroke="#56c288" />
|
||||
<text x="80" y="68" fill="#c6d2e1" fontSize="12" textAnchor="middle">Written</text>
|
||||
<text x="80" y="86" fill="#7a8699" fontSize="10" textAnchor="middle">still unlocked</text>
|
||||
<line x1="149" y1="72" x2="164" y2="72" stroke="#e0a94a" strokeWidth="1.5" className="schema-flow" strokeDasharray="5 4" />
|
||||
<polygon points="171,72 164,68 164,76" fill="#e0a94a" />
|
||||
<rect x="174" y="44" width="132" height="56" rx="8" fill="rgba(255,255,255,0.04)" stroke="#e0a94a" />
|
||||
<rect x="206" y="63" width="11" height="9" rx="1.5" fill="none" stroke="#e0a94a" />
|
||||
<path d="M208.5 63 v-3 a3 3 0 0 1 6 0 v3" fill="none" stroke="#e0a94a" />
|
||||
<text x="248" y="72" fill="#c6d2e1" fontSize="12" textAnchor="middle">Locked</text>
|
||||
<text x="240" y="88" fill="#e0a94a" fontSize="10" textAnchor="middle">chattr +i</text>
|
||||
<line x1="174" y1="112" x2="306" y2="112" stroke="#e0a94a" strokeWidth="1.5" />
|
||||
<line x1="174" y1="107" x2="174" y2="117" stroke="#e0a94a" strokeWidth="1.5" />
|
||||
<line x1="306" y1="107" x2="306" y2="117" stroke="#e0a94a" strokeWidth="1.5" />
|
||||
<text x="240" y="128" fill="#e0a94a" fontSize="10" textAnchor="middle">immutabilityDuration</text>
|
||||
<line x1="309" y1="72" x2="324" y2="72" stroke="#7a8699" strokeWidth="1.5" className="schema-flow" strokeDasharray="5 4" />
|
||||
<polygon points="331,72 324,68 324,76" fill="#7a8699" />
|
||||
<rect x="334" y="44" width="132" height="56" rx="8" fill="rgba(255,255,255,0.04)" stroke="#7a8699" />
|
||||
<text x="400" y="68" fill="#c6d2e1" fontSize="12" textAnchor="middle">Lifted</text>
|
||||
<text x="400" y="86" fill="#7a8699" fontSize="10" textAnchor="middle">mutable again</text>
|
||||
<line x1="469" y1="72" x2="484" y2="72" stroke="#ef6a5f" strokeWidth="1.5" className="schema-flow" strokeDasharray="5 4" />
|
||||
<polygon points="491,72 484,68 484,76" fill="#ef6a5f" />
|
||||
<rect x="494" y="44" width="132" height="56" rx="8" fill="rgba(255,255,255,0.04)" stroke="#ef6a5f" />
|
||||
<text x="560" y="68" fill="#c6d2e1" fontSize="12" textAnchor="middle">Deleted</text>
|
||||
<text x="560" y="86" fill="#7a8699" fontSize="10" textAnchor="middle">by retention, later</text>
|
||||
<line x1="14" y1="156" x2="612" y2="156" stroke="#7a8699" strokeWidth="1" />
|
||||
<polygon points="620,156 611,152 611,160" fill="#7a8699" />
|
||||
<text x="600" y="146" fill="#7a8699" fontSize="10" textAnchor="end">time</text>
|
||||
<line x1="60" y1="150" x2="60" y2="162" stroke="#5ac8c8" strokeWidth="1.5" />
|
||||
<line x1="130" y1="150" x2="130" y2="162" stroke="#5ac8c8" strokeWidth="1.5" />
|
||||
<line x1="200" y1="150" x2="200" y2="162" stroke="#5ac8c8" strokeWidth="1.5" />
|
||||
<line x1="270" y1="150" x2="270" y2="162" stroke="#5ac8c8" strokeWidth="1.5" />
|
||||
<line x1="340" y1="150" x2="340" y2="162" stroke="#5ac8c8" strokeWidth="1.5" />
|
||||
<line x1="410" y1="150" x2="410" y2="162" stroke="#5ac8c8" strokeWidth="1.5" />
|
||||
<line x1="480" y1="150" x2="480" y2="162" stroke="#5ac8c8" strokeWidth="1.5" />
|
||||
<line x1="550" y1="150" x2="550" y2="162" stroke="#5ac8c8" strokeWidth="1.5" />
|
||||
<text x="312" y="182" fill="#5ac8c8" fontSize="10" textAnchor="middle">liftEvery scan: each tick lifts any expired lock</text>
|
||||
</svg>
|
||||
</Schema>
|
||||
|
||||
### Locking {#locking}
|
||||
|
||||
The service watches the backup directory tree in real time. When a backup completes, it waits until the final file (the metadata `.json`, always written last by XO) has been fully written to disk, then locks all files belonging to that backup run with the Linux `chattr +i` attribute. This prevents any process, including Xen Orchestra, from modifying or deleting them.
|
||||
|
||||
### Lifting {#lifting}
|
||||
|
||||
Protection is released automatically once the `immutabilityDuration` has elapsed. The service periodically (every `liftEvery` interval) scans the backup tree, computes the age of each backup from the datetime encoded in its filename, and removes the immutable attribute from any backup that has expired.
|
||||
|
||||
The expiry reference is the **datetime in the filename**, not the file's modification time. XO periodically rewrites metadata files for cache updates and reconciliation, which would reset `mtime` and indefinitely defer expiry if that were used instead.
|
||||
|
||||
On the first scan after the service starts, all files are checked unconditionally regardless of their current state, to catch anything that may have been missed (e.g. after a crash or restart).
|
||||
|
||||
## Working with immutable backups {#working-with-immutable-backups}
|
||||
|
||||
When setting up backup jobs in Xen Orchestra, select your configured immutable backup repository (whether it's an S3 bucket or an on-premises one). Define your retention and rotation policies as you normally would. Immutability ensures that existing backups cannot be deleted or altered before their protection period expires, while still allowing new backups to be added.
|
||||
|
||||
## Best practices {#best-practices}
|
||||
|
||||
### Only enable on stable, healthy backup jobs {#only-enable-on-stable-healthy-backup-jobs}
|
||||
|
||||
:::warning
|
||||
Immutability should only be enabled on backup jobs that are already running correctly and whose retention policy is fully settled. Nothing will be lost, but there will be a lot of EACCESS/EPERM errors in the backup log.
|
||||
:::
|
||||
|
||||
Immutability and retention are two independent mechanisms, and they can conflict if a backup job is not in a clean state:
|
||||
|
||||
- **Jobs that run more than once per schedule** (accidental duplicates, misconfigured triggers) will accumulate extra backups that XO cannot clean up while they are protected. Those backups count against storage but cannot be removed until their immutability duration expires.
|
||||
- **Backups in an incorrect or partial state** (failed mid-run, inconsistent chain) will be locked in place for the full immutability duration. The normal cleanup scripts cannot remove them, because any attempt to delete or overwrite a protected file raises a permission error (`EPERM`). Those errors are logged, but the files stay.
|
||||
- **Retention and immutability durations must be aligned.** If the immutability duration is longer than the retention window, XO will keep trying, and failing, to delete backups it considers expired. Set `immutabilityDuration` to be at most equal to the retention period, so that files are only released after XO has already rotated them out.
|
||||
- **Do not use Long Term Retention (LTR) with immutability.** LTR may select and remove intermediate backups from within a chain, for example to keep only one backup per month. If any of those intermediate files are still immutable, the deletion fails with `EPERM`. The backup chain is left in an inconsistent state that XO cannot repair until the immutability duration expires.
|
||||
- **A broken chain root blocks cleanup of the rest of the chain.** In delta backup chains, removing any backup requires starting from the root. If the chain root is in a bad state (missing, corrupted, or partially written) and the remaining files are immutable, the cleanup script cannot remove them either: it encounters `EPERM` on each attempt and leaves the orphaned files in place until they age out naturally.
|
||||
- **Disks are not protected during upload.** The immutable attribute is applied only after all disk images for a given backup run have been fully uploaded. During the upload window, those files can still be modified or deleted. Coupling immutability with XO's at-rest encryption reduces this exposure, since an encrypted file is useless even if tampered with before locking.
|
||||
|
||||
In short: make sure your backup jobs are stable and producing clean results before adding immutability. Applying it to a job that already has problems will lock those problems in place.
|
||||
|
||||
### Define a clear immutability policy {#define-a-clear-immutability-policy}
|
||||
|
||||
Align the **lock duration** with your data retention strategy, compliance requirements, and disaster recovery goals. Make sure the policy reflects both legal obligations and operational needs.
|
||||
|
||||
### Secure your encryption keys {#secure-your-encryption-keys}
|
||||
|
||||
Store encryption keys **separately** from your backup data.
|
||||
|
||||
:::warning
|
||||
Losing encryption keys will render backups **permanently unrecoverable**.
|
||||
:::
|
||||
|
||||
### Maintain independence from Xen Orchestra {#maintain-independence-from-xen-orchestra}
|
||||
|
||||
The immutability enforcement mechanism **must** operate independently of Xen Orchestra. This ensures that even if an attacker compromises XO, they **cannot** delete or alter existing backups.
|
||||
|
||||
### Monitor storage and test recovery {#monitor-storage-and-test-recovery}
|
||||
|
||||
- Track storage capacity closely, as immutability prevents immediate deletion of older backups.
|
||||
- Plan for additional space to accommodate protected backups over time.
|
||||
- Test recovery procedures regularly, to make sure immutability does not disrupt your ability to restore data when needed.
|
||||
|
||||
## Limitations {#limitations}
|
||||
|
||||
Cloud-based solutions such as S3 Object Lock depend on your provider's implementation; not all S3-compatible systems behave identically, so always test before production use. See the [supported object storage providers](./object-storage-support.md) list and its support tiers.
|
||||
|
||||
## Troubleshooting {#troubleshooting}
|
||||
|
||||
For troubleshooting, refer to the [package README on GitHub](https://github.com/vatesfr/xen-orchestra/blob/master/%40xen-orchestra/immutable-backups/README.md). It covers the most common situations: files still immutable after the duration expired, making a repository or a single VM mutable again for manual cleanup, changing the immutability duration, and why incremental backups are only marked as protected in XO once their whole chain is inside the immutability window.
|
||||
|
||||
## Conclusion {#conclusion}
|
||||
|
||||
Immutability adds a critical layer of protection to your backups in Xen Orchestra. Whether you use Amazon S3 or an on-premises repository, the core principle is simple: once a backup is created, you cannot change or delete it until the protection period expires.
|
||||
|
||||
By integrating immutability with strong encryption, proactive monitoring, and regular testing, you ensure that your backup data stays secure, reliable, and recoverable, even in the face of ransomware, human error, or malicious attacks. This approach transforms your backup strategy into a robust defense against data loss and corruption.
|
||||
@@ -0,0 +1,268 @@
|
||||
---
|
||||
sidebar_label: From the sources
|
||||
---
|
||||
|
||||
# Installation from the sources
|
||||
|
||||
Xen Orchestra is fully open source: you can build and run it yourself, for free, from its Git repository. This is the method of choice for home labs and evaluation on your own terms.
|
||||
|
||||
:::warning
|
||||
There is no professional support for this installation method, and no QA beyond what the community reports. For production, use [XOA](installation.md). Use the sources at your own risk!
|
||||
:::
|
||||
|
||||
What you are about to build: a single `xen-orchestra` checkout containing the server (`xo-server`) and the web interfaces, running as one Node.js process, with Redis as its database. Total time on a fresh VM: about fifteen minutes.
|
||||
|
||||
This procedure is validated against a fresh **Debian 12 x64** install and works nearly identically on any dpkg-based system. RPM-based systems are close too, since most dependencies come from npm rather than the OS.
|
||||
|
||||
## Requirements
|
||||
|
||||
### Node.js
|
||||
|
||||
Xen Orchestra requires [Node.js](https://nodejs.org/), **always the [latest LTS version](https://github.com/nodejs/release?tab=readme-ov-file#release-schedule)**. Check what you have:
|
||||
|
||||
<Terminal title="check your Node.js version">{`
|
||||
node -v
|
||||
v22.11.0
|
||||
`}</Terminal>
|
||||
|
||||
If it is missing or older than the current LTS, install it following [the Node.js instructions](https://nodejs.org/en/download/package-manager/).
|
||||
|
||||
### Yarn
|
||||
|
||||
The build uses the [Yarn](https://classic.yarnpkg.com/en/docs/install) package manager: install it the same way, from its official instructions.
|
||||
|
||||
### System packages {#packages-and-prerequisites}
|
||||
|
||||
A few system packages are needed (Redis is the database XO uses; the rest covers builds and the various remote types):
|
||||
|
||||
<Terminal shell title="Debian / Ubuntu — install the dependencies">{`
|
||||
apt-get install build-essential redis-server libpng-dev git python3-minimal libvhdi-utils lvm2 cifs-utils nfs-common ntfs-3g openssl libfuse2
|
||||
`}</Terminal>
|
||||
|
||||
On Fedora and older CentOS-like systems:
|
||||
|
||||
<Terminal shell title="Fedora / CentOS-like — install the dependencies">{`
|
||||
dnf install redis libpng-devel git lvm2 cifs-utils make automake gcc gcc-c++ nfs-utils ntfs-3g openssl
|
||||
`}</Terminal>
|
||||
|
||||
:::note RHEL-family 10 and newer
|
||||
Since release 10 of CentOS Stream, AlmaLinux and Rocky Linux, Redis is replaced by **Valkey**, a drop-in compatible fork; the `valkey-compat-redis` package (in the `devel` repository) provides the usual Redis commands, and `ntfs-3g` moved to EPEL:
|
||||
|
||||
<Terminal shell title="RHEL-family 10 — install the dependencies">{`
|
||||
dnf install epel-release
|
||||
dnf config-manager --enable devel
|
||||
dnf install valkey valkey-compat-redis libpng-devel git lvm2 cifs-utils make automake gcc gcc-c++ nfs-utils ntfs-3g openssl
|
||||
`}</Terminal>
|
||||
:::
|
||||
|
||||
### Check that Redis is running {#make-sure-redis-is-running}
|
||||
|
||||
<Terminal shell title="start Redis (or valkey.service if you installed Valkey)">{`
|
||||
systemctl restart redis.service
|
||||
`}</Terminal>
|
||||
|
||||
<Terminal title="make sure it answers">{`
|
||||
redis-cli ping
|
||||
PONG
|
||||
`}</Terminal>
|
||||
|
||||
## Get the code and build {#fetching-the-code}
|
||||
|
||||
Everything lives in one repository. Ideally, work as a **non-root user** (see [the sudo section](#sudo) for NFS mounts):
|
||||
|
||||
<Terminal shell title="fetch the code">{`
|
||||
git clone -b master https://github.com/vatesfr/xen-orchestra
|
||||
`}</Terminal>
|
||||
|
||||
Install the dependencies and build, as the same user that will run Xen Orchestra (a few minutes):
|
||||
|
||||
<Terminal shell title="build">{`
|
||||
cd xen-orchestra
|
||||
yarn
|
||||
yarn build
|
||||
`}</Terminal>
|
||||
|
||||
## Configure
|
||||
|
||||
Create the `xo-server` configuration file from the provided sample:
|
||||
|
||||
<Terminal shell title="create the configuration">{`
|
||||
cd packages/xo-server
|
||||
mkdir -p ~/.config/xo-server
|
||||
cp sample.config.toml ~/.config/xo-server/config.toml
|
||||
`}</Terminal>
|
||||
|
||||
Two things you may want to change in that file:
|
||||
|
||||
- **Ports**: defaults are 80 and 443. A non-root user cannot bind ports below 1024, so pick 1024 or higher in that case.
|
||||
- If you install `xo-server` as a system-wide service, place the file in `/etc/xo-server/config.toml` instead.
|
||||
|
||||
## First run {#running-xo}
|
||||
|
||||
From the `xen-orchestra/packages/xo-server` directory:
|
||||
|
||||
<Terminal title="start Xen Orchestra">{`
|
||||
yarn start
|
||||
WebServer listening on localhost:80
|
||||
[INFO] Default user: "[email protected]" with password "admin"
|
||||
`}</Terminal>
|
||||
|
||||
Open the server's IP in your browser, log in with `[email protected]` / `admin`, and change that password right away. That's it!
|
||||
|
||||
## Run it at boot {#always-running}
|
||||
|
||||
The clean way is a **systemd service**. Create `/etc/systemd/system/xo-server.service` with the following (adapt the two paths to your Node and your checkout):
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=XO Server
|
||||
After=network-online.target
|
||||
|
||||
[Service]
|
||||
Environment="DEBUG=xo:main"
|
||||
Restart=always
|
||||
SyslogIdentifier=xo-server
|
||||
|
||||
# Adapt the paths to your Node binary and your xen-orchestra checkout!
|
||||
ExecStart=/usr/bin/node /home/username/xen-orchestra/packages/xo-server/dist/cli.mjs
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
<Terminal shell title="enable and start the service">{`
|
||||
systemctl daemon-reload
|
||||
systemctl enable --now xo-server
|
||||
`}</Terminal>
|
||||
|
||||
<Terminal shell title="check it">{`
|
||||
systemctl status xo-server
|
||||
`}</Terminal>
|
||||
|
||||
:::warning Security
|
||||
With this unit, `xo-server` runs as `root`: make sure the checkout files are not editable by other users, or they become an attack vector.
|
||||
:::
|
||||
|
||||
<details>
|
||||
<summary>Alternative: forever / forever-service (legacy)</summary>
|
||||
|
||||
The historical way, using the unmaintained [forever](https://github.com/foreversd/forever) tool. Prefer systemd for any new setup.
|
||||
|
||||
<Terminal shell title="run with forever, as the user owning XO">{`
|
||||
yarn global add forever
|
||||
forever start dist/cli.mjs
|
||||
`}</Terminal>
|
||||
|
||||
Or install it as a service (run as root, from the xo-server directory, adapting path and username):
|
||||
|
||||
<Terminal shell title="install as a service with forever-service">{`
|
||||
yarn global add forever forever-service
|
||||
cd /home/username/xen-orchestra/packages/xo-server/
|
||||
forever-service install orchestra -r username -s dist/cli.mjs
|
||||
`}</Terminal>
|
||||
|
||||
Manage it with `service orchestra start` / `status`, and remove it with `forever-service delete orchestra`.
|
||||
|
||||
</details>
|
||||
|
||||
## Updating
|
||||
|
||||
From your `xen-orchestra` directory:
|
||||
|
||||
<Terminal shell title="update to the latest master">{`
|
||||
git checkout . # careful: this discards any local changes!
|
||||
git pull --ff-only
|
||||
yarn
|
||||
yarn build
|
||||
`}</Terminal>
|
||||
|
||||
Then restart Xen Orchestra if it was running. Always update to the latest `master` before reporting an issue: it is the only supported state for source installations.
|
||||
|
||||
## Build troubleshooting {#troubleshooting}
|
||||
|
||||
If the build fails, reset the dependencies and try again, from the `xen-orchestra` directory:
|
||||
|
||||
<Terminal shell title="clean rebuild">{`
|
||||
rm -rf node_modules
|
||||
yarn
|
||||
yarn build
|
||||
`}</Terminal>
|
||||
|
||||
## sudo {#sudo}
|
||||
|
||||
Running `xo-server` as a non-root user requires `sudo` for mounting NFS remotes. Enable it near the end of the configuration file:
|
||||
|
||||
```toml
|
||||
useSudo = true
|
||||
```
|
||||
|
||||
Then allow your user to run the mount commands without a password prompt, in your `sudo` configuration:
|
||||
|
||||
```
|
||||
username ALL=(root)NOPASSWD: /bin/mount, /bin/umount, /bin/findmnt
|
||||
```
|
||||
|
||||
## About the banner
|
||||
|
||||
Running from the sources shows a banner reminding you that this version comes without support or QA. As a home user, simply ignore it: it is aimed at companies, for which the supported [XOA](installation.md) is the right vehicle, and whose subscriptions are what funds the development of XO and [XCP-ng](https://xcp-ng.org) (every euro earned goes directly back into these open source projects). Removing the banner in redistributed scripts hurts that loop, and keeping it is one simple way to support the project.
|
||||
|
||||
You can also support XO by spreading the word, reporting bugs, and contributing code.
|
||||
|
||||
:::tip
|
||||
Exceptional individual contributors are awarded a free XOA Premium subscription. If you think you deserve it, contact us!
|
||||
:::
|
||||
|
||||
## FreeBSD and OpenBSD
|
||||
|
||||
:::note Community territory
|
||||
We do not test Xen Orchestra on FreeBSD or OpenBSD at all: everything below comes purely from community feedback, and may lag behind reality. If you run XO on these systems and want to help maintain these instructions, [contact us](community.md): we would be happy to have more testers and maintainers for these targets.
|
||||
:::
|
||||
|
||||
### FreeBSD
|
||||
|
||||
<Terminal shell title="install the packages">{`
|
||||
pkg install gmake redis python git npm node autoconf
|
||||
npm update -g
|
||||
pkg install jpeg-turbo optipng gifsicle # saves npm from building them itself
|
||||
`}</Terminal>
|
||||
|
||||
FreeBSD ships CLANG rather than GCC:
|
||||
|
||||
<Terminal shell title="point g++ at clang++">{`
|
||||
ln -s /usr/bin/clang++ /usr/local/bin/g++
|
||||
`}</Terminal>
|
||||
|
||||
Enable Redis at boot by adding `redis_enable="YES"` to `/etc/rc.conf`, and start it now:
|
||||
|
||||
<Terminal shell title="start Redis">{`
|
||||
service redis start
|
||||
`}</Terminal>
|
||||
|
||||
### OpenBSD
|
||||
|
||||
<Terminal shell title="install the packages">{`
|
||||
pkg_add gmake redis python--%2.7 git node autoconf yarn
|
||||
pkg_add jpeg optipng gifsicle
|
||||
`}</Terminal>
|
||||
|
||||
OpenBSD ships CLANG rather than GCC:
|
||||
|
||||
<Terminal shell title="use clang for the build">{`
|
||||
export CC=/usr/bin/clang
|
||||
export CXX=/usr/bin/clang++
|
||||
`}</Terminal>
|
||||
|
||||
Raise the open-files limit, make `node` visible to `npm`, and point Yarn at Python if needed:
|
||||
|
||||
<Terminal shell title="build environment tweaks">{`
|
||||
ulimit -n 10240
|
||||
ln -s /usr/local/bin/node /tmp/node
|
||||
PYTHON=/usr/local/bin/python2 yarn
|
||||
`}</Terminal>
|
||||
|
||||
Enable and start Redis:
|
||||
|
||||
<Terminal shell title="Redis at boot">{`
|
||||
rcctl enable redis
|
||||
rcctl start redis
|
||||
`}</Terminal>
|
||||
@@ -0,0 +1,143 @@
|
||||
# Installation
|
||||
|
||||
Deploying Xen Orchestra takes a few minutes: you deploy the **Xen Orchestra Appliance (XOA)**, a pre-built VM with everything configured, directly on one of your hosts. Nothing is installed on the hosts themselves, and nothing changes in your infrastructure: XOA is just another VM.
|
||||
|
||||
This page walks the whole journey: deploy, first login, registration, and the first console and network settings. If you prefer building from the sources instead, the community method has [its own page](install-from-sources.md).
|
||||
|
||||
## Deploy XOA {#xoa}
|
||||
|
||||
Log in to your account and use the deploy form on [vates.tech/deploy](https://vates.tech/deploy/):
|
||||
|
||||
<UiShot light="/img/xoa/deploy-form.png" alt="The XOA deploy form: everything runs between your browser and your host" url="https://vates.tech/deploy/" />
|
||||
|
||||
:::tip
|
||||
All the deploy code runs within your browser: nothing is sent to our servers. Your credentials and host details never leave your network.
|
||||
:::
|
||||
|
||||
The wizard walks four steps: **Connect** (your host address and credentials), **Configure** (storage and network for the appliance, DHCP or static), **Secure**, and **Deploy**. It then imports and starts the VM on the storage repository you picked:
|
||||
|
||||
<UiDetail src="/img/xoa/deploy-wizard.png" alt="The four deploy steps: connect to your primary host, configure, secure, deploy" width={620} />
|
||||
|
||||
## XOA specifications and sizing {#xoa-vm-specifications}
|
||||
|
||||
By default, the deployed VM is configured with:
|
||||
|
||||
- 2 vCPUs
|
||||
- 2 GiB of RAM
|
||||
- 20 GiB of free SR space (2 GiB on thin provisioned SR)
|
||||
|
||||
### Sizing your XOA {#sizing}
|
||||
|
||||
The right size depends on what you ask of it:
|
||||
|
||||
| Usage | vCPUs | RAM |
|
||||
| ----------------------------------------------------------- | ------ | ---------------------- |
|
||||
| A few pools, no backup jobs, no V2V | 2 | 2 GiB (strict minimum) |
|
||||
| Enterprise usage (backup jobs, V2V, more pools) | 4 | 4 GiB minimum |
|
||||
| Working at scale (large infrastructure, heavy backup load) | 4 to 8 | 8 GiB |
|
||||
|
||||
A few rules of thumb:
|
||||
|
||||
- **2 GiB and 2 vCPUs is the strict minimum**, fine for a few pools without backups or V2V.
|
||||
- As soon as you use XOA in an enterprise context, **4 GiB and 4 vCPUs** should be your baseline.
|
||||
- **8 GiB** is better when working at scale, and **8 vCPUs** can bring extra speed when you run a lot of backups (transfers and compression are parallel workloads).
|
||||
- You can always give more, but **measure** afterwards to check the improvement is real before going further.
|
||||
|
||||
## First login
|
||||
|
||||
Once the VM is running, open its IP address in your browser. If you did not set a fixed IP or are unsure which one it got:
|
||||
|
||||
<Terminal shell title="host — find the XOA IP">{`xe vm-list params=name-label,networks | grep -A 1 XOA`}</Terminal>
|
||||
|
||||
or check your router's DHCP leases for an `xoa` entry.
|
||||
|
||||
- Default web UI credentials: `[email protected]` / `admin`. Change them right after the first login: create a new admin account and remove this one. If you ever lose your password, you can [reset the configuration](troubleshooting.md#reset-the-configuration) to get the default credentials back.
|
||||
- Console and SSH have **no default password**: you set one during deployment, or later [from the host](#first-console-connection).
|
||||
|
||||
## Register and start your trial {#registration}
|
||||
|
||||
**The first thing to do** in your new XOA is to register it, from the Updates view: registration is what enables updates and the free 30-day trial. Use your [account.vates.tech](https://account.vates.tech) credentials:
|
||||
|
||||
<UiDetail src="/img/xoa/register.png" alt="Registering the appliance from the Updates view" width={520} />
|
||||
|
||||
:::tip
|
||||
Appliance images are not rebuilt every month, unlike Xen Orchestra itself: right after deploying, an update is usually available. Register, update, then explore.
|
||||
:::
|
||||
|
||||
To try everything XO can do, start the trial from the same view ("Start Trial", the green button), and click Upgrade: your appliance runs the complete **Premium** feature set for 30 days.
|
||||
|
||||
<UiDetail src="/img/xoa/start-trial.png" alt="Starting the 30-day Premium trial" width={520} />
|
||||
|
||||
When the trial ends, the appliance keeps working and simply returns to the Free feature set: you lose no data and no configuration. For system-level settings of the appliance (firewall, NTP, service restart), see [the XOA appliance settings](configuration.md#xoa-appliance).
|
||||
|
||||
## Alternative deployment methods {#alternative-install}
|
||||
|
||||
Use these when the web deploy form is not an option (no Internet access from the browser, automation, restricted environments).
|
||||
|
||||
### Via XO Lite
|
||||
|
||||
If your hosts run XCP-ng 8.3 or later, [XO Lite](https://docs.vates.tech/products/add-ons/xo-lite) is already waiting on every host: open `https://your-host-ip` in a browser, log in with the host `root` credentials, and use its **Deploy XOA** action. Nothing to download, nothing to install: XO Lite is served directly by the host.
|
||||
|
||||
### Via a bash script
|
||||
|
||||
From your XCP-ng or XenServer host:
|
||||
|
||||
<Terminal shell title="host — deploy XOA with the script">{`bash -c "$(wget --no-verbose -O- https://xoa.io/deploy)"`}</Terminal>
|
||||
|
||||
The script asks for the IP configuration (DHCP by default, or a fixed address with netmask, gateway and DNS) and imports the XOA VM into your default storage repository. It writes nothing else on the host, and you can move the VM elsewhere afterwards.
|
||||
|
||||
:::note
|
||||
On old XCP-ng or XenServer versions, HTTPS may fail with an SSL error (`SSL23_GET_SERVER_HELLO`). You can fall back to plain HTTP: `bash -c "$(wget --no-verbose -O- http://xoa.io/deploy)"`.
|
||||
:::
|
||||
|
||||
### Via a manual XVA download
|
||||
|
||||
Download the XOA as an XVA file from [xen-orchestra.com](https://xen-orchestra.com), then import it from your host CLI (or from XO Lite):
|
||||
|
||||
<Terminal shell title="host — import the appliance">{`xe vm-import filename=xoa_unified.xva`}</Terminal>
|
||||
|
||||
<Terminal shell title="host — start it">{`xe vm-start vm="XOA"`}</Terminal>
|
||||
|
||||
To set a fixed IP address before the first start:
|
||||
|
||||
<Terminal shell title="host — optional static IP">{`xe vm-param-set uuid="$uuid" \\
|
||||
xenstore-data:vm-data/ip="$ip" \\
|
||||
xenstore-data:vm-data/netmask="$netmask" \\
|
||||
xenstore-data:vm-data/gateway="$gateway"`}</Terminal>
|
||||
|
||||
And to replace the default DNS server:
|
||||
|
||||
<Terminal shell title="host — optional custom DNS">{`xe vm-param-set uuid="$uuid" xenstore-data:vm-data/dns="$dns"`}</Terminal>
|
||||
|
||||
## First console connection
|
||||
|
||||
If you deployed with the [web form](https://vates.tech/deploy/), you already chose the `xoa` user password. Otherwise, **there is no default password, for security reasons**: set one from your host, using the XOA VM UUID (found with `xe vm-list`):
|
||||
|
||||
<Terminal shell title="host — set the xoa user password">{`xe vm-param-set uuid=<UUID> xenstore-data:vm-data/system-account-xoa-password='MyPassW0rd!'`}</Terminal>
|
||||
|
||||
Reboot the VM to apply, then connect with `ssh xoa@<XOA IP>`.
|
||||
|
||||
Once connected, `sudo -s` gives you a root shell, so you do not have to prefix every administration command:
|
||||
|
||||
<Terminal title="xoa — a root shell">{`sudo -s
|
||||
[sudo] password for xoa:`}</Terminal>
|
||||
|
||||
## Network configuration
|
||||
|
||||
XOA uses **DHCP** by default. To switch to a static address, run `xoa network static` and answer the prompts; `xoa network dhcp` goes back to DHCP:
|
||||
|
||||
<Terminal title="xoa — static IP configuration">{`xoa network static
|
||||
? Static IP for this machine 192.168.100.120/24
|
||||
? Gateway 192.168.100.254
|
||||
? IP of the DNS server 192.168.100.254`}</Terminal>
|
||||
|
||||
Xen Orchestra is then available at `https://your-vm-ip`.
|
||||
|
||||
To configure another interface than the default one, pass its name as an argument (`xoa network static enX1`, `xoa network dhcp enX1`). To add more IP addresses on an already configured interface, use the `--add` flag:
|
||||
|
||||
<Terminal title="xoa — add a secondary IP address">{`xoa network static --add
|
||||
? Static IP for this machine 192.168.200.120/24`}</Terminal>
|
||||
|
||||
## From the sources {#from-the-sources}
|
||||
|
||||
Xen Orchestra is fully open source and can also be built from its sources, without professional support. This community installation method has [its own dedicated page](install-from-sources.md).
|
||||
+182
-6
@@ -4,14 +4,190 @@ slug: /
|
||||
|
||||
# Xen Orchestra in a nutshell
|
||||
|
||||

|
||||
Xen Orchestra (XO) is the complete solution to **visualize, manage, back up and delegate** your XCP-ng (or XenServer) infrastructure: any number of pools, on any site, from one place. **No agent** is required for it to work. Together with [XCP-ng](https://docs.xcp-ng.org/), it forms [Vates VMS](https://docs.vates.tech/), the fully open source virtualization stack built and supported by [Vates](https://vates.tech).
|
||||
|
||||
## Introduction
|
||||
<UiShot dark="/img/xo6/lab-dashboard.webp" alt="Xen Orchestra 6: one dashboard for every pool, host and VM you manage" url="https://myxoa.domain.tld/v6/#/dashboard" />
|
||||
|
||||
XO (Xen Orchestra) is a complete solution to visualize, manage, backup and delegate your XCP-ng (or XenServer) infrastructure. **No agent** is required for it to work.
|
||||
Everything goes through XO, and everything that talks to your infrastructure talks to XO:
|
||||
|
||||
It provides a web UI, a CLI and a REST API, while also getting a Terraform provider among other connectors/plugins.
|
||||
<Schema label="Xen Orchestra at the center of your infrastructure" legend={[["#6aabf0", "XO"], ["#8e83fe", "XCP-ng"], ["#56c288", "VMs"], ["#e0a94a", "backup"], ["#5ac8c8", "V2V"]]} maxWidth="760px">
|
||||
<svg viewBox="0 0 680 380" role="img" aria-label="Users and automation tools drive Xen Orchestra, which manages any number of XCP-ng pools, streams backups to a repository, keeps disaster recovery copies and imports VMware VMs with V2V">
|
||||
{/* Who talks to XO: humans and automation. */}
|
||||
<a href="/xo6/gettingstarted" aria-label="The XO 6 web interface">
|
||||
<rect x="20" y="12" width="170" height="62" rx="8" fill="rgba(255,255,255,0.04)" stroke="rgba(255,255,255,0.28)"/>
|
||||
<text x="105" y="37" fontSize="13.5" fill="#c6d2e1" textAnchor="middle">Your team</text>
|
||||
<text x="105" y="56" fontSize="11.5" fill="#7a8699" textAnchor="middle">Web UI · any browser</text>
|
||||
</a>
|
||||
<a href="/automation/terraform-provider" aria-label="Automation and DevOps tools">
|
||||
<rect x="205" y="12" width="265" height="62" rx="8" fill="rgba(255,255,255,0.04)" stroke="rgba(255,255,255,0.28)"/>
|
||||
<text x="337" y="37" fontSize="13.5" fill="#c6d2e1" textAnchor="middle">Automation</text>
|
||||
<text x="337" y="56" fontSize="11.5" fill="#7a8699" textAnchor="middle">REST API · CLI · Terraform · Ansible</text>
|
||||
</a>
|
||||
<a href="/backup" aria-label="Backups">
|
||||
<rect x="485" y="12" width="175" height="62" rx="8" fill="rgba(224,169,74,0.10)" stroke="#e0a94a"/>
|
||||
<text x="572" y="37" fontSize="13.5" fill="#e0a94a" textAnchor="middle">Backup repository</text>
|
||||
<text x="572" y="56" fontSize="11.5" fill="#7a8699" textAnchor="middle">S3 · NFS · SMB · Azure</text>
|
||||
</a>
|
||||
<g className="schema-flow" stroke="#7a8699" strokeWidth="1.4" strokeDasharray="5 4">
|
||||
<line x1="105" y1="74" x2="240" y2="115"/>
|
||||
<line x1="337" y1="74" x2="337" y2="115"/>
|
||||
</g>
|
||||
<line className="schema-flow" x1="450" y1="115" x2="560" y2="74" stroke="#e0a94a" strokeWidth="1.6" strokeDasharray="5 4"/>
|
||||
{/* XO, the middleware. The band below the text stays empty so the
|
||||
backup packet can cross the box. */}
|
||||
<rect x="190" y="115" width="300" height="76" rx="8" fill="rgba(106,171,240,0.12)" stroke="#6aabf0"/>
|
||||
<text x="340" y="139" fontSize="17" fill="#6aabf0" textAnchor="middle">Xen Orchestra</text>
|
||||
<text x="340" y="156" fontSize="11.5" fill="#7a8699" textAnchor="middle">backup · DR · V2V · load balancing</text>
|
||||
<text x="340" y="172" fontSize="11.5" fill="#7a8699" textAnchor="middle">Web UI · REST API · CLI</text>
|
||||
{/* VMware cluster: the V2V source, on a 36s cycle. It appears, XO
|
||||
grows a connection wire to it, the VM is converted (the teal copy
|
||||
rides through XO and lands green in Pool 1 while the original
|
||||
fades), then the empty cluster and its wire disappear: XO connects
|
||||
to VMware only for the migration. */}
|
||||
<a className="schema-live" href="/xo5/v2v-migration-guide" aria-label="Migrate from VMware with V2V" opacity="0">
|
||||
<animate attributeName="opacity" dur="36s" repeatCount="indefinite"
|
||||
values="0;0;1;1;0;0" keyTimes="0;0.111;0.125;0.41;0.45;1"/>
|
||||
<rect x="20" y="115" width="140" height="62" rx="8" fill="none" stroke="rgba(255,255,255,0.22)" strokeDasharray="6 5"/>
|
||||
<text x="30" y="132" fontSize="12.5" fill="#7a8699">VMware cluster</text>
|
||||
<g className="schema-live" opacity="1">
|
||||
<animate attributeName="opacity" dur="36s" repeatCount="indefinite"
|
||||
values="1;1;0;0" keyTimes="0;0.347;0.36;1"/>
|
||||
<rect x="70" y="141" width="40" height="24" rx="4" fill="rgba(90,200,200,0.14)" stroke="#5ac8c8"/>
|
||||
<text x="90" y="157" fontSize="12.5" fill="#5ac8c8" textAnchor="middle">VM</text>
|
||||
</g>
|
||||
</a>
|
||||
{/* The connection only exists while the cluster does: the teal wire
|
||||
grows out of XO toward it, and vanishes with it. */}
|
||||
<line className="schema-flow schema-transient" x1="160" y1="146" x2="190" y2="146" stroke="#5ac8c8" strokeWidth="1.4" strokeDasharray="5 4" opacity="0">
|
||||
<animate attributeName="x1" dur="36s" repeatCount="indefinite"
|
||||
values="190;190;160;160" keyTimes="0;0.139;0.18;1"/>
|
||||
<animate attributeName="opacity" dur="36s" repeatCount="indefinite"
|
||||
values="0;0;1;1;0;0" keyTimes="0;0.139;0.15;0.41;0.45;1"/>
|
||||
</line>
|
||||
<a href="/full_replication" aria-label="Full replication">
|
||||
<rect x="520" y="115" width="140" height="62" rx="8" fill="none" stroke="rgba(255,255,255,0.22)" strokeDasharray="6 5"/>
|
||||
<text x="530" y="132" fontSize="12.5" fill="#7a8699">DR site</text>
|
||||
<g opacity="0.45">
|
||||
<rect x="570" y="141" width="40" height="24" rx="4" fill="rgba(86,194,136,0.14)" stroke="#56c288"/>
|
||||
<text x="590" y="157" fontSize="12.5" fill="#56c288" textAnchor="middle">VM</text>
|
||||
</g>
|
||||
</a>
|
||||
<line className="schema-flow" x1="490" y1="146" x2="520" y2="146" stroke="#6aabf0" strokeWidth="1.6" strokeDasharray="5 4"/>
|
||||
{/* Pools: XO manages any number of them, anywhere. */}
|
||||
<g className="schema-flow" stroke="#6aabf0" strokeWidth="1.6" strokeDasharray="5 4">
|
||||
<line x1="280" y1="191" x2="170" y2="235"/>
|
||||
<line x1="400" y1="191" x2="510" y2="235"/>
|
||||
</g>
|
||||
<line className="schema-flow" x1="340" y1="191" x2="340" y2="235" stroke="#6aabf0" strokeOpacity="0.7" strokeWidth="1.6" strokeDasharray="5 4"/>
|
||||
<rect x="328" y="235" width="24" height="136" rx="8" fill="none" stroke="rgba(255,255,255,0.22)" strokeDasharray="6 5"/>
|
||||
<text x="340" y="310" fontSize="18" fill="#7a8699" textAnchor="middle">…</text>
|
||||
<g fill="none" stroke="rgba(255,255,255,0.22)" strokeDasharray="6 5">
|
||||
<rect x="20" y="235" width="300" height="136" rx="10"/>
|
||||
<rect x="360" y="235" width="300" height="136" rx="10"/>
|
||||
</g>
|
||||
<text x="36" y="260" fontSize="14.5" fill="#7a8699">Pool 1 · Paris</text>
|
||||
<text x="376" y="260" fontSize="14.5" fill="#7a8699">Pool 12 · Amsterdam</text>
|
||||
<g fill="rgba(86,194,136,0.14)" stroke="#56c288" strokeOpacity="0.8">
|
||||
<rect x="48" y="288" width="40" height="24" rx="4"/>
|
||||
<rect x="96" y="288" width="40" height="24" rx="4"/>
|
||||
<rect x="388" y="288" width="40" height="24" rx="4"/>
|
||||
<rect x="436" y="288" width="40" height="24" rx="4"/>
|
||||
</g>
|
||||
<g fontSize="12.5" fill="#56c288" textAnchor="middle">
|
||||
<text x="68" y="304">VM</text><text x="116" y="304">VM</text>
|
||||
<text x="408" y="304">VM</text><text x="456" y="304">VM</text>
|
||||
</g>
|
||||
{/* Live migration, across pools and sites. */}
|
||||
<g className="schema-hop" style={{'--schema-hop-x': '388px', '--schema-hop-dur': '16s', '--schema-hop-delay': '-7s'}}>
|
||||
<rect x="144" y="288" width="40" height="24" rx="4" fill="rgba(86,194,136,0.14)" stroke="#56c288" strokeOpacity="0.8"/>
|
||||
<text x="164" y="304" fontSize="12.5" fill="#56c288" textAnchor="middle">VM</text>
|
||||
</g>
|
||||
{/* The converted VM: lands green in Pool 1, displaced by the next
|
||||
arrival one cycle later (park cycle aligned with the flight). */}
|
||||
<g className="schema-park" style={{'--schema-park-dur': '36s', '--schema-park-delay': '12.5s'}}>
|
||||
<rect x="192" y="288" width="40" height="24" rx="4" fill="rgba(86,194,136,0.14)" stroke="#56c288" strokeOpacity="0.8"/>
|
||||
<text x="212" y="304" fontSize="12.5" fill="#56c288" textAnchor="middle">VM</text>
|
||||
</g>
|
||||
<g fill="rgba(142,131,254,0.14)" stroke="#8e83fe" strokeOpacity="0.85">
|
||||
<rect x="36" y="326" width="268" height="26" rx="5"/>
|
||||
<rect x="376" y="326" width="268" height="26" rx="5"/>
|
||||
</g>
|
||||
<g fontSize="13.5" fill="#8e83fe" textAnchor="middle">
|
||||
<text x="170" y="344">XCP-ng hosts</text>
|
||||
<text x="510" y="344">XCP-ng hosts</text>
|
||||
</g>
|
||||
{/* A backup rides from a VM through XO to the repository. It hovers a
|
||||
few pixels above its VM before departing. */}
|
||||
<g className="schema-packet" opacity="0">
|
||||
<rect x="-31" y="-8" width="62" height="16" rx="4" fill="rgba(224,169,74,0.18)" stroke="#e0a94a"/>
|
||||
<text x="0" y="3.5" fontSize="10" fill="#e0a94a" textAnchor="middle">VM backup</text>
|
||||
<animateMotion begin="2s" dur="15s" repeatCount="indefinite" calcMode="linear"
|
||||
path="M456,274 L510,235 L400,191 L445,181 L455,120 L560,66"
|
||||
keyPoints="0;0;1;1" keyTimes="0;0.12;0.34;1"/>
|
||||
<animate attributeName="opacity" begin="2s" dur="15s" repeatCount="indefinite"
|
||||
values="0;1;1;0;0" keyTimes="0;0.05;0.31;0.35;1"/>
|
||||
</g>
|
||||
{/* DR sync: a dimmed 1:1 copy of the leftmost Pool 1 VM is born on
|
||||
the original (which never moves), rides the management line up
|
||||
through XO's band, exits right along the DR wire and fades into
|
||||
the parked standby. */}
|
||||
<g className="schema-packet" opacity="0">
|
||||
<rect x="-20" y="-12" width="40" height="24" rx="4" fill="rgba(86,194,136,0.14)" stroke="#56c288"/>
|
||||
<text x="0" y="4" fontSize="12.5" fill="#56c288" textAnchor="middle">VM</text>
|
||||
<animateMotion dur="36s" repeatCount="indefinite" calcMode="linear"
|
||||
path="M68,300 L170,235 L280,191 L330,183 L450,183 L490,157 L590,153"
|
||||
keyPoints="0;0;1;1" keyTimes="0;0.68;0.76;1"/>
|
||||
<animate attributeName="opacity" dur="36s" repeatCount="indefinite"
|
||||
values="0;0;0.5;0.5;0;0" keyTimes="0;0.667;0.68;0.74;0.765;1"/>
|
||||
</g>
|
||||
{/* The V2V conversion in flight: teal on departure, green on arrival
|
||||
(the parked VM above takes over at landing). */}
|
||||
<g className="schema-packet" opacity="0">
|
||||
<rect x="-20" y="-12" width="40" height="24" rx="4" fill="rgba(90,200,200,0.14)" stroke="#5ac8c8"/>
|
||||
<text x="0" y="4" fontSize="12.5" fill="#5ac8c8" textAnchor="middle">VM</text>
|
||||
<animateMotion dur="36s" repeatCount="indefinite" calcMode="linear"
|
||||
path="M90,153 L160,147 L230,183 L280,191 L170,235 L212,300"
|
||||
keyPoints="0;0;1;1" keyTimes="0;0.25;0.347;1"/>
|
||||
<animate attributeName="opacity" dur="36s" repeatCount="indefinite"
|
||||
values="0;0;0.9;0.9;0;0" keyTimes="0;0.25;0.26;0.34;0.35;1"/>
|
||||
</g>
|
||||
</svg>
|
||||
</Schema>
|
||||
|
||||
## Quick start
|
||||
## Start here
|
||||
|
||||
Log in to your account and use the deploy form available from [Vates website](https://vates.tech/deploy/)
|
||||
<CardGrid>
|
||||
<LinkCard title="Deploy Xen Orchestra" href="/installation">Get the turnkey appliance (XOA) running in minutes, or install from the sources.</LinkCard>
|
||||
<LinkCard title="Discover XO 6" href="/xo6/gettingstarted">Tour the new interface: tree view, dashboards, consoles.</LinkCard>
|
||||
<LinkCard title="Set up backups" href="/backup">Rolling snapshots, incremental backups, replication and more.</LinkCard>
|
||||
<LinkCard title="Migrate from VMware" href="/xo5/v2v-migration-guide">Import your ESXi VMs directly into your pools with V2V.</LinkCard>
|
||||
<LinkCard title="Automate everything" href="/automation/restapi">REST API, CLI, Terraform, Ansible, Pulumi and more.</LinkCard>
|
||||
<LinkCard title="Get support" href="/support">Professional support by the Vates team, or community help.</LinkCard>
|
||||
</CardGrid>
|
||||
|
||||
## What XO does for you
|
||||
|
||||
- **Administration**: complete control of your pools, hosts, VMs, storage and networks, from a [modern web interface](xo6/gettingstarted.md) or from XO 5.
|
||||
- **Backup and disaster recovery**: rolling snapshots, full and incremental backups, replication, mirroring and immutability, toward S3, NFS, SMB or Azure targets. See [Backups](xo6/backups.md).
|
||||
- **Migration from VMware**: [V2V](xo5/v2v-migration-guide.md) imports your ESXi VMs directly into your pools.
|
||||
- **Automation**: a [REST API](automation/restapi.md), a CLI, and first-class providers for [Terraform](automation/terraform-provider.md), [Ansible](automation/ansible.md), [Pulumi](automation/pulumi-provider.md), [Packer](automation/packer-provider.md) and [PowerShell](automation/powershell-module.md), plus [Kubernetes cluster recipes](automation/kubernetes.md).
|
||||
- **Delegation**: users, groups and [RBAC](rbac.md) to give each team exactly the access it needs.
|
||||
- **Scale**: one XO manages any number of pools on any number of sites, over LAN or WAN.
|
||||
|
||||
## XO in the Vates VMS stack
|
||||
|
||||
This documentation covers Xen Orchestra itself. Its two siblings cover the rest of the stack, and the three work as one set:
|
||||
|
||||
| You are looking for | Where to go |
|
||||
| -------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- |
|
||||
| Xen Orchestra: the interfaces, the backup engine, the REST API and automation, XOA | **You are here** |
|
||||
| XCP-ng: installing and operating the hypervisor, hosts, storage and networks, hardware compatibility | [docs.xcp-ng.org](https://docs.xcp-ng.org/) |
|
||||
| The stack as a whole: getting started end to end, bundles and licensing, compatibility ecosystem, security advisories, product roadmap | [docs.vates.tech](https://docs.vates.tech/) |
|
||||
|
||||
:::tip One search for the three documentations
|
||||
The search bar at the top covers docs.xen-orchestra.com, docs.xcp-ng.org and docs.vates.tech at once, with results grouped by product. Wherever a topic lives, searching from here will find it.
|
||||
:::
|
||||
|
||||
## Two interfaces, one product
|
||||
|
||||
Xen Orchestra currently ships two web interfaces on the same server and the same data: **XO 6**, the new default interface, and **XO 5**, which remains available for the operations XO 6 does not cover yet. Read [XO 6 vs. XO 5](xo6/xo6vsxo5.md) to see what lives where.
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
---
|
||||
slug: backup
|
||||
---
|
||||
|
||||
# Introduction to backups
|
||||
|
||||
Xen Orchestra ships a complete, **agentless** backup engine for your whole infrastructure: nothing to install inside your VMs, everything managed from one place, from quick rolling snapshots to cross-site disaster recovery.
|
||||
|
||||
New to backups in XO? Start with these two:
|
||||
|
||||
<CardGrid>
|
||||
<LinkCard title="Backup strategy guide" href="/backup_howto">Which backup type for which need: design your protection plan before clicking anything.</LinkCard>
|
||||
<LinkCard title="Backups in XO 6" href="/xo6/backups">Follow backup health from the new dashboards: job status, per-VM protection, restore points.</LinkCard>
|
||||
</CardGrid>
|
||||
|
||||
## Pick your backup type
|
||||
|
||||
- **[Rolling snapshots](rolling_snapshots.md)**: scheduled snapshots kept on a rotation. No repository needed, instant restore points.
|
||||
- **[Full backups](full_backups.md)**: a complete export of the VM to a backup repository (BR), every time. Simple and self-contained.
|
||||
- **[Incremental backups](xo5/incremental_backups.md)**: after an initial full, only the changed blocks are sent. Fast, compact, deduplicable.
|
||||
- **[Full replication](full_replication.md)** (formerly Disaster Recovery, DR): a ready-to-boot copy of your VMs, kept up to date on another host or SR.
|
||||
- **[Incremental replication](xo5/incremental_replication.md)** (formerly Continuous Replication, CR): the same standby copy, sending only the deltas.
|
||||
- **[Mirror backups](mirror_backup.md)**: replicate a whole backup repository to another one, the key to [3-2-1 strategies](backup_howto.md#long-term-retention-strategy).
|
||||
- **[Metadata backup](xo5/metadata_backup.md)**: the XO configuration and pool metadata themselves, so the orchestrator is never your single point of failure.
|
||||
|
||||
:::tip
|
||||
You don't have to pick VMs one by one: **[smart backup](xo5/backups.md#smart-backup)** selects them dynamically by pool, tag or power state, so new VMs are protected automatically.
|
||||
:::
|
||||
|
||||
## Going further
|
||||
|
||||
<CardGrid>
|
||||
<LinkCard title="Features and settings" href="/xo5/backups">Encryption, schedules, smart backup, backup repositories, restore (including file-level), retention, health checks: the full reference.</LinkCard>
|
||||
<LinkCard title="Backup proxies" href="/xo5/proxy">Offload backup traffic to proxies, closer to your pools and repositories.</LinkCard>
|
||||
<LinkCard title="Distributed backups" href="/distributed_backups">Combine proxies and mirrors for multi-site, resilient backup architectures.</LinkCard>
|
||||
<LinkCard title="Immutability" href="/immutability">Make your backup repositories tamper-proof against ransomware.</LinkCard>
|
||||
<LinkCard title="Backup reports" href="/xo5/backup_reports">Get notified after each run: email, XMPP and more.</LinkCard>
|
||||
<LinkCard title="Troubleshooting" href="/xo5/backup_troubleshooting">Interrupted runs, full SRs, slow transfers: the usual suspects and their fixes.</LinkCard>
|
||||
</CardGrid>
|
||||
|
||||
:::tip
|
||||
Sizing question? The [retention calculator](calculator.md) estimates how much storage a given schedule and retention will consume.
|
||||
:::
|
||||
|
||||
## See it in action
|
||||
|
||||
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/FfUqIwT8KzI?si=kTvxIFhPjv-8Iwri" title="Administer and backup your VM infrastructure the easiest way" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
|
||||
+26
-10
@@ -2,25 +2,41 @@
|
||||
slug: project
|
||||
---
|
||||
|
||||
# About the Xen Orchestra project
|
||||
# About
|
||||
|
||||
Xen Orchestra is an Open Source project created by [Olivier Lambert](https://www.linkedin.com/in/olivier-lambert-22316b26/) with a long story behind it.
|
||||
Xen Orchestra is an Open Source project with more than 15 years of history. Originated by [Olivier Lambert](https://www.linkedin.com/in/olivier-lambert-22316b26/), co-founder of [Vates](https://vates.tech), it quickly became a collective effort: today a dedicated team of around 20 people designs, develops and maintains it full time at Vates, alongside a worldwide community of users and contributors.
|
||||
|
||||
## Initial idea
|
||||
## Milestones {#initial-idea}
|
||||
|
||||
The idea of Xen Orchestra was originally born in 2009, see the original announcement on [Xen User mailing list](https://lists.xenproject.org/archives/html/xen-users/2009-09/msg00537.html). It worked on Xen and `xend` (now deprecated).
|
||||
- **2009**: the original idea is announced on the [Xen user mailing list](https://lists.xenproject.org/archives/html/xen-users/2009-09/msg00537.html). This first incarnation targets Xen and `xend` (both now long deprecated).
|
||||
- **December 2012**: the project is rebooted on top of XAPI for XenServer, with the first commit of the current codebase.
|
||||
- **February 2014**: XO 3.0, the first release of the rebooted project.
|
||||
- **May 2015**: XO 4.0, with a fully redesigned web interface.
|
||||
- **June 2016**: XO 5.0, the first release of the generation still known today as [XO 5](xo6/xo6vsxo5.md).
|
||||
- **2018**: after Citrix closed a lot of XenServer features, Olivier Lambert launched [XCP-ng](https://xcp-ng.org), a fully open source fork of XenServer: successful Kickstarter campaign in early 2018, first release (XCP-ng 7.4) on March 31, 2018.
|
||||
- **2022**: work starts on [XO Lite](https://docs.vates.tech/products/add-ons/xo-lite), the lightweight web UI embedded in every XCP-ng host.
|
||||
- **January 2023**: first preview of [V2V](xo5/v2v-migration-guide.md), the built-in tool to migrate VMs directly from VMware to XCP-ng.
|
||||
- **November 2025**: XO 5.113, the last feature release of the 5.x series.
|
||||
- **December 2025**: XO 6.0, the first official release of the new [XO 6](xo6/gettingstarted.md) interface, becomes the default UI.
|
||||
- **February 2026**: XO 6.2 introduces [distributed backups](distributed_backups.md), spreading backup data across multiple backup repositories (BR).
|
||||
- **March 2026**: XO 6.3 brings symmetrical replication and a rewritten immutable backup engine.
|
||||
- **May 2026**: XO 6.5 delivers QCOW2 general availability (disks beyond the 2 TiB VHD limit), bidirectional replication and traffic rules on networks and VIFs.
|
||||
- **July 2026**: XO 6.7 focuses on Rolling Pool Update reliability and keeps expanding the XO 6 workflows.
|
||||
|
||||
## XO reboot for XCP-ng/XenServer
|
||||
### The reboot story {#xo-reboot-for-xcp-ngxenserver}
|
||||
|
||||
Project was rebooted in the end of 2012, and "pushed" thanks to Lars Kurth. It's also a commercial project since 2016, and now with a team of 6 people dedicated fulltime.
|
||||
|
||||
Here is a video in LinuxCon 2013 telling the story:
|
||||
The 2012 reboot was "pushed" thanks to Lars Kurth, and Xen Orchestra has also been a commercial project backed by a dedicated team since 2016. Here is a video from LinuxCon 2013 telling the story:
|
||||
|
||||
<iframe width="560" height="315" src="https://www.youtube.com/embed/TT2Q5l2K54k" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
||||
|
||||
## XCP-ng
|
||||
## Part of the Vates VMS stack {#xcp-ng}
|
||||
|
||||
After Citrix decided to close at lot of XenServer features, Olivier Lambert decided to fork the virtualization platform. That's why Xen Orchestra and XCP-ng team are so close. Feel free to learn more on [https://xcp-ng.org](https://xcp-ng.org).
|
||||
Xen Orchestra is the management and backup layer of the [Vates Virtualization Management Stack (VMS)](https://vates.tech), alongside the [XCP-ng](https://xcp-ng.org) hypervisor. Both are developed by [Vates](https://vates.tech) and are fully open source: professional support for the whole platform is delivered through the stack, from the hypervisor to the management layer. See the [Vates documentation](https://docs.vates.tech) for the full picture.
|
||||
|
||||
## Feedback and issues
|
||||
|
||||
- **Product feedback and feature requests**: [feedback.vates.tech](https://feedback.vates.tech/)
|
||||
- **Bugs**: tracked on the [GitHub repository](https://github.com/vatesfr/xen-orchestra/issues), but it is always better to first drop a message on the forum, in the [Xen Orchestra section](https://xcp-ng.org/forum/category/12/xen-orchestra)
|
||||
|
||||
## Team and contributors
|
||||
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
---
|
||||
slug: support
|
||||
---
|
||||
|
||||
# Support and licensing
|
||||
|
||||
:::tip
|
||||
To run a self-diagnosis or open a secure support tunnel from your XOA, see [Troubleshooting](troubleshooting.md#still-stuck).
|
||||
:::
|
||||
|
||||
Xen Orchestra runs in a controlled and tested environment thanks to XOA (the [Xen Orchestra virtual Appliance](https://vates.tech/deploy/)). **This is the only way to get pro support**. Any account with a registered XOA can open tickets from its personal space on [account.vates.tech](https://account.vates.tech).
|
||||
|
||||
Professional support is delivered through the [Vates VMS bundles](https://docs.vates.tech/pricing-licencing/vms-bundle-overview/), which cover your whole stack: XCP-ng, Xen Orchestra and the support itself. Higher tiers include faster ticket response times and cover more features: see [the plans and response times](https://vates.tech/pricing-and-support/).
|
||||
|
||||
## XOA Free support
|
||||
|
||||
With the free version of the Xen Orchestra Appliance (XOA free), **you can open private support tickets** and we will do our best to assist you. However, this support is limited and is not guaranteed in regards to response times or resolutions offered.
|
||||
|
||||
## Community support
|
||||
|
||||
While Xen Orchestra is free and Open Source software, supporting and developing it takes a lot of effort. If you are considering using Xen Orchestra in production, please subscribe to one of our [professional support plans](https://vates.tech/pricing-and-support/).
|
||||
|
||||
Read more in the [dedicated section for community support](community.md).
|
||||
|
||||
## Licensing and purchase {#licensing}
|
||||
|
||||
Everything commercial lives in one central place, the [Vates docs](https://docs.vates.tech/), so it is always current:
|
||||
|
||||
- [Vates VMS bundle overview](https://docs.vates.tech/pricing-licencing/vms-bundle-overview/): what each bundle includes.
|
||||
- [Pricing and available add-ons](https://docs.vates.tech/pricing-licencing/pricing-addons/): including XO Proxy and other add-ons.
|
||||
- [Applying Xen Orchestra licenses](https://docs.vates.tech/pricing-licencing/applying-xo-licences/): bind a license to your XOA.
|
||||
- [Migrating licenses](https://docs.vates.tech/pricing-licencing/migrating-licences/): move a license to another appliance.
|
||||
- [Account management](https://docs.vates.tech/pricing-licencing/account-management/): invoices, payment methods, and your personal space.
|
||||
- [Contact and quote requests](https://docs.vates.tech/pricing-licencing/contact-quote-requests/): for purchase departments and quotes.
|
||||
@@ -1,5 +1,5 @@
|
||||
# Licenses
|
||||
|
||||
XO is an Open Source project released under the [AGPL v3](http://www.gnu.org/licenses/agpl-3.0-standalone.html) license, contributions are therefore very welcome.
|
||||
XO is an Open Source project: its components are released mostly under the [AGPL v3](http://www.gnu.org/licenses/agpl-3.0-standalone.html) license, with some generic libraries under the [ISC](https://www.isc.org/licenses/) license (see [LICENSE.md](https://github.com/vatesfr/xen-orchestra/blob/master/LICENSE.md) in the repository). Contributions are therefore very welcome.
|
||||
|
||||

|
||||
<img src="/img/agplv3-logo.svg" alt="AGPL v3 logo" width="180" />
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
---
|
||||
sidebar_label: Replace your XOA
|
||||
---
|
||||
|
||||
# Replace your XOA
|
||||
|
||||
Replacing your appliance with a fresh one takes three steps: deploy the new XOA, export the configuration of the old one, and import it into the new one. Everything follows: users, ACLs, connected pools, backup jobs, remotes and settings.
|
||||
|
||||
## Why replace it?
|
||||
|
||||
- **To get a fresh appliance, not just fresh XO code.** The [updater](updater.md) keeps Xen Orchestra itself current, but the appliance around it (Debian system, kernel, Node.js runtime) ages like any VM. Redeploying gives you the latest base system in one move.
|
||||
- **Because you lost it.** XOA failure is not an emergency: your hosts and VMs keep running without it, and a fresh appliance plus a configuration import puts you back exactly where you were, in minutes. Many people do not realize how disposable the appliance is: treat it as cattle, not as a pet.
|
||||
- **To move it**: new pool, new storage, new site. Deploy where you want it, import, delete the old one.
|
||||
|
||||
:::tip
|
||||
Export your configuration regularly (and after any significant change): it is a small file, and it turns any XOA loss into a ten-minute non-event.
|
||||
:::
|
||||
|
||||
## Deploy the new appliance
|
||||
|
||||
Deploy a new XOA next to the old one, as described in [Installation](installation.md).
|
||||
|
||||
## Export the configuration
|
||||
|
||||
On the old appliance, go to **Settings → Config** and click **Download current config**:
|
||||
|
||||
<UiDetail src="/img/xoa/config-export.png" alt="Exporting the configuration, optionally encrypted with a passphrase" width={520} />
|
||||
|
||||
You can set a passphrase to encrypt the exported file.
|
||||
|
||||
## Import the configuration
|
||||
|
||||
On the new appliance, go to **Settings → Config** and drag and drop the exported file into the **Import** section:
|
||||
|
||||
<UiDetail src="/img/xoa/config-import.png" alt="Importing the configuration on the new appliance" width={520} />
|
||||
|
||||
Click to import: a modal asks for the passphrase (leave it empty if you did not set one). Once the import finishes, the new appliance takes over with your complete configuration.
|
||||
|
||||
:::note Advanced users
|
||||
Manual edits made to `/etc/xo-server/config.toml` on the old appliance are not part of the exported configuration: re-apply them on the new one (see [Configuration](configuration.md)).
|
||||
:::
|
||||
@@ -0,0 +1,282 @@
|
||||
---
|
||||
sidebar_label: Mirror backups
|
||||
---
|
||||
|
||||
# Mirror Backups
|
||||
|
||||
The goal is to replicate a backup from one backup repository (BR, formerly called remote) to another. For instance, you make your backup to in-house NFS storage, and then replicate to bigger, slower and cheaper storage with a longer retention.
|
||||
|
||||
The source and destination can have different settings for encryption, VHD storage mode, retention, or compression.
|
||||
|
||||
A mirror backup is a backup of your backups: XO reads the archives already stored on the source BR and copies the new ones to the destination BR. The VM and the hosts are never involved in the transfer:
|
||||
|
||||
<Schema label="A mirror backup copies existing archives from one BR to another: the VM is only exported once by its normal backup job, then XO mirrors the archives to a bigger, slower, cheaper BR with a longer retention" legend={[["#e0a94a", "backup archive"], ["#5ac8c8", "mirror transfer"], ["#8e83fe", "Xen Orchestra"]]} maxWidth="640px">
|
||||
<svg viewBox="0 0 640 260" role="img" aria-label="A VM is exported by its normal backup job to a source backup repository holding archives B, C and D; Xen Orchestra orchestrates a mirror transfer that copies the new archives to a bigger destination backup repository with a longer retention, holding A, B, C and D; the VM and hosts are not involved in the mirror transfer">
|
||||
<rect x="272" y="16" width="96" height="32" rx="6" fill="rgba(255,255,255,0.04)" stroke="#8e83fe" />
|
||||
<text x="320" y="36" fill="#c6d2e1" fontSize="11" textAnchor="middle">Xen Orchestra</text>
|
||||
<line x1="296" y1="48" x2="204" y2="94" stroke="rgba(255,255,255,0.22)" strokeDasharray="4 4" />
|
||||
<line x1="344" y1="48" x2="448" y2="74" stroke="rgba(255,255,255,0.22)" strokeDasharray="4 4" />
|
||||
<text x="320" y="66" fill="#7a8699" fontSize="9" textAnchor="middle">orchestrates</text>
|
||||
<rect x="40" y="16" width="64" height="36" rx="6" fill="rgba(255,255,255,0.04)" stroke="#56c288" />
|
||||
<text x="72" y="38" fill="#c6d2e1" fontSize="12" textAnchor="middle">VM</text>
|
||||
<line x1="72" y1="52" x2="72" y2="88" stroke="#56c288" className="schema-flow" strokeDasharray="5 4" />
|
||||
<polygon points="72,96 66,86 78,86" fill="#56c288" />
|
||||
<text x="80" y="76" fill="#56c288" fontSize="9">backup job</text>
|
||||
<rect x="24" y="96" width="216" height="140" rx="8" fill="none" stroke="rgba(255,255,255,0.22)" strokeDasharray="6 5" />
|
||||
<text x="36" y="118" fill="#c6d2e1" fontSize="12">Source BR</text>
|
||||
<text x="36" y="134" fill="#7a8699" fontSize="10">fast storage, short retention</text>
|
||||
<rect x="40" y="148" width="56" height="40" rx="6" fill="rgba(255,255,255,0.04)" stroke="#e0a94a" />
|
||||
<text x="68" y="172" fill="#c6d2e1" fontSize="13" textAnchor="middle">B</text>
|
||||
<rect x="104" y="148" width="56" height="40" rx="6" fill="rgba(255,255,255,0.04)" stroke="#e0a94a" />
|
||||
<text x="132" y="172" fill="#c6d2e1" fontSize="13" textAnchor="middle">C</text>
|
||||
<rect x="168" y="148" width="56" height="40" rx="6" fill="rgba(224,169,74,0.12)" stroke="#e0a94a" />
|
||||
<text x="196" y="172" fill="#c6d2e1" fontSize="13" textAnchor="middle">D</text>
|
||||
<line x1="246" y1="168" x2="360" y2="168" stroke="#5ac8c8" strokeWidth="2" className="schema-flow" strokeDasharray="5 4" />
|
||||
<polygon points="372,168 360,162 360,174" fill="#5ac8c8" />
|
||||
<text x="308" y="154" fill="#5ac8c8" fontSize="11" textAnchor="middle">mirror</text>
|
||||
<text x="308" y="188" fill="#7a8699" fontSize="9" textAnchor="middle">new backups only</text>
|
||||
<rect x="376" y="76" width="248" height="170" rx="8" fill="none" stroke="rgba(255,255,255,0.22)" strokeDasharray="6 5" />
|
||||
<text x="388" y="98" fill="#c6d2e1" fontSize="12">Destination BR</text>
|
||||
<text x="388" y="114" fill="#7a8699" fontSize="10">bigger, slower, cheaper</text>
|
||||
<rect x="392" y="148" width="52" height="40" rx="6" fill="rgba(255,255,255,0.04)" stroke="#e0a94a" />
|
||||
<text x="418" y="172" fill="#c6d2e1" fontSize="13" textAnchor="middle">A</text>
|
||||
<rect x="450" y="148" width="52" height="40" rx="6" fill="rgba(255,255,255,0.04)" stroke="#e0a94a" />
|
||||
<text x="476" y="172" fill="#c6d2e1" fontSize="13" textAnchor="middle">B</text>
|
||||
<rect x="508" y="148" width="52" height="40" rx="6" fill="rgba(255,255,255,0.04)" stroke="#e0a94a" />
|
||||
<text x="534" y="172" fill="#c6d2e1" fontSize="13" textAnchor="middle">C</text>
|
||||
<rect x="566" y="148" width="52" height="40" rx="6" fill="rgba(224,169,74,0.12)" stroke="#e0a94a" />
|
||||
<text x="592" y="172" fill="#c6d2e1" fontSize="13" textAnchor="middle">D</text>
|
||||
<text x="388" y="226" fill="#7a8699" fontSize="10">longer retention: keeps more restore points</text>
|
||||
</svg>
|
||||
</Schema>
|
||||
|
||||
## Creation
|
||||
|
||||
In the Backup view, create a new backup job and select **Mirror backup**.
|
||||
Then, choose whether you want to mirror incremental backups or full backups.
|
||||
A mirror backup job has exactly one source repository and one or more destinations. The mirroring speed is limited by the slowest repository.
|
||||
|
||||
Most options of the full/incremental backup jobs also apply here, like concurrency (number of VMs transferred in parallel), reports, proxy and speed limit. You can also add a health check on schedules. Please note that only the last transferred backup (if any) will be checked.
|
||||
|
||||
:::tip
|
||||
If you have full and incremental backups on a repository, you must configure 2 mirror backup jobs, one full and one incremental.
|
||||
:::
|
||||
|
||||
## Synchronizing algorithm for full backups {#synchronizing-algorithm-for-full-backups}
|
||||
|
||||
Any new backup on the source is transferred to the destination. Each side then applies its own retention: the source window slides forward while the destination, with its longer retention, keeps one more restore point before deleting anything.
|
||||
|
||||
<Schema label="Three runs of a full mirror: each run copies only the new archive, the source window slides (retention 3) while the destination accumulates until its own retention of 4 forces the oldest archive out" legend={[["#e0a94a", "full backup"], ["#5ac8c8", "transfer"], ["#ef6a5f", "deleted on destination"]]} maxWidth="640px">
|
||||
<svg viewBox="0 0 640 244" role="img" aria-label="Three rows show successive mirror runs. Run 1: the source holds A, B and C, all three are transferred, the destination holds A, B and C. Run 2: the source slides to B, C and D, only D is transferred, the destination holds A, B, C and D. Run 3: the source slides to C, D and E, only E is transferred, and A is deleted from the destination because its retention of 4 is exceeded, leaving B, C, D and E">
|
||||
<text x="130" y="22" fill="#c6d2e1" fontSize="12" textAnchor="middle">Source BR (retention 3)</text>
|
||||
<text x="442" y="22" fill="#c6d2e1" fontSize="12" textAnchor="middle">Destination BR (retention 4)</text>
|
||||
<text x="16" y="60" fill="#7a8699" fontSize="10">run 1</text>
|
||||
<rect x="68" y="40" width="36" height="32" rx="5" fill="rgba(255,255,255,0.04)" stroke="#e0a94a" />
|
||||
<text x="86" y="60" fill="#c6d2e1" fontSize="12" textAnchor="middle">A</text>
|
||||
<rect x="112" y="40" width="36" height="32" rx="5" fill="rgba(255,255,255,0.04)" stroke="#e0a94a" />
|
||||
<text x="130" y="60" fill="#c6d2e1" fontSize="12" textAnchor="middle">B</text>
|
||||
<rect x="156" y="40" width="36" height="32" rx="5" fill="rgba(255,255,255,0.04)" stroke="#e0a94a" />
|
||||
<text x="174" y="60" fill="#c6d2e1" fontSize="12" textAnchor="middle">C</text>
|
||||
<line x1="204" y1="56" x2="308" y2="56" stroke="#5ac8c8" className="schema-flow" strokeDasharray="5 4" />
|
||||
<polygon points="318,56 307,50.5 307,61.5" fill="#5ac8c8" />
|
||||
<text x="260" y="48" fill="#5ac8c8" fontSize="10" textAnchor="middle">A, B, C</text>
|
||||
<rect x="336" y="40" width="36" height="32" rx="5" fill="rgba(255,255,255,0.04)" stroke="#e0a94a" />
|
||||
<text x="354" y="60" fill="#c6d2e1" fontSize="12" textAnchor="middle">A</text>
|
||||
<rect x="380" y="40" width="36" height="32" rx="5" fill="rgba(255,255,255,0.04)" stroke="#e0a94a" />
|
||||
<text x="398" y="60" fill="#c6d2e1" fontSize="12" textAnchor="middle">B</text>
|
||||
<rect x="424" y="40" width="36" height="32" rx="5" fill="rgba(255,255,255,0.04)" stroke="#e0a94a" />
|
||||
<text x="442" y="60" fill="#c6d2e1" fontSize="12" textAnchor="middle">C</text>
|
||||
<text x="16" y="124" fill="#7a8699" fontSize="10">run 2</text>
|
||||
<rect x="68" y="104" width="36" height="32" rx="5" fill="rgba(255,255,255,0.04)" stroke="#e0a94a" />
|
||||
<text x="86" y="124" fill="#c6d2e1" fontSize="12" textAnchor="middle">B</text>
|
||||
<rect x="112" y="104" width="36" height="32" rx="5" fill="rgba(255,255,255,0.04)" stroke="#e0a94a" />
|
||||
<text x="130" y="124" fill="#c6d2e1" fontSize="12" textAnchor="middle">C</text>
|
||||
<rect x="156" y="104" width="36" height="32" rx="5" fill="rgba(224,169,74,0.12)" stroke="#e0a94a" />
|
||||
<text x="174" y="124" fill="#c6d2e1" fontSize="12" textAnchor="middle">D</text>
|
||||
<line x1="204" y1="120" x2="308" y2="120" stroke="#5ac8c8" className="schema-flow" strokeDasharray="5 4" />
|
||||
<polygon points="318,120 307,114.5 307,125.5" fill="#5ac8c8" />
|
||||
<text x="260" y="112" fill="#5ac8c8" fontSize="10" textAnchor="middle">D only</text>
|
||||
<rect x="336" y="104" width="36" height="32" rx="5" fill="rgba(255,255,255,0.04)" stroke="#e0a94a" />
|
||||
<text x="354" y="124" fill="#c6d2e1" fontSize="12" textAnchor="middle">A</text>
|
||||
<rect x="380" y="104" width="36" height="32" rx="5" fill="rgba(255,255,255,0.04)" stroke="#e0a94a" />
|
||||
<text x="398" y="124" fill="#c6d2e1" fontSize="12" textAnchor="middle">B</text>
|
||||
<rect x="424" y="104" width="36" height="32" rx="5" fill="rgba(255,255,255,0.04)" stroke="#e0a94a" />
|
||||
<text x="442" y="124" fill="#c6d2e1" fontSize="12" textAnchor="middle">C</text>
|
||||
<rect x="468" y="104" width="36" height="32" rx="5" fill="rgba(224,169,74,0.12)" stroke="#e0a94a" />
|
||||
<text x="486" y="124" fill="#c6d2e1" fontSize="12" textAnchor="middle">D</text>
|
||||
<text x="16" y="188" fill="#7a8699" fontSize="10">run 3</text>
|
||||
<rect x="68" y="168" width="36" height="32" rx="5" fill="rgba(255,255,255,0.04)" stroke="#e0a94a" />
|
||||
<text x="86" y="188" fill="#c6d2e1" fontSize="12" textAnchor="middle">C</text>
|
||||
<rect x="112" y="168" width="36" height="32" rx="5" fill="rgba(255,255,255,0.04)" stroke="#e0a94a" />
|
||||
<text x="130" y="188" fill="#c6d2e1" fontSize="12" textAnchor="middle">D</text>
|
||||
<rect x="156" y="168" width="36" height="32" rx="5" fill="rgba(224,169,74,0.12)" stroke="#e0a94a" />
|
||||
<text x="174" y="188" fill="#c6d2e1" fontSize="12" textAnchor="middle">E</text>
|
||||
<line x1="204" y1="184" x2="308" y2="184" stroke="#5ac8c8" className="schema-flow" strokeDasharray="5 4" />
|
||||
<polygon points="318,184 307,178.5 307,189.5" fill="#5ac8c8" />
|
||||
<text x="260" y="176" fill="#5ac8c8" fontSize="10" textAnchor="middle">E only</text>
|
||||
<rect x="336" y="168" width="36" height="32" rx="5" fill="rgba(239,106,95,0.08)" stroke="#ef6a5f" />
|
||||
<text x="354" y="188" fill="#ef6a5f" fontSize="12" textAnchor="middle">A</text>
|
||||
<text x="354" y="216" fill="#ef6a5f" fontSize="9" textAnchor="middle">deleted</text>
|
||||
<rect x="380" y="168" width="36" height="32" rx="5" fill="rgba(255,255,255,0.04)" stroke="#e0a94a" />
|
||||
<text x="398" y="188" fill="#c6d2e1" fontSize="12" textAnchor="middle">B</text>
|
||||
<rect x="424" y="168" width="36" height="32" rx="5" fill="rgba(255,255,255,0.04)" stroke="#e0a94a" />
|
||||
<text x="442" y="188" fill="#c6d2e1" fontSize="12" textAnchor="middle">C</text>
|
||||
<rect x="468" y="168" width="36" height="32" rx="5" fill="rgba(255,255,255,0.04)" stroke="#e0a94a" />
|
||||
<text x="486" y="188" fill="#c6d2e1" fontSize="12" textAnchor="middle">D</text>
|
||||
<rect x="512" y="168" width="36" height="32" rx="5" fill="rgba(224,169,74,0.12)" stroke="#e0a94a" />
|
||||
<text x="530" y="188" fill="#c6d2e1" fontSize="12" textAnchor="middle">E</text>
|
||||
<text x="442" y="216" fill="#7a8699" fontSize="9" textAnchor="middle">run 3: retention 4 exceeded, A is deleted</text>
|
||||
</svg>
|
||||
</Schema>
|
||||
|
||||
_Each letter is a full backup archive. The source has a retention of 3, the destination a retention of 4._
|
||||
|
||||
### First transfer
|
||||
|
||||
```
|
||||
- source : ABC
|
||||
- destination: empty
|
||||
```
|
||||
|
||||
XO transfers A, then B, then C. The destination now contains ABC.
|
||||
|
||||
:::warning
|
||||
**Limitation:** if the mirror retention is lower than the backup retention on the source repository, more data than necessary may be transferred during the first run, since all the backups of the source will be transferred to the destinations. Then the older backups will be purged on the destinations.
|
||||
:::
|
||||
|
||||
### Second transfer
|
||||
|
||||
```
|
||||
- source : BCD
|
||||
- destination: ABC
|
||||
```
|
||||
|
||||
Only D is transferred. The destination now contains ABCD.
|
||||
|
||||
### Third transfer
|
||||
|
||||
```
|
||||
- source : CDE
|
||||
- destination: ABCD
|
||||
```
|
||||
|
||||
Only E is transferred, and A is deleted from the destination because its retention of 4 is now exceeded. The destination now contains BCDE.
|
||||
|
||||
### If there is too much change on the source {#if-there-is-too-much-change-on-source}
|
||||
|
||||
```
|
||||
- source : IJK
|
||||
- destination: BCDE
|
||||
```
|
||||
|
||||
I, J and K are transferred in order, and B, C and D are deleted from the destination. The destination now contains EIJK.
|
||||
|
||||
## Synchronizing algorithm for incremental backups
|
||||
|
||||
This job only transfers new backups, then runs the same merge algorithm as [Incremental Backups](xo5/incremental_backups.md) on the destination. Since each side applies its own retention, the merges happen independently: the source merges sooner (retention 3), the destination later (retention 4).
|
||||
|
||||
<Schema label="Three runs of an incremental mirror: only the new deltas cross the wire, and each BR merges its own chain when its own retention is exceeded, the source after run 1, the destination one run later" legend={[["#e0a94a", "key (full) backup"], ["#6aabf0", "delta"], ["#5ac8c8", "transfer"]]} maxWidth="640px">
|
||||
<svg viewBox="0 0 640 266" role="img" aria-label="Three rows show successive mirror runs of an incremental chain. Run 1: the source holds key A plus deltas b and c, all three are transferred, the destination holds A, b and c. Run 2: the source has merged A and b into key B and holds B, c and d, only the delta d is transferred, the destination holds A, b, c and d with no merge yet. Run 3: the source holds C, d and e, only the delta e is transferred, and the destination now merges A and b into B, holding B, c, d and e">
|
||||
<text x="124" y="22" fill="#c6d2e1" fontSize="12" textAnchor="middle">Source BR (retention 3)</text>
|
||||
<text x="412" y="22" fill="#c6d2e1" fontSize="12" textAnchor="middle">Destination BR (retention 4)</text>
|
||||
<text x="16" y="64" fill="#7a8699" fontSize="10">run 1</text>
|
||||
<rect x="68" y="44" width="36" height="32" rx="5" fill="rgba(255,255,255,0.04)" stroke="#e0a94a" />
|
||||
<text x="86" y="64" fill="#c6d2e1" fontSize="12" textAnchor="middle">A</text>
|
||||
<rect x="112" y="47" width="30" height="26" rx="4" fill="rgba(255,255,255,0.04)" stroke="#6aabf0" />
|
||||
<text x="127" y="64" fill="#c6d2e1" fontSize="11" textAnchor="middle">b</text>
|
||||
<rect x="150" y="47" width="30" height="26" rx="4" fill="rgba(255,255,255,0.04)" stroke="#6aabf0" />
|
||||
<text x="165" y="64" fill="#c6d2e1" fontSize="11" textAnchor="middle">c</text>
|
||||
<line x1="204" y1="60" x2="308" y2="60" stroke="#5ac8c8" className="schema-flow" strokeDasharray="5 4" />
|
||||
<polygon points="318,60 307,54.5 307,65.5" fill="#5ac8c8" />
|
||||
<text x="260" y="52" fill="#5ac8c8" fontSize="10" textAnchor="middle">A, b, c</text>
|
||||
<rect x="336" y="44" width="36" height="32" rx="5" fill="rgba(255,255,255,0.04)" stroke="#e0a94a" />
|
||||
<text x="354" y="64" fill="#c6d2e1" fontSize="12" textAnchor="middle">A</text>
|
||||
<rect x="380" y="47" width="30" height="26" rx="4" fill="rgba(255,255,255,0.04)" stroke="#6aabf0" />
|
||||
<text x="395" y="64" fill="#c6d2e1" fontSize="11" textAnchor="middle">b</text>
|
||||
<rect x="418" y="47" width="30" height="26" rx="4" fill="rgba(255,255,255,0.04)" stroke="#6aabf0" />
|
||||
<text x="433" y="64" fill="#c6d2e1" fontSize="11" textAnchor="middle">c</text>
|
||||
<text x="16" y="132" fill="#7a8699" fontSize="10">run 2</text>
|
||||
<rect x="68" y="112" width="36" height="32" rx="5" fill="rgba(255,255,255,0.04)" stroke="#e0a94a" />
|
||||
<text x="86" y="132" fill="#c6d2e1" fontSize="12" textAnchor="middle">B</text>
|
||||
<rect x="112" y="115" width="30" height="26" rx="4" fill="rgba(255,255,255,0.04)" stroke="#6aabf0" />
|
||||
<text x="127" y="132" fill="#c6d2e1" fontSize="11" textAnchor="middle">c</text>
|
||||
<rect x="150" y="115" width="30" height="26" rx="4" fill="rgba(106,171,240,0.12)" stroke="#6aabf0" />
|
||||
<text x="165" y="132" fill="#c6d2e1" fontSize="11" textAnchor="middle">d</text>
|
||||
<text x="68" y="160" fill="#e0a94a" fontSize="9">A + b merged into B</text>
|
||||
<line x1="204" y1="128" x2="308" y2="128" stroke="#5ac8c8" className="schema-flow" strokeDasharray="5 4" />
|
||||
<polygon points="318,128 307,122.5 307,133.5" fill="#5ac8c8" />
|
||||
<text x="260" y="120" fill="#5ac8c8" fontSize="10" textAnchor="middle">d only</text>
|
||||
<rect x="336" y="112" width="36" height="32" rx="5" fill="rgba(255,255,255,0.04)" stroke="#e0a94a" />
|
||||
<text x="354" y="132" fill="#c6d2e1" fontSize="12" textAnchor="middle">A</text>
|
||||
<rect x="380" y="115" width="30" height="26" rx="4" fill="rgba(255,255,255,0.04)" stroke="#6aabf0" />
|
||||
<text x="395" y="132" fill="#c6d2e1" fontSize="11" textAnchor="middle">b</text>
|
||||
<rect x="418" y="115" width="30" height="26" rx="4" fill="rgba(255,255,255,0.04)" stroke="#6aabf0" />
|
||||
<text x="433" y="132" fill="#c6d2e1" fontSize="11" textAnchor="middle">c</text>
|
||||
<rect x="456" y="115" width="30" height="26" rx="4" fill="rgba(106,171,240,0.12)" stroke="#6aabf0" />
|
||||
<text x="471" y="132" fill="#c6d2e1" fontSize="11" textAnchor="middle">d</text>
|
||||
<text x="336" y="160" fill="#7a8699" fontSize="9">no merge: retention 4 not exceeded</text>
|
||||
<text x="16" y="208" fill="#7a8699" fontSize="10">run 3</text>
|
||||
<rect x="68" y="188" width="36" height="32" rx="5" fill="rgba(255,255,255,0.04)" stroke="#e0a94a" />
|
||||
<text x="86" y="208" fill="#c6d2e1" fontSize="12" textAnchor="middle">C</text>
|
||||
<rect x="112" y="191" width="30" height="26" rx="4" fill="rgba(255,255,255,0.04)" stroke="#6aabf0" />
|
||||
<text x="127" y="208" fill="#c6d2e1" fontSize="11" textAnchor="middle">d</text>
|
||||
<rect x="150" y="191" width="30" height="26" rx="4" fill="rgba(106,171,240,0.12)" stroke="#6aabf0" />
|
||||
<text x="165" y="208" fill="#c6d2e1" fontSize="11" textAnchor="middle">e</text>
|
||||
<text x="68" y="236" fill="#e0a94a" fontSize="9">B + c merged into C</text>
|
||||
<line x1="204" y1="204" x2="308" y2="204" stroke="#5ac8c8" className="schema-flow" strokeDasharray="5 4" />
|
||||
<polygon points="318,204 307,198.5 307,209.5" fill="#5ac8c8" />
|
||||
<text x="260" y="196" fill="#5ac8c8" fontSize="10" textAnchor="middle">e only</text>
|
||||
<rect x="336" y="188" width="36" height="32" rx="5" fill="rgba(255,255,255,0.04)" stroke="#e0a94a" />
|
||||
<text x="354" y="208" fill="#c6d2e1" fontSize="12" textAnchor="middle">B</text>
|
||||
<rect x="380" y="191" width="30" height="26" rx="4" fill="rgba(255,255,255,0.04)" stroke="#6aabf0" />
|
||||
<text x="395" y="208" fill="#c6d2e1" fontSize="11" textAnchor="middle">c</text>
|
||||
<rect x="418" y="191" width="30" height="26" rx="4" fill="rgba(255,255,255,0.04)" stroke="#6aabf0" />
|
||||
<text x="433" y="208" fill="#c6d2e1" fontSize="11" textAnchor="middle">d</text>
|
||||
<rect x="456" y="191" width="30" height="26" rx="4" fill="rgba(106,171,240,0.12)" stroke="#6aabf0" />
|
||||
<text x="471" y="208" fill="#c6d2e1" fontSize="11" textAnchor="middle">e</text>
|
||||
<text x="336" y="236" fill="#e0a94a" fontSize="9">A + b merged into B</text>
|
||||
<text x="320" y="258" fill="#7a8699" fontSize="10" textAnchor="middle">Each BR merges independently: the destination merges one run later because its retention is longer</text>
|
||||
</svg>
|
||||
</Schema>
|
||||
|
||||
_Key (full) backups are in uppercase, delta backups in lowercase. The source has a retention of 3, the destination a retention of 4._
|
||||
|
||||
### First transfer
|
||||
|
||||
```
|
||||
- source : Abc # one key, two delta
|
||||
- destination: empty
|
||||
```
|
||||
|
||||
XO transfers A, then b, then c. The destination now contains Abc.
|
||||
|
||||
:::warning
|
||||
**Limitation:** if the mirror retention is lower than the backup retention on the source repository, more data than necessary may be transferred during the first run, since all the backups of the source will be transferred to the destinations. Then the older backups will be purged on the destinations.
|
||||
:::
|
||||
|
||||
### Second transfer
|
||||
|
||||
```
|
||||
- source : Bcd # A and b have been merged
|
||||
- destination: Abc
|
||||
```
|
||||
|
||||
Only the delta d is transferred. The destination now contains Abcd (no merge yet: its retention of 4 is not exceeded).
|
||||
|
||||
### Third transfer
|
||||
|
||||
```
|
||||
- source : Cde # B and c have been merged
|
||||
- destination: Abcd
|
||||
```
|
||||
|
||||
Only the delta e is transferred. The destination now contains Bcde (A is merged into b on the destination).
|
||||
|
||||
### If there is too much change on the source {#if-there-is-too-much-change-on-source-1}
|
||||
|
||||
```
|
||||
- source : Ijk
|
||||
- destination: Bcde
|
||||
```
|
||||
|
||||
The whole chain is transferred in order. The destination now contains EIjk (B, c and d are merged into e).
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
Xen Orchestra is compatible with a wide range of S3-compatible object storage solutions. Based on our testing and validation, we categorize storage providers into three tiers to help you understand their expected reliability and performance.
|
||||
|
||||
To configure an S3-compatible backup repository, see [Backup repositories](xo5/backups.md#remotes).
|
||||
|
||||
## Storage tiers explained
|
||||
|
||||
- **Tier 1** providers are extensively tested in our labs. We ensure Xen Orchestra aligns with their implementation and performs reliably, even at scale.
|
||||
@@ -20,14 +22,14 @@ Xen Orchestra is compatible with a wide range of S3-compatible object storage so
|
||||
| **OVH** | 1 | Fully tested and validated for reliability at scale. |
|
||||
| **Wasabi** | 2 | Behaves similarly to Tier 1 but with less extensive large-scale testing. |
|
||||
| **CleverCloud** | 2 | Behaves similarly to Tier 1 but with less extensive large-scale testing. |
|
||||
| **Backblaze / B2** | 3 | The `list` operation may time out, which will cause irrecuperrable errors during the `cleanVM` phase |
|
||||
| **Backblaze / B2** | 3 | The `list` operation may time out, which will cause irrecoverable errors during the `cleanVM` phase |
|
||||
| **MinIO** | 2 or 3 | Depends on performance; can be dimensioned to handle large deployment, but this is **not covered by Vates support**. |
|
||||
| **Ceph** (on-premise) | 2 or 3 | Depends on performance; can be dimensioned to handle large deployment, but this is **not covered by Vates support**. |
|
||||
| **NetApp** | 2 | Tier 2 support applies to ONTAP version 9.16 or later. |
|
||||
|
||||
## What this means for your backups
|
||||
|
||||
The most demanding part of the backup process—cleaning and merging old data—is where tier differences matter most. Once a backup is complete, restoration is fully supported by Vates regardless of the storage tier.
|
||||
The most demanding part of the backup process (cleaning and merging old data) is where tier differences matter most. Once a backup is complete, restoration is fully supported by Vates regardless of the storage tier. You can inspect the health of a backup repository (BR) at any time with the [`xo-backups` CLI](xo5/backups.md#backups-cli).
|
||||
|
||||
Currently, we don’t have a formal validation program for every provider. This list reflects our hands-on experience working with users to ensure their backups remain secure.
|
||||
|
||||
@@ -35,4 +37,4 @@ Currently, we don’t have a formal validation program for every provider. This
|
||||
|
||||
We welcome collaboration with storage providers interested in pre-validating their platforms. If you can provide access and have active users, we’re happy to work with you.
|
||||
|
||||
If you’re using a storage solution at scale — whether successfully or with challenges — your feedback is invaluable. Reach out to us so we can refine the list and enhance support for the entire community.
|
||||
If you’re using a storage solution at scale, whether successfully or with challenges, your feedback is invaluable. Reach out to us so we can refine the list and enhance support for the entire community.
|
||||
@@ -1,15 +1,25 @@
|
||||
# ACL v2 / RBAC (REST API/XO6)
|
||||
---
|
||||
sidebar_label: RBAC
|
||||
---
|
||||
|
||||
ACL v2 is the access control system for the Xen Orchestra REST API and the XO6 UI. It lets you define exactly what each user or group can see and do — down to individual objects — without granting them full administrator access.
|
||||
# RBAC: Role-Based Access Control
|
||||
|
||||
## What changed from v1
|
||||
RBAC is the access control system for the Xen Orchestra [REST API](automation/restapi.md) and the XO 6 interface. It lets you define exactly what each user or group can see and do, down to individual objects, without granting them full administrator access.
|
||||
|
||||
The old ACL system (v1) allowed granting access to individual objects (a VM, an SR…). Simple, but limited: there was no way to say _"this user can shutdown only VMs tagged `qa`"_. It also only covered **XAPI objects** — VMs, hosts, SRs, networks. Users, groups, backups, schedules, and jobs were out of scope.
|
||||
:::note Where RBAC applies, and why it was once called "ACL v2"
|
||||
RBAC covers the **[REST API](automation/restapi.md)** and **XO 6**. The JSON-RPC API behind the XO 5 interface keeps the original [ACL system](xo5/users.md#acls), and those ACLs are not available on the REST API.
|
||||
|
||||
ACL v2 introduces a full **RBAC (Role-Based Access Control)** model with effects, selectors, and an action hierarchy, covering the entire infrastructure including XO management objects.
|
||||
You may still come across this feature under the name **ACL v2**. That was only a working name while it was being built. It is a full rewrite of the original ACLs into a much broader model, so it is now called by what it actually is: RBAC. Same feature, current name.
|
||||
:::
|
||||
|
||||
:::note
|
||||
ACL v2 is available through the **REST API only**. The JSON-RPC API (used by XO5) stays on ACL v1. Conversely, ACL v1 is not available on the REST API.
|
||||
## What changed from the original ACLs
|
||||
|
||||
The original [ACL system](xo5/users.md#acls) allowed granting access to individual objects (a VM, an SR…). Simple, but limited: there was no way to say _"this user can shutdown only VMs tagged `qa`"_. It also only covered **XAPI objects**: VMs, hosts, SRs, networks. Users, groups, backups, schedules, and jobs were out of scope.
|
||||
|
||||
RBAC introduces a full role-based model with effects, selectors, and an action hierarchy, covering the entire infrastructure including XO management objects.
|
||||
|
||||
:::info
|
||||
On XOA, RBAC is included in the **Essential+**, **Pro** and **Enterprise** bundles. Installations from the sources are not restricted.
|
||||
:::
|
||||
|
||||
---
|
||||
@@ -18,7 +28,7 @@ ACL v2 is available through the **REST API only**. The JSON-RPC API (used by XO5
|
||||
|
||||
### How it works
|
||||
|
||||
ACL v2 follows a **deny-by-default** model:
|
||||
RBAC follows a **deny-by-default** model:
|
||||
|
||||
- XOA admins always have full access, regardless of any ACL configuration.
|
||||
- Non-admin users start with **zero access**. They can only access objects they have been explicitly granted permission to.
|
||||
@@ -41,10 +51,10 @@ A user's effective privileges are the union of all privileges from all their dir
|
||||
|
||||
A privilege defines:
|
||||
|
||||
- **resource** — the type of object (e.g. `vm`, `backup-job`, `sr`)
|
||||
- **action** — what operation is allowed or denied (e.g. `read`, `start`, `delete`)
|
||||
- **effect** — whether the privilege grants (`allow`) or blocks (`deny`) the action
|
||||
- **selector** _(optional)_ — a filter expression to restrict the privilege to a subset of objects ([complex-matcher format](../xo5/manage_infrastructure.md#filter-syntax))
|
||||
- **resource**: the type of object (e.g. `vm`, `backup-job`, `sr`)
|
||||
- **action**: what operation is allowed or denied (e.g. `read`, `start`, `delete`)
|
||||
- **effect**: whether the privilege grants (`allow`) or blocks (`deny`) the action
|
||||
- **selector** _(optional)_: a filter expression to restrict the privilege to a subset of objects ([complex-matcher format](xo5/manage_infrastructure.md#filter-syntax))
|
||||
|
||||
### Action hierarchy
|
||||
|
||||
@@ -63,22 +73,52 @@ The reverse is not true: granting `shutdown:clean` does **not** grant `shutdown:
|
||||
|
||||
## Built-in template roles
|
||||
|
||||
Xen Orchestra ships with eight ready-to-use role templates. They are **immutable** and automatically kept up to date on startup — they cannot be modified, deleted, or assigned directly.
|
||||
Xen Orchestra ships with eight ready-to-use role templates. They are **immutable** and automatically kept up to date on startup: they cannot be modified, deleted, or assigned directly.
|
||||
|
||||
To use them, **copy** a template into a new role and assign that copy to your users or groups. This ensures the built-in templates always stay up to date without affecting your custom configuration.
|
||||
|
||||
| Role | Description |
|
||||
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **Read only** | Read access to the entire infrastructure and all XO objects. Cannot modify anything. |
|
||||
| **VMs power state manager** | Can start, stop, reboot, pause, suspend, resume, and unpause VMs. |
|
||||
| **VMs creator** | Can instantiate VM templates and create VDIs and VIFs. |
|
||||
| **VMs read only** | Can only list and view VMs. |
|
||||
| **VMs administrator** | Full control over VM actions |
|
||||
| **Network administrator** | Can manage networks and VIFs, read and update PIFs, and view hosts and VMs. |
|
||||
| **Administrator** | Full access to the entire infrastructure |
|
||||
| **Storage administrator** | Administer storage resources (SRs, VDIs, VBDs, PBDs) and backup repositories, plus read access to unmanaged VDIs and storage managers. |
|
||||
| Role | Description |
|
||||
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **Read only** | Read access to the entire infrastructure and all XO objects. Cannot modify anything. |
|
||||
| **VMs power state manager** | Can start, stop, reboot, pause, suspend, resume, and unpause VMs. |
|
||||
| **VMs creator** | Can instantiate VM templates and create VDIs and VIFs. |
|
||||
| **VMs read only** | Can only list and view VMs. |
|
||||
| **VMs administrator** | Full control over VM actions, plus read access to VM snapshots. |
|
||||
| **Network administrator** | Scoped admin for networking: manages networks and VIFs, creates pool networks, reads and updates PIFs, and views pools, hosts and VMs. |
|
||||
| **Storage administrator** | Scoped admin for storage: full control over SRs, VDIs, VBDs, PBDs and backup repositories, read access to unmanaged VDIs and storage managers. |
|
||||
| **Administrator** | Full access to the entire infrastructure and all XO objects. |
|
||||
|
||||

|
||||
The **Administrator** template and the two scoped administrator roles below were introduced in Xen Orchestra 6.6.
|
||||
|
||||
### Scoped administrator roles
|
||||
|
||||
The two scoped admin templates let you delegate a whole functional area (storage or networking) without handing out global admin rights. Here is exactly what each template grants:
|
||||
|
||||
**Storage administrator**
|
||||
|
||||
| Resource | Access |
|
||||
| ---------------------------------------------- | ------------------------------------------------------------------------------------------ |
|
||||
| `sr`, `vdi`, `vbd`, `pbd`, `backup-repository` | Every action (`*`): read, create, delete, connect/plug, scan, migrate, resize, and so on. |
|
||||
| `vdi-unmanaged`, `sm` | Read only. |
|
||||
|
||||
In practice, a Storage administrator can create and delete SRs, manage virtual disks and their attachments on both hosts and VMs, plug or unplug PBDs, and fully manage backup repositories (create, forget, benchmark, update), while the rest of the infrastructure stays out of reach.
|
||||
|
||||
**Network administrator**
|
||||
|
||||
| Resource | Access |
|
||||
| --------- | ------------------------------------------------------------------------------------------------ |
|
||||
| `network` | Every action (`*`): read, create, delete, update tags and `other_config`. |
|
||||
| `vif` | Every action (`*`): read, create, delete, connect, disconnect, update locking mode, rate limit… |
|
||||
| `pool` | `read` and `create:network` (create networks at the pool level, including bonded and internal). |
|
||||
| `pif` | `read` and `update` (e.g. reconfigure the management interface). |
|
||||
| `host` | Read only. |
|
||||
| `vm` | Read only. |
|
||||
|
||||
A Network administrator can therefore manage the whole network stack, from pool networks down to individual VM interfaces, while hosts and VMs themselves remain visible but untouchable.
|
||||
|
||||
To copy a template into an assignable role, use `POST /rest/v0/acl-roles/<template-id>/actions/copy`:
|
||||
|
||||
<UiDetail src="/img/xo6/swagger-role-copy.png" alt="The copy action on a template role, in the REST API Swagger UI" width={620} />
|
||||
|
||||
---
|
||||
|
||||
@@ -89,11 +129,13 @@ Some endpoints are always accessible to a logged-in user **without any ACL privi
|
||||
| Endpoint | Description |
|
||||
| ---------------------------------------------- | ------------------------------------------- |
|
||||
| `GET /rest/v0/users/me` | Get your own user profile |
|
||||
| `GET /rest/v0/users/me/privileges` | List your own privileges |
|
||||
| `GET /rest/v0/users/me/acl-privileges` | List your own privileges |
|
||||
| `GET /rest/v0/users/me/authentication_tokens` | List your own authentication tokens |
|
||||
| `POST /rest/v0/users/me/authentication_tokens` | Create an authentication token for yourself |
|
||||
|
||||
`me` is a convenience alias — it is automatically redirected to `/rest/v0/users/{your-id}`.
|
||||
`me` is a convenience alias: it is automatically redirected to `/rest/v0/users/{your-id}`.
|
||||
|
||||
This is how delegation works end to end: any user, whatever their privileges, can create their own [authentication token](automation/restapi.md#authentication) and use it to call the REST API within the limits of their roles.
|
||||
|
||||
:::tip
|
||||
The Swagger UI available at `/rest/v0/swagger` documents every endpoint with its required privileges. Endpoints with no declared privilege are admin-only.
|
||||
@@ -103,7 +145,7 @@ The Swagger UI available at `/rest/v0/swagger` documents every endpoint with its
|
||||
|
||||
## Supported resources and actions
|
||||
|
||||
Actions are written using the exact string you pass in a privilege. A parent action (e.g. `reboot`) is a shortcut that covers all its children — see [Action hierarchy](#action-hierarchy).
|
||||
Actions are written using the exact string you pass in a privilege. A parent action (e.g. `reboot`) is a shortcut that covers all its children, see [Action hierarchy](#action-hierarchy).
|
||||
|
||||
### Infrastructure resources
|
||||
|
||||
@@ -157,6 +199,8 @@ Actions are written using the exact string you pass in a privilege. A parent act
|
||||
| `acl-role` | `read`, `create`, `delete`, `update:name`, `update:description`, `update:users`, `update:groups` |
|
||||
| `acl-privilege` | `read`, `create`, `delete`, `update:action`, `update:effect`, `update:resource`, `update:selector` |
|
||||
|
||||
Note the last two rows: RBAC configuration is itself covered by the model. You do not need to be a full administrator to manage roles and privileges; a user holding the right `acl-role` and `acl-privilege` privileges can delegate access in turn, through the REST API.
|
||||
|
||||
---
|
||||
|
||||
## Concrete examples
|
||||
@@ -165,14 +209,16 @@ Actions are written using the exact string you pass in a privilege. A parent act
|
||||
|
||||
> Alice needs to start and stop VMs in her test environment, but must not touch anything in production.
|
||||
|
||||
Create a `QA Operator` role with these privileges: POST /acl-privileges
|
||||
Create a `QA Operator` role, then POST each of these privileges to `/rest/v0/acl-privileges`:
|
||||
|
||||
```json
|
||||
{ "resource": "vm", "action": "read", "effect": "allow", "selector": "tags:qa" "roleId": "169020fd-4d5e-45fc-a26c-23153df00dcf"}
|
||||
{ "resource": "vm", "action": "start", "effect": "allow", "selector": "tags:qa" "roleId": "169020fd-4d5e-45fc-a26c-23153df00dcf"}
|
||||
{ "resource": "vm", "action": "shutdown", "effect": "allow", "selector": "tags:qa" "roleId": "169020fd-4d5e-45fc-a26c-23153df00dcf"}
|
||||
{ "resource": "vm", "action": "read", "effect": "allow", "selector": "tags:qa", "roleId": "169020fd-4d5e-45fc-a26c-23153df00dcf" }
|
||||
{ "resource": "vm", "action": "start", "effect": "allow", "selector": "tags:qa", "roleId": "169020fd-4d5e-45fc-a26c-23153df00dcf" }
|
||||
{ "resource": "vm", "action": "shutdown", "effect": "allow", "selector": "tags:qa", "roleId": "169020fd-4d5e-45fc-a26c-23153df00dcf" }
|
||||
```
|
||||
|
||||
`roleId` is the id returned when the role was created, as shown in the [walkthrough](#walkthrough-creating-and-assigning-a-role) below. The next two examples omit it and show the privilege itself only.
|
||||
|
||||
Attach the role to Alice. She can now manage QA VMs only. Any attempt on a VM without the `qa` tag is blocked with a 403.
|
||||
|
||||
:::tip Selectors are evaluated dynamically
|
||||
@@ -184,7 +230,7 @@ This means a single tag change is enough to grant or revoke access to a resource
|
||||
|
||||
### Bob: Snapshot only running VMs
|
||||
|
||||
> Bob is allowed to snapshot VMs, but only while they are running — to avoid snapshotting stopped VMs that may be part of an automated maintenance process.
|
||||
> Bob is allowed to snapshot VMs, but only while they are running, to avoid snapshotting stopped VMs that may be part of an automated maintenance process.
|
||||
|
||||
Create a `Running VM Snapshot` role with these privileges:
|
||||
|
||||
@@ -199,24 +245,24 @@ Bob can see and snapshot any running VM. Stopped VMs are completely invisible to
|
||||
|
||||
### Carol: Full VM access except production
|
||||
|
||||
> Carol can do everything on VMs — except touch anything tagged `prod`.
|
||||
> Carol can do everything on VMs, except touch anything tagged `prod`.
|
||||
|
||||
Create a `Full VM Access (non-prod)` role with these privileges. The `*` wildcard grants every action on a resource at once. Pair it with a `deny` to carve out an exception — `deny` always wins:
|
||||
Create a `Full VM Access (non-prod)` role with these privileges. The `*` wildcard grants every action on a resource at once. Pair it with a `deny` to carve out an exception (`deny` always wins):
|
||||
|
||||
```json
|
||||
{ "resource": "vm", "action": "*", "effect": "allow" }
|
||||
{ "resource": "vm", "action": "*", "effect": "deny", "selector": "tags:prod" }
|
||||
```
|
||||
|
||||
Carol can start, stop, delete, snapshot any VM she wants. Production VMs are completely invisible to her — they never appear in her lists and any direct attempt returns a 403.
|
||||
Carol can start, stop, delete, snapshot any VM she wants. Production VMs are completely invisible to her: they never appear in her lists and any direct attempt returns a 403.
|
||||
|
||||
---
|
||||
|
||||
## Walkthrough: creating and assigning a role
|
||||
|
||||
### Step 1 — Create a role
|
||||
### Step 1: Create a role {#step-1--create-a-role}
|
||||
|
||||

|
||||
<UiDetail src="/img/xo6/swagger-create-role.png" alt="Creating a custom role through POST /acl-roles" width={480} />
|
||||
|
||||
Response:
|
||||
|
||||
@@ -224,25 +270,49 @@ Response:
|
||||
{ "id": "e4b1f3c2-1234-5678-abcd-000000000001" }
|
||||
```
|
||||
|
||||
### Step 2 — Add privileges to the role
|
||||
### Step 2: Add privileges to the role {#step-2--add-privileges-to-the-role}
|
||||
|
||||

|
||||
<UiDetail src="/img/xo6/swagger-create-privilege.png" alt="Attaching a privilege to a role through POST /acl-privileges" width={480} />
|
||||
|
||||
### Step 3 — Assign the role to the user
|
||||
### Step 3: Assign the role to the user {#step-3--assign-the-role-to-the-user}
|
||||
|
||||

|
||||
<UiDetail src="/img/xo6/swagger-add-user-to-role.png" alt="Adding a user to a role" width={480} />
|
||||
|
||||
The user can now list VMs.
|
||||
|
||||
To assign to a group instead (all group members inherit the role):
|
||||
|
||||

|
||||
<UiDetail src="/img/xo6/swagger-add-group-to-role.png" alt="Adding a group to a role" width={480} />
|
||||
|
||||
---
|
||||
|
||||
## Role management endpoints
|
||||
|
||||
Everything shown in the walkthrough (and more) is available as plain REST calls, ready for automation. All endpoints live under `/rest/v0/` and are protected by the matching `acl-role` or `acl-privilege` privileges:
|
||||
|
||||
| Endpoint | Description |
|
||||
| ---------------------------------------------- | --------------------------------------------------------------- |
|
||||
| `GET` / `POST /acl-roles` | List roles / create a role |
|
||||
| `GET` / `PATCH` / `DELETE /acl-roles/:id` | Read, rename or delete a role |
|
||||
| `POST /acl-roles/:id/actions/copy` | Copy a role (the only way to use a template) |
|
||||
| `GET /acl-roles/:id/privileges` | List the privileges of a role |
|
||||
| `PUT` / `DELETE /acl-roles/:id/users/:userId` | Assign the role to a user / remove it |
|
||||
| `PUT` / `DELETE /acl-roles/:id/groups/:groupId`| Assign the role to a group / remove it |
|
||||
| `GET /acl-roles/:id/users` | List the users holding a role _(XO 6.7)_ |
|
||||
| `GET /acl-roles/:id/groups` | List the groups holding a role _(XO 6.7)_ |
|
||||
| `GET /groups/:id/acl-roles` | List the roles of a group _(XO 6.7)_ |
|
||||
| `GET` / `POST /acl-privileges` | List privileges / create a privilege inside a role |
|
||||
| `GET` / `PATCH` / `DELETE /acl-privileges/:id` | Read, update or delete a privilege |
|
||||
|
||||
In the XO 6 interface, the **Administration** section of the sidebar covers users and groups; role and privilege management itself currently happens through the REST API, as shown above. See [Users and administration](xo6/management.md#users-and-administration).
|
||||
|
||||
<UiShot light="/img/xo6/administration-light.png" dark="/img/xo6/administration-dark.png" alt="The Administration section in XO 6, where users and groups are managed" url="https://your-xo/v6/#/admin/user-management/users" />
|
||||
|
||||
---
|
||||
|
||||
## Selectors
|
||||
|
||||
By default, a privilege applies to **all** objects of the given resource type. The optional `selector` field narrows it down using the [complex-matcher](../xo5/manage_infrastructure#filter-syntax) syntax — the same filter syntax used in the XO UI.
|
||||
By default, a privilege applies to **all** objects of the given resource type. The optional `selector` field narrows it down using the [complex-matcher](xo5/manage_infrastructure.md#filter-syntax) syntax, the same filter syntax used in the XO UI.
|
||||
|
||||
A selector is evaluated against each object's properties. If it matches, the privilege applies; otherwise it does not.
|
||||
|
||||
@@ -264,4 +334,5 @@ A selector is evaluated against each object's properties. If it matches, the pri
|
||||
- **Use groups.** Assigning a role to a group avoids repeating the same assignment for every user.
|
||||
- **Combine `allow` and `deny`.** When a user needs broad access with specific exceptions, grant with a wildcard privilege and carve out exceptions with `deny` + a selector.
|
||||
- **Template roles are immutable.** Copy them first before customizing.
|
||||
- **Delegate the delegation.** Grant `acl-role` and `acl-privilege` privileges to trusted operators so they can manage access themselves, without full admin rights.
|
||||
- **Endpoint permissions** are visible in the Swagger UI (`/rest/v0/swagger`). Endpoints without a declared privilege require admin access.
|
||||
@@ -0,0 +1,45 @@
|
||||
# Releases
|
||||
|
||||
Xen Orchestra is distributed in two ways: as a turnkey virtual appliance (**XOA**) and **from the sources** on GitHub. Both contain the same Xen Orchestra, including its two web interfaces ([XO 6 and XO 5](xo6/xo6vsxo5.md)), the REST API and the backup engine.
|
||||
|
||||
## XOA, the appliance
|
||||
|
||||
XOA (**X**en **O**rchestra virtual **A**ppliance) is the pre-installed VM, and the recommended way to run Xen Orchestra:
|
||||
|
||||
- everything ready to work, deployed in minutes
|
||||
- complete QA on every release
|
||||
- a web [updater](updater.md) with release channels
|
||||
- bundled remote support capabilities
|
||||
- extra services (XO Hub, recipes, advanced metrics)
|
||||
- a secured system (sudo, firewall)
|
||||
|
||||
Deploying one is trivial: see the [XOA install section](installation.md#xoa).
|
||||
|
||||
:::tip
|
||||
Whatever your future usage, try XOA first: it is the easiest way to test everything, and the only way to get professional support.
|
||||
:::
|
||||
|
||||
## Release cadence and channels
|
||||
|
||||
A new Xen Orchestra release ships **every month**, versioned like `XOA 6.x`. Each release is announced on the [blog](https://xen-orchestra.com/blog/) with its release notes, and every change is tracked in the [changelog](https://github.com/vatesfr/xen-orchestra/blob/master/CHANGELOG.md#changelog).
|
||||
|
||||
On XOA you choose between two [release channels](updater.md#release-channel):
|
||||
|
||||
- **Stable**: a release that is already one month old, hardened by a month of community feedback and fixes. For production appliances where stability comes first.
|
||||
- **Latest**: all the newest improvements, QA validated, fresh from the monthly release.
|
||||
|
||||
Switching channels is done from the Updates view, without redeploying anything.
|
||||
|
||||
## From the sources
|
||||
|
||||
Xen Orchestra is fully open source, and you can [install it from the sources](install-from-sources.md). In that case there are no releases to speak of: **stay on `master`**, and update before reporting anything:
|
||||
|
||||
<Terminal shell title="xo — updating an installation from the sources">{`
|
||||
cd xen-orchestra
|
||||
git pull # stay on master
|
||||
yarn && yarn build
|
||||
`}</Terminal>
|
||||
|
||||
:::warning
|
||||
There is no community support for source installations that are not up to date with `master`.
|
||||
:::
|
||||
@@ -0,0 +1,90 @@
|
||||
# Rolling snapshots
|
||||
|
||||
:::warning
|
||||
Snapshots are NOT backups. A snapshot lives on the same storage as the original disk: if you lose that disk or the whole storage repository (SR), you lose every snapshot with it. Rolling snapshots are a convenient way to roll back in time, not a way to survive a storage failure.
|
||||
|
||||
Snapshots and backups are not mutually exclusive either: use rolling snapshots for quick rollbacks, and a real backup job (with data stored on a separate backup repository) for actual protection. Never rely on snapshots alone!
|
||||
:::
|
||||
|
||||
A rolling snapshot job takes a snapshot of the VMs you selected, on the schedule you defined, and applies a retention policy: when the number of snapshots created by the job exceeds the limit, the oldest one is deleted automatically. The result is a rotating window of instant restore points that maintains itself, with no manual cleanup and no backup repository (BR) needed.
|
||||
|
||||
Because everything stays on the SR, snapshots are created in seconds and reverting a VM to any point in the window is nearly instant. That makes rolling snapshots ideal as a first line of defense against "oops" moments: a bad update, a broken config change, a botched application upgrade.
|
||||
|
||||
## How it works
|
||||
|
||||
Every time the schedule fires, Xen Orchestra:
|
||||
|
||||
1. Takes a snapshot of each VM in the job.
|
||||
2. Counts the snapshots previously created by this job.
|
||||
3. Deletes the oldest one(s) if the total exceeds the configured retention.
|
||||
|
||||
With a daily schedule and a retention of 7, you always keep the last seven days: each morning a fresh snapshot appears, and the one from eight days ago disappears.
|
||||
|
||||
<Schema label="Daily rolling snapshots with a retention of 7" legend={[["#56c288", "new snapshot"], ["#ef6a5f", "oldest, removed"], ["#e0a94a", "rotation"]]} maxWidth="640px">
|
||||
<svg viewBox="0 0 640 240" role="img" aria-label="A VM on its storage repository with seven daily snapshots; when the new day 8 snapshot is created, the oldest day 1 snapshot is removed">
|
||||
<rect x="20" y="28" width="600" height="184" rx="10" fill="none" stroke="rgba(255,255,255,0.22)" strokeDasharray="6 5"/>
|
||||
<text x="36" y="52" fontSize="12" fill="#7a8699">Storage repository (SR)</text>
|
||||
<rect x="45" y="66" width="96" height="46" rx="5" fill="rgba(86,194,136,0.14)" stroke="#56c288"/>
|
||||
<text x="93" y="93" fontSize="12" textAnchor="middle" fill="#c6d2e1">VM</text>
|
||||
<line x1="141" y1="92" x2="552" y2="130" stroke="#56c288" strokeWidth="1.5" strokeDasharray="5 4" className="schema-flow"/>
|
||||
<polygon points="562,133 550,124 548,135" fill="#56c288"/>
|
||||
<rect x="45" y="138" width="62" height="46" rx="5" fill="rgba(239,106,95,0.10)" stroke="#ef6a5f" strokeDasharray="4 3"/>
|
||||
<text x="76" y="158" fontSize="10" textAnchor="middle" fill="#ef6a5f">Day 1</text>
|
||||
<text x="76" y="172" fontSize="9" textAnchor="middle" fill="#ef6a5f">removed</text>
|
||||
<g fill="rgba(255,255,255,0.04)" stroke="rgba(255,255,255,0.28)">
|
||||
<rect x="115" y="138" width="62" height="46" rx="5"/>
|
||||
<rect x="185" y="138" width="62" height="46" rx="5"/>
|
||||
<rect x="255" y="138" width="62" height="46" rx="5"/>
|
||||
<rect x="325" y="138" width="62" height="46" rx="5"/>
|
||||
<rect x="395" y="138" width="62" height="46" rx="5"/>
|
||||
<rect x="465" y="138" width="62" height="46" rx="5"/>
|
||||
</g>
|
||||
<g fontSize="10" textAnchor="middle" fill="#c6d2e1">
|
||||
<text x="146" y="165">Day 2</text>
|
||||
<text x="216" y="165">Day 3</text>
|
||||
<text x="286" y="165">Day 4</text>
|
||||
<text x="356" y="165">Day 5</text>
|
||||
<text x="426" y="165">Day 6</text>
|
||||
<text x="496" y="165">Day 7</text>
|
||||
</g>
|
||||
<rect x="535" y="138" width="62" height="46" rx="5" fill="rgba(86,194,136,0.14)" stroke="#56c288"/>
|
||||
<text x="566" y="158" fontSize="10" textAnchor="middle" fill="#56c288">Day 8</text>
|
||||
<text x="566" y="172" fontSize="9" textAnchor="middle" fill="#56c288">new</text>
|
||||
<line x1="535" y1="196" x2="94" y2="196" stroke="#e0a94a" strokeDasharray="5 4" className="schema-flow"/>
|
||||
<polygon points="82,196 94,192 94,200" fill="#e0a94a"/>
|
||||
<text x="320" y="232" fontSize="10.5" textAnchor="middle" fill="#e0a94a">Retention = 7: creating today's snapshot removes the oldest one</text>
|
||||
</svg>
|
||||
</Schema>
|
||||
|
||||
## Creating a rolling snapshot job
|
||||
|
||||
Rolling snapshots are configured like any other backup job:
|
||||
|
||||
1. Go to the **Backup** view and create a new backup job.
|
||||
2. Select **Rolling snapshot** as the job type.
|
||||
3. Select the VMs to snapshot, either explicitly or with smart mode (dynamic selection based on pools, tags and power state, so new matching VMs are included automatically).
|
||||
4. Define the schedule (when snapshots are taken) and the snapshot retention (how many to keep).
|
||||
5. Save the job. It will now run on its own, and you can also trigger it manually at any time.
|
||||
|
||||
To roll back, open the VM's **Snapshots** tab and revert to the restore point you want.
|
||||
|
||||
## Scheduling examples
|
||||
|
||||
- Nightly snapshot, for example at 4:30 AM, with a retention of 7: you can revert any VM in the job to any of the last seven days.
|
||||
- Weekly snapshot, for example Sunday at 11:00 PM, with a retention of 4: about a month of rollback capability, at a coarser granularity.
|
||||
- Combine both in two separate jobs if you want short-term granularity and a longer safety net at the same time.
|
||||
|
||||
## Caveats
|
||||
|
||||
:::tip
|
||||
On thick-provisioned storage (LVM-based SRs: iSCSI, HBA, local LVM), every snapshot reserves the full virtual size of the disk on the SR. Seven rolling snapshots of a 200 GiB disk can claim more than 1.4 TiB. Avoid rolling snapshots for large VMs on these SRs, or keep the retention very low. Thin-provisioned storage (local ext, NFS, XOSTOR) only consumes space for the actual changes.
|
||||
:::
|
||||
|
||||
- **Coalesce load**: deleting a snapshot triggers coalesce work on the SR to merge the disk chain back together. If snapshots rotate faster than the SR can coalesce (very frequent schedules on slow storage), chains pile up and Xen Orchestra will skip the VM to protect it. See [VDI chain protection](xo5/backup_troubleshooting.md#vdi-chain-protection) for details.
|
||||
- **Reverting is destructive**: rolling a VM back to a snapshot discards everything that happened after that snapshot was taken. If you are not sure you want to lose the current state, snapshot it first, then revert.
|
||||
|
||||
## When to use it
|
||||
|
||||
Rolling snapshots shine as a cheap, fast undo button: before risky changes, on dev and test VMs, or as a short-term rollback layer on top of a proper backup policy. They cost nothing to set up, need no backup repository, and restore in seconds.
|
||||
|
||||
They are not a protection layer: they will not survive the loss of the SR, a corrupted storage, or a host disaster. Once your rolling snapshots are in place, head over to the [Backup strategy guide](backup_howto.md) to design real protection, with [incremental backups](xo5/incremental_backups.md) as the natural next step: they reuse the same snapshot mechanism, but export the data to a separate backup repository where a storage failure can't reach it.
|
||||
@@ -0,0 +1,57 @@
|
||||
# Host compatibility list
|
||||
|
||||
Xen Orchestra connects to hosts running [XCP-ng](https://xcp-ng.org/) or [XenServer](https://www.xenserver.com/) (formerly Citrix Hypervisor), and only those: XO is **agent-less** and talks to the XAPI toolstack directly, so a Xen hypervisor installed from a regular Linux distribution will not work (see the [architecture section](architecture.md)).
|
||||
|
||||
Xen Orchestra should be functional with any version of these two platforms. For the best support quality, use the versions marked with full support below.
|
||||
|
||||
| Badge | Meaning |
|
||||
|:---:|---|
|
||||
| ✅ | Full support |
|
||||
| 🚀 | All extra features (for example RAM-enabled backup) |
|
||||
| ☠️ | Platform without security updates anymore: upgrade your hosts! |
|
||||
| ❎ | Not all XO features supported |
|
||||
|
||||
## XCP-ng
|
||||
|
||||
Xen Orchestra and XCP-ng are built by the same company ([Vates](https://vates.tech)) and ship together as [Vates VMS](https://docs.vates.tech/): one subscription covers the XCP-ng licenses for all your hosts and your Xen Orchestra Appliance, and each monthly release is tested as a stack. If you run the bundle and keep it updated, XO and XCP-ng compatibility is a given.
|
||||
|
||||
The table below matters if you run XO from the sources, manage a mixed estate, or still have pools on older XCP-ng releases:
|
||||
|
||||
<HostCompatTable rows={[
|
||||
{version: 'XCP-ng 8.3 LTS', status: '✅ 🚀', notes: 'Recommended: LTS since June 2025, all XO features', highlight: true},
|
||||
{version: 'XCP-ng 8.2 LTS', status: '✅ ☠️', eol: true, notes: 'EOL since September 16, 2025'},
|
||||
{version: 'XCP-ng 8.1', status: '✅ ☠️', eol: true},
|
||||
{version: 'XCP-ng 8.0', status: '✅ ☠️', eol: true},
|
||||
{version: 'XCP-ng 7.6', status: '✅ ☠️', eol: true},
|
||||
{version: 'XCP-ng 7.5', status: '✅ ☠️', eol: true},
|
||||
{version: 'XCP-ng 7.4', status: '✅ ☠️', eol: true},
|
||||
]} />
|
||||
|
||||
:::note
|
||||
The next major branch, XCP-ng 9.x, is in development for both x86 and ARM; its releases will appear here as they ship. Follow the [XCP-ng blog](https://xcp-ng.org/blog/) for announcements.
|
||||
:::
|
||||
|
||||
## XenServer (formerly Citrix Hypervisor)
|
||||
|
||||
:::note
|
||||
XenServer versioning changed over the years: the product was renamed Citrix Hypervisor for the 8.0 to 8.2 era, then back to XenServer. Since XenServer 8 there are no public point releases: versions are plain "XenServer 8" and "XenServer 9", each updated continuously through Early Access and Normal update channels.
|
||||
:::
|
||||
|
||||
<HostCompatTable rows={[
|
||||
{version: 'XenServer 9', status: '✅', notes: 'Released July 2026, vendor support until July 31, 2031', highlight: true},
|
||||
{version: 'XenServer 8', status: '✅', notes: 'Vendor support until November 30, 2028', highlight: true},
|
||||
{version: 'Citrix Hypervisor 8.2 LTS', status: '✅ ☠️', eol: true, notes: 'Vendor EOL since June 25, 2025'},
|
||||
{version: 'Citrix Hypervisor 8.1', status: '✅ ☠️', eol: true},
|
||||
{version: 'Citrix Hypervisor 8.0', status: '✅ ☠️', eol: true},
|
||||
{version: 'XenServer 7.6', status: '✅ ☠️', eol: true},
|
||||
{version: 'XenServer 7.5', status: '✅ ☠️', eol: true, notes: 'VDI I/O error (Citrix ticket XSO-873), fix never released by Citrix'},
|
||||
{version: 'XenServer 7.4', status: '✅ ☠️', eol: true},
|
||||
{version: 'XenServer 7.3', status: '✅ ☠️', eol: true},
|
||||
{version: 'XenServer 7.2', status: '❎ ☠️', eol: true, notes: 'JSON-RPC issues: possible INTERNAL_ERROR during incremental replication and incremental backup restore'},
|
||||
{version: 'XenServer 7.1 LTS', status: '✅ ☠️', eol: true},
|
||||
{version: 'XenServer 7.0', status: '✅ ☠️', eol: true},
|
||||
{version: 'XenServer 6.5', status: '✅ ☠️', eol: true, notes: 'Random delta backup issues'},
|
||||
{version: 'XenServer 6.1 and 6.2', status: '❎ ☠️', eol: true, notes: 'No official support (XML-RPC only, too CPU intensive); no incremental backup, no incremental replication'},
|
||||
{version: 'XenServer 5.x', status: '❎ ☠️', eol: true, notes: 'Basic administration only, no official support'},
|
||||
]} />
|
||||
|
||||
@@ -0,0 +1,229 @@
|
||||
# Troubleshooting
|
||||
|
||||
This page covers the problems you may encounter with your XOA, and how to get out of them.
|
||||
|
||||
:::warning
|
||||
If you have issues with an XO installed [from the sources](install-from-sources.md), please go through the [community support checklist](community.md) first.
|
||||
:::
|
||||
|
||||
## First reflex: `xoa check`
|
||||
|
||||
Whenever something feels wrong, start with the built-in check:
|
||||
|
||||
<Terminal title="xoa — health check">{`
|
||||
xoa check
|
||||
✔ Node version
|
||||
✔ Disk space for /var
|
||||
✔ Disk space for /
|
||||
✔ XOA version
|
||||
✔ xo-server config syntax
|
||||
✔ Appliance registration
|
||||
✔ Internet connectivity
|
||||
`}</Terminal>
|
||||
|
||||
Anything other than a clean list of green ticks (errors, lost packets, missing entries) points at the problem area. Then look for the matching section below, and check the [logs](#logs).
|
||||
|
||||
## Deployment issues
|
||||
|
||||
### Deploy error: no default SR
|
||||
|
||||
> Auto deploy failed. - No SR specified and Pool default SR is null
|
||||
|
||||
The pool you are importing XOA on has no default storage repository. Find the UUID of the SR you want:
|
||||
|
||||
<Terminal shell title="host — list storage repositories">{`
|
||||
xe sr-list
|
||||
`}</Terminal>
|
||||
|
||||
then set it as the pool default (press Tab after `uuid=` to autofill your pool UUID):
|
||||
|
||||
<Terminal shell title="host — set the default SR">{`
|
||||
xe pool-param-set uuid=<pool-uuid> default-SR=<sr-uuid>
|
||||
`}</Terminal>
|
||||
|
||||
Run the deploy again: it will work.
|
||||
|
||||
### XOA unreachable, or starts then shuts down after a few seconds
|
||||
|
||||
XOA runs in HVM mode, which requires hardware virtualization extensions (any hardware since roughly 2011). Check on your host:
|
||||
|
||||
<Terminal shell title="host — check virtualization extensions">{`
|
||||
grep -cE 'vmx|svm' /proc/cpuinfo
|
||||
`}</Terminal>
|
||||
|
||||
A result of `0` means the extensions are absent or disabled: enable virtualization in your BIOS/UEFI settings, or XOA cannot run on this hardware.
|
||||
|
||||
## Access issues
|
||||
|
||||
### Set or recover the XOA VM password
|
||||
|
||||
No password is set for the `xoa` system user by default. Set (or reset) one through the XenStore data of the VM, from your XCP-ng host:
|
||||
|
||||
<Terminal shell title="host — set the xoa user password">{`
|
||||
xe vm-param-set uuid=<UUID> xenstore-data:vm-data/system-account-xoa-password=<password>
|
||||
`}</Terminal>
|
||||
|
||||
Restart the VM, then log in over SSH with the `xoa` user and that password.
|
||||
|
||||
### Recover the web login password
|
||||
|
||||
From the XOA CLI (see [first console connection](installation.md#first-console-connection)):
|
||||
|
||||
<Terminal shell title="xoa — reset a web account password">{`
|
||||
sudo xo-server-recover-account [email protected]
|
||||
`}</Terminal>
|
||||
|
||||
It prompts for a new password. If the email does not exist in XO yet, an admin account is created with it: handy as a rescue account.
|
||||
|
||||
### Empty page after login
|
||||
|
||||
Your antivirus or firewall is blocking WebSockets, the protocol XO clients use to talk to `xo-server` (see [architecture](architecture.md)). Switch to **HTTPS**: WebSockets are then encapsulated in TLS, out of reach of the interception.
|
||||
|
||||
### User login failures
|
||||
|
||||
Look at the `xo-server` [logs](#logs) while reproducing the login attempt: the reason is displayed there.
|
||||
|
||||
## Logs
|
||||
|
||||
- **From the web interface**: Settings, then Logs.
|
||||
- **From the CLI**, with `journalctl`:
|
||||
|
||||
<Terminal shell title="xoa — tail xo-server logs">{`
|
||||
journalctl -u xo-server -f -n 50
|
||||
`}</Terminal>
|
||||
|
||||
<Terminal shell title="xoa — tail updater logs">{`
|
||||
journalctl -u xoa-updater -f -n 50
|
||||
`}</Terminal>
|
||||
|
||||
Start the tail, reproduce your issue, and read the error as it happens.
|
||||
|
||||
## Runtime issues
|
||||
|
||||
### Migration of the XOA VM fails
|
||||
|
||||
XOA ships with a static max memory of 16 GiB, which can break its own live migration:
|
||||
|
||||
```
|
||||
"Failed","Migrating VM 'XOA' from '<origin_hostname>' to '<destination_hostname>'
|
||||
Internal error: Xenops_interface.Internal_error("Domain.Xenguest_failure(\"Error while waiting for suspend notification…\")")
|
||||
```
|
||||
|
||||
Reduce the static max memory of the XOA VM to a lower value and migrate again.
|
||||
|
||||
### xo-server out of memory
|
||||
|
||||
If `xo-server` crashes with `FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory` in its logs, give it more room, in two steps.
|
||||
|
||||
First, increase the memory of the XOA VM itself (4 or 8 GiB).
|
||||
|
||||
Then raise the memory limit of the `xo-server` process: edit `/etc/systemd/system/xo-server.service` and find this line:
|
||||
|
||||
```ini
|
||||
ExecStart=/usr/local/bin/xo-server
|
||||
```
|
||||
|
||||
Replace it with the following line, where the number is your VM memory in MiB minus about 512 MiB for the OS (for a 4096 MiB VM, use 3584):
|
||||
|
||||
```ini
|
||||
ExecStart=/usr/local/bin/node --max-old-space-size=3584 /usr/local/bin/xo-server
|
||||
```
|
||||
|
||||
<Terminal shell title="xoa — apply the service change">{`
|
||||
systemctl daemon-reload
|
||||
`}</Terminal>
|
||||
|
||||
<Terminal shell title="xoa — restart xo-server">{`
|
||||
systemctl restart xo-server
|
||||
`}</Terminal>
|
||||
|
||||
### Stats not showing on a pool
|
||||
|
||||
If statistics are missing for all VMs and hosts of one specific pool, check whether a _Backup network_ is configured on it (pool Advanced tab), and make sure XO can reach **all hosts** of the pool through that network.
|
||||
|
||||
### Ghost tasks
|
||||
|
||||
If ghost tasks accumulate, try in order:
|
||||
|
||||
1. refresh the web page
|
||||
2. disconnect and reconnect the pool owning the tasks
|
||||
3. restart the XAPI toolstack of the XCP-ng pool master
|
||||
4. restart `xo-server`
|
||||
|
||||
## Network issues
|
||||
|
||||
Check the current configuration with `ip addr` (the default interface is `enX0` or `eth0`), and make sure any external firewall allows the XOA IP. Reconfigure with `xoa network static` or `xoa network dhcp`, as described in [Network configuration](installation.md#network-configuration).
|
||||
|
||||
## Updater issues
|
||||
|
||||
### Behind a transparent proxy
|
||||
|
||||
Transparent proxies usually break the updater with SSL/TLS errors. Allow it to work:
|
||||
|
||||
<Terminal shell title="xoa — as root">{`
|
||||
sudo -s
|
||||
echo NODE_TLS_REJECT_UNAUTHORIZED=0 >> /etc/xo-appliance/env
|
||||
npm config -g set strict-ssl=false
|
||||
systemctl restart xoa-updater
|
||||
`}</Terminal>
|
||||
|
||||
Then run the update again.
|
||||
|
||||
### Redownload and rebuild packages
|
||||
|
||||
If a package disappeared after a failed build or a manual mistake:
|
||||
|
||||
<Terminal shell title="xoa — force the updater to redownload">{`
|
||||
rm /var/lib/xoa-updater/update.json
|
||||
xoa-updater --upgrade
|
||||
`}</Terminal>
|
||||
|
||||
## Renew the self-signed certificate
|
||||
|
||||
If the provided certificate expired, generate a new one, as root on the appliance:
|
||||
|
||||
<Terminal shell title="xoa — regenerate the certificate">{`
|
||||
cd /etc/ssl
|
||||
cp cert.pem cert.pem-old
|
||||
cp key.pem key.pem-old
|
||||
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -nodes -days 360
|
||||
systemctl restart xo-server.service
|
||||
`}</Terminal>
|
||||
|
||||
## Reset the configuration
|
||||
|
||||
Last resort: reset the `xo-server` database. **This deletes all configured users, servers and backup jobs.**
|
||||
|
||||
<Terminal shell title="xoa — full reset">{`
|
||||
redis-cli
|
||||
FLUSHALL
|
||||
systemctl restart xo-server.service
|
||||
`}</Terminal>
|
||||
|
||||
You can then log in again with `[email protected]` / `admin`.
|
||||
|
||||
## Backup issues
|
||||
|
||||
Backups have their own page: [Backup troubleshooting](xo5/backup_troubleshooting.md).
|
||||
|
||||
## Still stuck?
|
||||
|
||||
Open a ticket from your personal space on [account.vates.tech](https://account.vates.tech): describe the issue, and attach the `xoa check` output and the relevant logs.
|
||||
|
||||
### Open a support tunnel {#support-tunnel}
|
||||
|
||||
XOA is the only way to get our pro support, which can investigate remotely through a secure SSH tunnel. Our team will ask you for a "support ID": you get it by opening the tunnel, either from the web UI (XOA menu, **Support** section) or from the CLI if the web UI is not reachable:
|
||||
|
||||
<Terminal title="open a secure support tunnel">{`
|
||||
xoa support tunnel
|
||||
The support tunnel has been created.
|
||||
|
||||
Do not stop this command before the intervention is over!
|
||||
Give this id to the support: 40713
|
||||
`}</Terminal>
|
||||
|
||||
Give this number to the support team: only Vates holds the private key for the tunnel. Close it with `Ctrl+C` once your issue is solved.
|
||||
|
||||
:::tip
|
||||
The tunnel uses the bundled `xoa-support` user. You can deactivate this account with `chage -E 0 xoa-support`, and re-activate it with `chage -E 1 xoa-support`.
|
||||
:::
|
||||
@@ -5,7 +5,11 @@ All updates are pushed through the updater, which is the central piece that keep
|
||||
It also allows you to change your current version into another (Free, Starter, Enterprise or Premium) **without downloading a new XOA**.
|
||||
|
||||
:::tip
|
||||
By design, the updater is only available in XOA. If you are using XO from the sources, you'll have to use `git` commands and rebuild to keep up.
|
||||
By design, the updater is only available in XOA. If you are using XO from the sources, [update with `git` and rebuild](install-from-sources.md#updating).
|
||||
:::
|
||||
|
||||
:::info Updating from XO 6
|
||||
Updates are not managed from the XO 6 interface yet. From XO 6, click the **XO 5** link in the top-right corner, then open the **XOA → Updates** view: everything below happens there. Your appliance and both interfaces update together.
|
||||
:::
|
||||
|
||||
## Requirements
|
||||
@@ -20,27 +24,27 @@ The updater is configurable directly from the web interface, or via the CLI.
|
||||
|
||||
The updater is available in the "Update" menu:
|
||||
|
||||

|
||||
<UiDetail src="/img/xoa/update-menu.png" alt="The Updates entry in the XOA menu" width={420} />
|
||||
|
||||
You can see the yellow bell icon: it means your appliance is not registered. You **must register in order to have updates and a trial**.
|
||||
|
||||

|
||||
<UiDetail src="/img/xoa/update-tooltip.png" alt="A yellow bell: the appliance is not registered yet" width={420} />
|
||||
|
||||
#### Register
|
||||
|
||||
Updates and trials will be available as soon as you register your appliance. To register, use your https://xen-orchestra.com credentials you gave to download it previously (your email and your password):
|
||||
Updates and trials will be available as soon as you register your appliance. To register, use your [account.vates.tech](https://account.vates.tech) credentials (your email and your password):
|
||||
|
||||

|
||||
<UiDetail src="/img/xoa/register.png" alt="Registering with your xen-orchestra.com account" width={520} />
|
||||
|
||||
#### Check for new versions
|
||||
|
||||
The updater will check for new versions periodically. A green tick in the menu means your version is up to date:
|
||||
|
||||

|
||||
<UiDetail src="/img/xoa/update-ok.png" alt="Green tick: the appliance is up to date" width={420} />
|
||||
|
||||
However, if you want to start a manual check, you can do it by clicking on the "Update" button:
|
||||
|
||||

|
||||
<UiDetail src="/img/xoa/update-button.png" alt="Trigger a manual check with the Update button" width={420} />
|
||||
|
||||
### Release channel
|
||||
|
||||
@@ -56,20 +60,20 @@ The latest channel will include all the latest improvements available in Xen Orc
|
||||
|
||||
:::tip
|
||||
To select the release channel of your choice, go to the XOA > Updates view:
|
||||

|
||||
<UiDetail src="/img/xoa/release-channels.png" alt="Choosing the release channel in the XOA Updates view" width={520} />
|
||||
:::
|
||||
|
||||
### Upgrade
|
||||
|
||||
If a new version is found, you'll have an upgrade button and its tooltip displayed:
|
||||
|
||||

|
||||
<UiDetail src="/img/xoa/update-available.png" alt="An upgrade is available" width={420} />
|
||||
|
||||
### Proxy configuration
|
||||
|
||||
If you are behind a proxy, you can edit your proxy settings in this panel:
|
||||
|
||||

|
||||
<UiDetail src="/img/xoa/proxy-settings.png" alt="Updater proxy settings" width={520} />
|
||||
|
||||
### From the CLI
|
||||
|
||||
@@ -77,8 +81,8 @@ If your interface is not accessible, or you just prefer to use CLIs commands, it
|
||||
|
||||
#### Register
|
||||
|
||||
```console
|
||||
$ xoa-updater --register
|
||||
<Terminal title="xoa — register the appliance">{`
|
||||
xoa-updater --register
|
||||
Successfully connected to xoa-updater-service
|
||||
|
||||
Please enter your xen-orchestra.com identifiers to register your XOA:
|
||||
@@ -86,24 +90,24 @@ Please enter your xen-orchestra.com identifiers to register your XOA:
|
||||
? Password: *****
|
||||
|
||||
ℹ Your Xen Orchestra Appliance has been successfully registered
|
||||
```
|
||||
`}</Terminal>
|
||||
|
||||
#### Check for new versions
|
||||
|
||||
```console
|
||||
$ xoa-updater
|
||||
<Terminal title="xoa — check for new versions">{`
|
||||
xoa-updater
|
||||
Successfully connected to xoa-updater-service
|
||||
Checking new versions...ok ✔
|
||||
New versions available:
|
||||
xo-server 4.8.1
|
||||
|
||||
ℹ xoa-updater may be run again to upgrade packages
|
||||
```
|
||||
`}</Terminal>
|
||||
|
||||
#### Upgrade
|
||||
|
||||
```console
|
||||
$ xoa-updater --upgrade
|
||||
<Terminal title="xoa — upgrade">{`
|
||||
xoa-updater --upgrade
|
||||
Successfully connected to xoa-updater-service
|
||||
Checking new versions...ok ✔
|
||||
New versions available:
|
||||
@@ -113,11 +117,15 @@ Downloading packages...
|
||||
Installing new packages...
|
||||
|
||||
✔ Your XOA has been successfully updated.
|
||||
```
|
||||
`}</Terminal>
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
If your updater is down, you can restart it with `systemctl restart xoa-updater`.
|
||||
If your updater is down, restart it:
|
||||
|
||||
<Terminal shell title="xoa — restart the updater">{`
|
||||
systemctl restart xoa-updater
|
||||
`}</Terminal>
|
||||
|
||||
If you can't fetch updates, perform a few checks from your XOA:
|
||||
|
||||
@@ -126,20 +134,22 @@ If you can't fetch updates, perform a few checks from your XOA:
|
||||
- use `ifconfig` to check your network configuration
|
||||
- check your firewall(s) and allow XOA to reach xen-orchestra.com (port 443)
|
||||
|
||||
## XenServer Updates
|
||||
## XenServer updates {#xenserver-updates}
|
||||
|
||||
Starting September 2023, XenServer Updates require authentication:
|
||||
Xen Orchestra can install XenServer hotfixes on your pools directly, from a pool's **Patches** view. Since September 2023, XenServer requires authentication to download hotfixes, so XO needs your **XenServer Client ID** credentials to fetch them on your behalf:
|
||||
|
||||
1. Make sure your XenServer hosts have [the proper licenses](https://docs.xenserver.com/en-us/citrix-hypervisor/overview-licensing.html)
|
||||
1. Make sure your XenServer hosts have [the proper licenses](https://docs.xenserver.com/en-us/xenserver/8/overview-licensing).
|
||||
2. Get your Client ID file (`xencenter_client_id.json`), which contains the username and API key XO will use.
|
||||
3. In Xen Orchestra, open your **User Settings** page (bottom left-hand corner) and upload the file in the "XenServer Client ID" section:
|
||||
|
||||
2. Go to any XenServer Update URL like [this one](https://support.citrix.com/article/CTX277443/hotfix-xs81e006-for-citrix-hypervisor-81) and log in to check that your account has permissions to download updates. You should see a "Download" button.
|
||||
<UiDetail src="/img/xoa/xs-client-id-upload.png" alt="Uploading xencenter_client_id.json in your XO user settings" width={520} />
|
||||
|
||||
3. Go to this URL: [https://support.citrix.com/xencenterclientiddownload](https://support.citrix.com/xencenterclientiddownload) and click "Download Client ID"
|
||||
4. Go to a pool's **Patches** view and install the updates. A `LICENCE_RESTRICTION` error means your hosts are missing XenServer licenses.
|
||||
|
||||

|
||||
:::warning
|
||||
Citrix removed the self-service Client ID download page from its support portal. If you already have your `xencenter_client_id.json`, XO keeps using it; to obtain new credentials, go through Citrix support. Note that this hotfix mechanism concerns Citrix Hypervisor 8.2 CU1 and older (now end of life): XenServer 8 and 9 hosts fetch their updates themselves from the `ops.xenserver.com` channels, with XO showing the missing patches per pool and host.
|
||||
:::
|
||||
|
||||
4. In Xen Orchestra, go to your User Settings page (bottom left-hand corner) and upload the file `xencenter_client_id.json` you just downloaded from the "XenServer Client ID" section
|
||||
|
||||

|
||||
|
||||
5. Go to a pool's "Patches" page. You can now install XenServer Updates. If you get a `LICENCE_RESTRICTION` error, it means that [you're missing XenServer licenses on your hosts](https://docs.xenserver.com/en-us/citrix-hypervisor/overview-licensing.html).
|
||||
:::tip
|
||||
This authentication story only concerns XenServer. XCP-ng updates are plain RPM repositories, fully handled from Xen Orchestra: see the [XCP-ng updates documentation](https://docs.xcp-ng.org/management/updates/).
|
||||
:::
|
||||
@@ -1,3 +1,7 @@
|
||||
---
|
||||
sidebar_label: Windows templates with Cloudbase-init
|
||||
---
|
||||
|
||||
# Windows Templates with Cloudbase-init: Step-by-step Guide & Best Practices
|
||||
|
||||
This section provides step-by-step instructions for creating Windows templates that support cloud-init, using [Cloudbase-init](https://cloudbase.it/cloudbase-init/).
|
||||
@@ -9,7 +13,7 @@ From this master VM, you can branch out *template VMs* and customize them with d
|
||||
Finally, these template VMs will be generalized with Sysprep and converted into templates that can be used for VM creation.
|
||||
See the following diagram:
|
||||
|
||||

|
||||
<UiDetail src="/img/windows-templates/overview.png" alt="Overview diagram" width={620} />
|
||||
|
||||
Here is a list of steps for preparing a Windows template:
|
||||
|
||||
@@ -50,13 +54,13 @@ We highly recommend starting from the default Windows templates, as they contain
|
||||
Use at least 4 vCPUs and 4 GB of RAM to ensure that the update process goes smoothly.
|
||||
:::
|
||||
|
||||

|
||||
<UiDetail src="/img/windows-templates/1-audit1.png" alt="Windows OOBE screen" width={700} />
|
||||
|
||||
*Master VM: Press Ctrl+Shift+F3 here to enter Audit mode.*
|
||||
|
||||
Windows will automatically restart, and you will be presented with the Sysprep GUI as follows.
|
||||
|
||||

|
||||
<UiDetail src="/img/windows-templates/1-audit2.png" alt="Windows in Audit mode, with Sysprep window visible" width={700} />
|
||||
|
||||
*Master VM: Windows in Audit mode*
|
||||
|
||||
@@ -76,14 +80,14 @@ As its name indicated, this VM will become your new Windows template for future
|
||||
Use a full VM copy (**Copy** button) to avoid having too many VM disk layers, which may degrade performance.
|
||||
:::
|
||||
|
||||

|
||||
<UiDetail src="/img/windows-templates/1-copyvm.png" alt="Copy VM" width={620} />
|
||||
|
||||
## Installing software in template
|
||||
|
||||
You can install any software you need in this template.
|
||||
In this example, we install the XenServer VM Tools:
|
||||
|
||||

|
||||
<UiDetail src="/img/windows-templates/2-winpv2.png" alt="XenServer VM Tools Setup Settings" width={700} />
|
||||
|
||||
You can freely restart the VM when prompted.
|
||||
Once restarted, the VM will go back to Audit mode until you run Sysprep again.
|
||||
@@ -92,11 +96,11 @@ Once restarted, the VM will go back to Audit mode until you run Sysprep again.
|
||||
|
||||
Grab the latest installer from [cloudbase.it](https://cloudbase.it/cloudbase-init/) and start the installation process.
|
||||
|
||||

|
||||
<UiDetail src="/img/windows-templates/2-cbi1.png" alt="Installing Cloudbase-init" width={700} />
|
||||
|
||||
Don't run Sysprep yet; you still need to configure Cloudbase-init.
|
||||
|
||||

|
||||
<UiDetail src="/img/windows-templates/2-cbi2.png" alt="Cloudbase-init is installed, don't sysprep yet" width={700} />
|
||||
|
||||
Enter the directory `C:\Program Files\Cloudbase Solutions\Cloudbase-Init\conf`.
|
||||
You will find the following two files: `cloudbase-init.conf` and `cloudbase-init-unattend.conf`.
|
||||
@@ -108,7 +112,7 @@ metadata_services=cloudbaseinit.metadata.services.nocloudservice.NoCloudConfigDr
|
||||
|
||||
This line makes sure Cloudbase-init uses the NoCloud configuration drive (as generated by XO) as its data source.
|
||||
|
||||

|
||||
<UiDetail src="/img/windows-templates/3-cbi.png" alt="Configuring cloudbase-init.conf" width={700} />
|
||||
|
||||
Your VM is now ready for conversion to template.
|
||||
|
||||
@@ -127,7 +131,7 @@ C:\Windows\System32\Sysprep\sysprep.exe /generalize /oobe /shutdown "/unattend:C
|
||||
|
||||
Once the Sysprep process is complete, your template VM will shut down.
|
||||
|
||||

|
||||
<UiDetail src="/img/windows-templates/4-sysprep.png" alt="Sysprep is running" width={700} />
|
||||
|
||||
Convert your VM to a template; do not start it again or the cloud-init configuration process will begin.
|
||||
|
||||
@@ -135,7 +139,7 @@ Convert your VM to a template; do not start it again or the cloud-init configura
|
||||
|
||||
Create VMs from your prepared template and enter your cloud-init configs as necessary.
|
||||
|
||||

|
||||
<UiDetail src="/img/windows-templates/5-instantiate.png" alt="Create VM from template" width={700} />
|
||||
|
||||
:::tip
|
||||
Refer to the [Cloudbase-init plugins documentation](https://cloudbase-init.readthedocs.io/en/latest/plugins.html) for information on how to configure cloud-init for Windows guests.
|
||||
@@ -143,11 +147,11 @@ Refer to the [Cloudbase-init plugins documentation](https://cloudbase-init.readt
|
||||
|
||||
Your VMs will reboot several times during the unsealing process.
|
||||
|
||||

|
||||
<UiDetail src="/img/windows-templates/5-unseal.png" alt="Windows is getting ready" width={700} />
|
||||
|
||||
Enjoy your finished product!
|
||||
|
||||

|
||||
<UiDetail src="/img/windows-templates/6-finish.png" alt="VM with hostname set as desired" width={700} />
|
||||
|
||||
## Tips and tricks
|
||||
|
||||
|
||||
+28
-26
@@ -1,5 +1,7 @@
|
||||
# Advanced features
|
||||
|
||||
<InterfaceNote />
|
||||
|
||||
This section is dedicated to all others Xen Orchestra "advanced features".
|
||||
|
||||
## Live Telemetry
|
||||
@@ -14,7 +16,7 @@ This feature will be only available in XCP-ng+XOA. If you are a hardcore Citrix
|
||||
|
||||
Go into the Advanced host view:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/telemetry-enable.png" alt="The Advanced Live Telemetry button, in the host Advanced tab" width={700} />
|
||||
|
||||
By clicking here, XOA will handle everything: installing netdata on the host, and configure a secured/encrypted streaming toward your XOA.
|
||||
|
||||
@@ -24,7 +26,7 @@ As soon it's installed, the button will now be replaced by a "Go to Advanced Liv
|
||||
|
||||
IMPI info (power, temperatures, voltages, fans…):
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/telemetry-ipmi.png" alt="IPMI data in netdata: power, temperatures, voltages, fans" width={620} />
|
||||
|
||||
:::tip
|
||||
This feature is only available in one-click in your XOA. However, all sources and packages to do it yourself are available!
|
||||
@@ -32,11 +34,11 @@ This feature is only available in one-click in your XOA. However, all sources an
|
||||
|
||||
Memory details:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/telemetry-memory.png" alt="Detailed memory metrics" width={620} />
|
||||
|
||||
Firewall:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/telemetry-firewall.png" alt="Firewall activity" width={620} />
|
||||
|
||||
## Hardware Monitoring
|
||||
|
||||
@@ -47,7 +49,7 @@ Xen Orchestra makes it easy to monitor disk health using a XAPI plugin for XCP-n
|
||||
- **Healthy Disks:** If all disks are in good condition, Xen Orchestra shows: **All disks are healthy ✅**.
|
||||
- **Unhealthy Disks:** If any issues are detected, a warning icon appears, indicating how many disks are affected:
|
||||
|
||||

|
||||
<UiDetail src="/img/disk-health-warning.png" alt="A host with disks reporting SMART issues" width={480} />
|
||||
|
||||
## Web hooks
|
||||
|
||||
@@ -149,7 +151,7 @@ Those alerts will be also stored and accessible in the web interface, and also l
|
||||
### Update alerts
|
||||
|
||||
:::warning
|
||||
:construction_worker: This feature might be missing. We are investigating. :construction_worker:
|
||||
This feature might currently be missing. We are investigating.
|
||||
:::
|
||||
|
||||
When your XOA detects new packages, you'll be notified by email.
|
||||
@@ -171,7 +173,7 @@ The key idea is to be able to schedule any action (migrate, reboot etc.), for th
|
||||
|
||||
In the main menu, go to the "Job Manager" section:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/jobmanager.png" alt="The Job Manager entry, in the main menu" width={240} />
|
||||
|
||||
You can now **schedule all actions** on your hosts, VMs, or ACLs. It's configured in 2 steps:
|
||||
|
||||
@@ -180,7 +182,7 @@ You can now **schedule all actions** on your hosts, VMs, or ACLs. It's configure
|
||||
|
||||
Real example, step by step: **Creating a job called "security reboot"** (in this case, restarting "nfs" and "Core1" VMs):
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/job_create.png" alt="Create a job: pick the action and the target VMs" width={700} />
|
||||
|
||||
Note that you can execute this job **now** by clicking on the orange play button (to test it for instance):
|
||||
|
||||
@@ -188,11 +190,11 @@ Note that you can execute this job **now** by clicking on the orange play button
|
||||
|
||||
**Schedule the job** (every Sunday at 5:00 AM):
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/schedule_job.png" alt="Schedule the job: every Sunday at 5:00 AM" width={700} />
|
||||
|
||||
And that's it! The job is listed in the Overview:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/schedule_recap.png" alt="The job is now listed in the Overview" width={700} />
|
||||
|
||||
The possibilities are infinite! You can schedule a **lot** of things (any actions on a VM, like migrate, start, clone, suspend etc. Same thing also applies to hosts).
|
||||
|
||||
@@ -226,18 +228,18 @@ If you have a UPS for your hosts, and lose power, you may have a limited amount
|
||||
|
||||
On the host view, clicking on this button will trigger the _Emergency Shutdown_ procedure:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/e-shutdown-1.png" alt="The Emergency Shutdown button, in the host view" width={340} />
|
||||
|
||||
1. **All running VMs will be suspended** (think of it like "hibernate" on your laptop: the RAM will be stored in the storage repository).
|
||||
2. Only after this is complete, the host will be halted.
|
||||
|
||||
Here, you can see the running VMs are being suspended:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/e-shutdown-2.png" alt="Running VMs being suspended" width={620} />
|
||||
|
||||
And finally, that's it. They are cleanly shut down with the RAM saved to disk to be resumed later:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/e-shutdown-3.png" alt="All VMs suspended, with their RAM saved to disk" width={620} />
|
||||
|
||||
Now the host is halted automatically.
|
||||
|
||||
@@ -270,9 +272,9 @@ From there, you can even manage your existing resources with Terraform!
|
||||
|
||||
Synchronize your pools, VMs, network interfaces and IP addresses with your [Netbox](https://docs.netbox.dev/en/stable/) instance.
|
||||
|
||||

|
||||
<UiShot light="/img/xo5/netbox.png" alt="Your XO pools, VMs and IP addresses, synchronized in Netbox" url="https://netbox.company.net" />
|
||||
|
||||
## Supported versions
|
||||
### Supported versions {#supported-versions}
|
||||
|
||||
- `>= 2.10`
|
||||
- `3.x`
|
||||
@@ -315,7 +317,7 @@ XO will try to find the right prefix for each IP address. If it can't find a pre
|
||||
- Virtualization > virtual machine
|
||||
- Virtualization > interface
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/netbox-permissions.png" alt="The two XO permissions, on the Netbox side" width={620} />
|
||||
|
||||
- Create a Netbox user:
|
||||
- Go to Admin > Users > Add
|
||||
@@ -340,7 +342,7 @@ For testing purposes, you can create an API token bound to a Netbox superuser ac
|
||||
- Virtualization > interface
|
||||
- Name it "uuid" (lower case!)
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/customfield.png" alt="The uuid custom field in Netbox" width={560} />
|
||||
|
||||
:::tip
|
||||
In Netbox 2.x, custom fields can be created from the Admin panel > Custom fields > Add custom field.
|
||||
@@ -371,7 +373,7 @@ In Xen Orchestra, recipes are ready-to-use automation templates that make it eas
|
||||
With just a few clicks, you can launch a complete multi-VM environment, where all nodes are automatically set up and connected.
|
||||
|
||||
:::tip
|
||||
Currently, the only available recipe is for Kubernetes clusters. [This guide](../xo6/kubernetes.md) will walk you through creating one.
|
||||
Currently, the only available recipe is for Kubernetes clusters. [This guide](../automation/kubernetes.md) will walk you through creating one.
|
||||
|
||||
Coming soon: We’ll expand the Recipes feature to include EasyVirt DC Scope deployment.
|
||||
:::
|
||||
@@ -575,9 +577,9 @@ Every SR-tagged metric (`xcp_host_disk_iops_*`, `xcp_host_disk_throughput_*`, `x
|
||||
| Metric | Type | Labels | Description |
|
||||
| ---------------------------------- | ----- | -------- | ------------------------------------------------------------------------------------------------------------ |
|
||||
| `xo_nodejs_process_memory_bytes` | gauge | `type` | Memory usage of the XO main process in bytes (`rss`, `heap_used`, `heap_total`, `external`, `array_buffers`) |
|
||||
| `xo_nodejs_heap_size_limit_bytes` | gauge | | V8 heap size limit in bytes — OOM occurs when heap_used approaches this value |
|
||||
| `xo_nodejs_heap_size_limit_bytes` | gauge | | V8 heap size limit in bytes: OOM occurs when heap_used approaches this value |
|
||||
| `xo_nodejs_heap_available_bytes` | gauge | | Remaining V8 heap space before hitting the size limit |
|
||||
| `xo_nodejs_detached_contexts` | gauge | | Number of detached V8 contexts not yet GC'd — non-zero and growing indicates a memory leak |
|
||||
| `xo_nodejs_detached_contexts` | gauge | | Number of detached V8 contexts not yet GC'd: non-zero and growing indicates a memory leak |
|
||||
| `xo_nodejs_process_cpu_seconds` | gauge | `mode` | CPU time consumed by the XO main process since last collection (`user`, `system`) |
|
||||
| `xo_nodejs_event_loop_utilization` | gauge | `metric` | Event loop utilization ratio since last collection (`mean`, `p99`, `max`) |
|
||||
|
||||
@@ -591,7 +593,7 @@ All metrics include these labels for filtering:
|
||||
| `pool_name` | Pool name |
|
||||
| `uuid` | Object UUID (host or VM) |
|
||||
| `type` | Object type (`host` or `vm`) |
|
||||
| `content_type` | XAPI SR content type (e.g. `user`, `disk`, `iso`) — on SR capacity metrics and `xo_sr_total` |
|
||||
| `content_type` | XAPI SR content type (e.g. `user`, `disk`, `iso`), on SR capacity metrics and `xo_sr_total` |
|
||||
| `host_name` | Host name (for host metrics) |
|
||||
| `vm_name` | VM name (for VM metrics) |
|
||||
| `sr_uuid` | Storage Repository UUID (for SR, VDI, XOSTOR, and resolved host disk metrics) |
|
||||
@@ -608,7 +610,7 @@ All metrics include these labels for filtering:
|
||||
| `is_control_domain` | Whether the VM is a control domain / dom0 (`true`/`false`) |
|
||||
| `power_state` | Power state: `Running`, `Halted`, `Unknown` (for `xcp_host_status`); `Running`, `Paused`, `Halted`, `Suspended` (for `xcp_vm_status`) |
|
||||
| `enabled` | Whether the host is enabled: `true`/`false` (for `xcp_host_status`) |
|
||||
| `sr_type` | XAPI SR type (e.g. `linstor`, `lvm`, `nfs`) — on every SR-tagged metric |
|
||||
| `sr_type` | XAPI SR type (e.g. `linstor`, `lvm`, `nfs`), on every SR-tagged metric |
|
||||
| `node_name` | LINSTOR node hostname (for XOSTOR node metrics) |
|
||||
| `role` | LINSTOR node role: `master` or `satellite` (for `xcp_xostor_node_status`) |
|
||||
| `state` | LINSTOR node state (verbatim from `healthCheck`, e.g. `ONLINE`) or replica `disk-state` (e.g. `UpToDate`) |
|
||||
@@ -616,7 +618,7 @@ All metrics include these labels for filtering:
|
||||
| `target_type` | Object targeted by an alarm: `sr` or `host` |
|
||||
| `package` | XOSTOR-related RPM name for pending updates |
|
||||
| `status` | SMART overall-health string: `PASSED`, `FAILED`, `UNKNOWN` |
|
||||
| `tags` | XO tags of the object, comma-separated and sorted (e.g. `prod,web`) — on host, VM and SR metrics; omitted when the object has no tags |
|
||||
| `tags` | XO tags of the object, comma-separated and sorted (e.g. `prod,web`), on host, VM and SR metrics; omitted when the object has no tags |
|
||||
|
||||
##### Filtering by XO tags
|
||||
|
||||
@@ -1034,10 +1036,10 @@ server {
|
||||
|
||||
A health check endpoint is available without authentication:
|
||||
|
||||
```bash
|
||||
<Terminal title="health check, no authentication needed">{`
|
||||
curl http://your-xoa-ip/openmetrics/health
|
||||
# Response: {"status":"ok"}
|
||||
```
|
||||
{"status":"ok"}
|
||||
`}</Terminal>
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
|
||||
@@ -1,380 +0,0 @@
|
||||
# Architecture
|
||||
|
||||
Xen Orchestra (XO) is software built with a server and clients, such as the web client `xo-web`, but also a CLI capable client, called `xo-cli`.
|
||||
|
||||
:::tip
|
||||
XO is totally agent-less: you don't have to install any program on your hosts to get it working!
|
||||
:::
|
||||
|
||||
## XOA
|
||||
|
||||
_Xen Orchestra Virtual Appliance_ (XOA) is a virtual machine with Xen Orchestra already installed, thus working out-of-the-box.
|
||||
|
||||
This is the easiest way to try Xen Orchestra quickly.
|
||||
|
||||
Your XOA is connected to all your hosts, or the pool master only if you are using Pools in XCP-ng/Citrix Hypervisor:
|
||||
|
||||

|
||||
|
||||
## Xen Orchestra (XO)
|
||||
|
||||

|
||||
|
||||
Xen Orchestra itself is built as a modular solution. Each part has its role.
|
||||
|
||||
## xo-server (server)
|
||||
|
||||
The core is "[xo-server](https://github.com/vatesfr/xen-orchestra/tree/master/packages/xo-server/)" - a daemon dealing directly with XCP-ng/XenServer or XAPI capable hosts. This is where users are stored, and it's the center point for talking to your whole Xen infrastructure.
|
||||
|
||||
XO-Server is the core of Xen Orchestra. Its central role opens a lot of possibilities versus other solutions - let's see why.
|
||||
|
||||
### Daemon mode
|
||||
|
||||
As a daemon, XO-Server is always up. Because of this, it can listen and record every event occurring on your entire Xen infrastructure. Connections are always open and it can cache information before serving it to another client (CLI, Web or anything else).
|
||||
|
||||
### Central point
|
||||
|
||||
Contrary to XenCenter, each Xen Orchestra's client is connected to one XO-Server, and not all the Xen servers. With a traditional architecture:
|
||||
|
||||

|
||||
|
||||
You can see how we avoid a lot of resource and bandwidth waste with a central point:
|
||||
|
||||

|
||||
|
||||
### Events
|
||||
|
||||
Legacy interfaces use the "pull" model, requesting data every "x" seconds:
|
||||
|
||||

|
||||
|
||||
It's **not scalable** and **slow**.
|
||||
|
||||
Previously with XO < 3.4, we used events in the following way:
|
||||
|
||||

|
||||
|
||||
But the interface was still lagging behind the server. With XO 3.4 and beyond, we now have a full event system, allowing instant display of what's happening on your infrastructure:
|
||||
|
||||

|
||||
|
||||
### A proxy for your hosts
|
||||
|
||||
XO-Server will act as a proxy for all your clients. This opens a lot of possibilities!
|
||||
|
||||
#### Console proxy
|
||||
|
||||
A good example is the console: you can now expose your consoles even if your clients are outside the network!
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
#### VM streaming
|
||||
|
||||
Another possibility is to stream a VM from one host to another.
|
||||
|
||||
To do that previously, you needed to export your VM somewhere, then re-import it:
|
||||
|
||||

|
||||
|
||||
Thanks to our architecture, it's now far easier:
|
||||
|
||||

|
||||
|
||||
#### Patching on the fly
|
||||
|
||||
To install a patch manually, it requires a lot of steps: find, download, extract and apply the patch, sequentially.
|
||||
|
||||
"xo-server" can do all these steps at once:
|
||||
|
||||
1. automatically download the patch from Citrix servers
|
||||
2. unzip it and upload it on the fly to your host
|
||||
3. apply it as soon it's done
|
||||
|
||||
### Pluggable
|
||||
|
||||
It's really easy to connect other modules to XO-server, and extend or adapt the solution to your needs (see XO-web and XO-cli for real examples).
|
||||
|
||||
#### ACLs
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
### NodeJS under the hood
|
||||
|
||||
[NodeJS](https://en.wikipedia.org/wiki/Nodejs) is a software platform for scalable server-side and networking applications. It's famous for its efficiency, scalability and its asynchronous capabilities. Exactly what we need! Thus, XO-server is written in JavaScript.
|
||||
|
||||
## xo-web (web UI)
|
||||
|
||||
The web interface is "[xo-web](https://github.com/vatesfr/xen-orchestra/tree/master/packages/xo-web)" - it runs directly from your browser. The connection with `xo-server` is done via _WebSockets_.
|
||||
|
||||
This is probably the first part of Xen Orchestra you'll see. The Web interface allows you to interact with your virtual infrastructure. As a module of XO-Web it facilitates everyday Xen administrator work, but also provides a solution to delegate parts of your infrastructure to other people.
|
||||
|
||||

|
||||
|
||||
[Read the manage section](./manage.md) to discover what you can do in XO-web.
|
||||
|
||||
### ReactJS
|
||||
|
||||
We stay consistent from the back-end to the front-end with one main language: [ReactJS](https://reactjs.org/)
|
||||
|
||||

|
||||
|
||||
## xo-cli (CLI)
|
||||
|
||||
"[xo-cli](https://github.com/vatesfr/xen-orchestra/tree/master/packages/xo-cli)" is a module allowing you to send commands directly from the command line.
|
||||
|
||||
Thanks to introspection, `xo-cli` will detect all the available features exposed in the `xo-server` API.
|
||||
|
||||
:::warning
|
||||
This CLI is mainly used as a debug tool, there's no 100% guarantee on its stability. Use it only if you really know what you do.
|
||||
:::
|
||||
|
||||
### Usage
|
||||
|
||||
```console
|
||||
$ xo-cli help
|
||||
Usage:
|
||||
|
||||
xo-cli register [--allowUnauthorized] [--expiresIn <duration>] [--otp <otp>] <XO-Server URL> <username> [<password>]
|
||||
xo-cli register [--allowUnauthorized] [--expiresIn <duration>] --token <token> <XO-Server URL>
|
||||
Registers the XO instance to use.
|
||||
|
||||
--allowUnauthorized, --au
|
||||
Accept invalid certificate (e.g. self-signed).
|
||||
|
||||
--expiresIn <duration>
|
||||
Can be used to change the validity duration of the
|
||||
authorization token (default: one month).
|
||||
|
||||
--otp <otp>
|
||||
One-time password if required for this user.
|
||||
|
||||
--token <token>
|
||||
An authentication token to use instead of username/password.
|
||||
|
||||
xo-cli create-token <params>…
|
||||
Create an authentication token for XO API.
|
||||
|
||||
<params>…
|
||||
Accept the same parameters as register, see its usage.
|
||||
|
||||
xo-cli unregister
|
||||
Remove stored credentials.
|
||||
|
||||
xo-cli list-commands [--json] [<pattern>]...
|
||||
Returns the list of available commands on the current XO instance.
|
||||
|
||||
The patterns can be used to filter on command names.
|
||||
|
||||
xo-cli list-objects [--<property>]… [<property>=<value>]...
|
||||
Returns a list of XO objects.
|
||||
|
||||
--<property>
|
||||
Restricts displayed properties to those listed.
|
||||
|
||||
<property>=<value>
|
||||
Restricted displayed objects to those matching the patterns.
|
||||
|
||||
xo-cli <command> [--json] [<name>=<value>]...
|
||||
Executes a command on the current XO instance.
|
||||
|
||||
--json
|
||||
Prints the result in JSON format.
|
||||
|
||||
xo-cli rest del <resource>
|
||||
Delete the resource.
|
||||
|
||||
Examples:
|
||||
xo-cli rest del tasks/<task id>
|
||||
xo-cli rest del vms/<vm id>/tags/<tag>
|
||||
|
||||
xo-cli rest get <collection> [fields=<fields>] [filter=<filter>] [limit=<limit>]
|
||||
List objects in a REST API collection.
|
||||
|
||||
<collection>
|
||||
Full path of the collection to list
|
||||
|
||||
fields=<fields>
|
||||
When provided, returns a collection of objects containing the requested
|
||||
fields instead of the simply the objects' paths.
|
||||
|
||||
The field names must be separated by commas.
|
||||
|
||||
filter=<filter>
|
||||
List only objects that match the filter
|
||||
|
||||
Syntax: https://docs.xen-orchestra.com/xo5/manage_infrastructure#filter-syntax
|
||||
|
||||
limit=<limit>
|
||||
Maximum number of objects to list, e.g. `limit=10`
|
||||
|
||||
Examples:
|
||||
xo-cli rest get
|
||||
xo-cli rest get tasks filter='status:pending'
|
||||
xo-cli rest get vms fields=name_label,power_state
|
||||
|
||||
xo-cli rest get [--output <file>] <object> [wait | wait=result]
|
||||
Show an object from the REST API.
|
||||
|
||||
--output <file>
|
||||
If specified, the response will be saved in <file> instead of being parsed.
|
||||
|
||||
If <file> ends with `/`, it will be considered as the directory in which
|
||||
to save the response, and the filename will be last part of the <object> path.
|
||||
|
||||
<object>
|
||||
Full path of the object to show
|
||||
|
||||
wait
|
||||
If the object is a task, waits for it to be updated before returning.
|
||||
|
||||
wait=result
|
||||
If the object is a task, waits for it to be finished before returning.
|
||||
|
||||
Examples:
|
||||
xo-cli rest get vms/<VM UUID>
|
||||
xo-cli rest get tasks/<task id>/actions wait=result
|
||||
|
||||
xo-cli rest patch <object> <name>=<value>...
|
||||
Update properties of an object (not all properties are writable).
|
||||
|
||||
<object>
|
||||
Full path of the object to update
|
||||
|
||||
<name>=<value>...
|
||||
Properties to update on the object
|
||||
|
||||
Examples:
|
||||
xo-cli rest patch vms/<VM UUID> name_label='My VM' name_description='Its description
|
||||
|
||||
xo-cli rest post <action> <name>=<value>...
|
||||
Execute an action.
|
||||
|
||||
<action>
|
||||
Full path of the action to execute
|
||||
|
||||
<name>=<value>...
|
||||
Parameters to pass to the action
|
||||
|
||||
Examples:
|
||||
xo-cli rest post tasks/<task id>/actions/abort
|
||||
xo-cli rest post vms/<VM UUID>/actions/snapshot name_label='My snapshot'
|
||||
|
||||
xo-cli rest put <collection>/<item id> <name>=<value>...
|
||||
Put a item in a collection
|
||||
|
||||
<collection>/<item id>
|
||||
Full path of the item to add
|
||||
|
||||
<name>=<value>...
|
||||
Properties of the item
|
||||
|
||||
Examples:
|
||||
xo-cli rest put vms/<vm id>/tags/<tag>
|
||||
```
|
||||
|
||||
#### Register your XO instance
|
||||
|
||||
```console
|
||||
$ xo-cli register http://xo.my-company.net [email protected] admin
|
||||
Successfully logged with [email protected]
|
||||
```
|
||||
|
||||
Note: only a token will be saved in the configuration file (`/etc/xo-server/config.toml`).
|
||||
|
||||
#### List available objects
|
||||
|
||||
Prints all objects:
|
||||
|
||||
```sh
|
||||
xo-cli list-objects
|
||||
```
|
||||
|
||||
It is possible to filter on object properties, for instance to print
|
||||
all VM templates:
|
||||
|
||||
```sh
|
||||
xo-cli list-objects type=VM-template
|
||||
```
|
||||
|
||||
#### List available commands
|
||||
|
||||
```sh
|
||||
xo-cli list-commands
|
||||
```
|
||||
|
||||
Commands can be filtered using patterns:
|
||||
|
||||
```sh
|
||||
xo-cli list-commands '{user,group}.*'
|
||||
```
|
||||
|
||||
#### Execute a command
|
||||
|
||||
The same syntax is used for all commands: `xo-cli <command> <param name>=<value>...`
|
||||
|
||||
E.g., adding a new server:
|
||||
|
||||
```console
|
||||
$ xo-cli server.add host=my.server.net username=root password=secret-password
|
||||
42
|
||||
```
|
||||
|
||||
The return value is the identifier of this new server in XO.
|
||||
|
||||
Parameters (except `true` and `false` which are correctly parsed as
|
||||
booleans) are assumed to be strings. For other types, you may use JSON
|
||||
encoding by prefixing with `json:`:
|
||||
|
||||
```sh
|
||||
xo-cli foo.bar baz='json:[1, 2, 3]'
|
||||
```
|
||||
|
||||
##### VM export
|
||||
|
||||
```sh
|
||||
xo-cli vm.export vm=a01667e0-8e29-49fc-a550-17be4226783c @=vm.xva
|
||||
```
|
||||
|
||||
##### VM import
|
||||
|
||||
```sh
|
||||
xo-cli vm.import sr=60a6939e-8b0a-4352-9954-5bde44bcdf7d @=vm.xva
|
||||
```
|
||||
|
||||
> Note: `xo-cli` only supports the import of XVA files. It will not import OVA files. To import OVA images, you must use the XOA web UI or use `xo-upload-ova` [available here](https://github.com/vatesfr/xen-orchestra/blob/master/@xen-orchestra/upload-ova/README.md#xo-upload-ova).
|
||||
|
||||
## API
|
||||
|
||||
Our web UI (`xo-web`) and CLI (`xo-cli`) both talk to `xo-server` via the same API. This API works in a kind of "connected mode", using JSON-RPC through websockets, in a way where we can subscribe to any events to always stay up-to-date on the client side.
|
||||
|
||||
:::warning
|
||||
However, this API was initially meant to only be private. Also, as it's JSON-RPC inside websockets, it's not trivial to use. If you want to make calls in an easy fashion, you should take a look at our [REST API](restapi.md).
|
||||
:::
|
||||
|
||||
If you need assistance on how to use it:
|
||||
|
||||
1. Try to use [xo-cli](./architecture.md#xo-cli-cli) first. You'll learn all the available calls
|
||||
2. A good intro can be find within [xo-lib](https://github.com/vatesfr/xen-orchestra/tree/master/packages/xo-lib#xo-lib-)
|
||||
3. Create a support ticket asking us for precise call you want to make, we'll help you!
|
||||
|
||||
## Plugins
|
||||
|
||||
Xen Orchestra plugins allow you to extend features without rewriting the core of the application.
|
||||
|
||||
You can see your installed plugins in "Settings" then the "Plugins" page:
|
||||
|
||||

|
||||
|
||||
All plugin configuration should be done in the web interface:
|
||||
|
||||

|
||||
|
||||
A plugin can be:
|
||||
|
||||
- activated/deactivated
|
||||
- loaded on start of the application
|
||||
- configured (extend the plugin settings by clicking on the "+" icon
|
||||
@@ -1,298 +0,0 @@
|
||||
# Backup strategy guide
|
||||
|
||||
This guide explains how to design and implement a backup strategy in Xen Orchestra.
|
||||
|
||||
Instead of a simple list of questions and answers, it walks you through **key decisions** and **best practices** before, during, and after setting up backups.
|
||||
|
||||
---
|
||||
|
||||
## Glossary
|
||||
|
||||
This part explains the terminology of backup types and features.
|
||||
|
||||
- **Backup sequence**: A feature that allows you to chain multiple backup jobs to run one after the other, automatically.
|
||||
- [**File restore**](./backups#restore-a-file): A feature that allows you to restore individual files from a VM backup without restoring the full VM.
|
||||
- [**Full backup**](./full_backups): Copies the entire VM to backup repositories each time, regardless of previous backups.
|
||||
- [**Full replication**](./full_replication): Creates a replica of a VM on other storage repositories (on the same pool or on another) by copying it completly on each run.
|
||||
- [**Incremental backup**](./incremental_backups): Transfer and stores only the changes since the last backup to backup repositories , reducing storage and network needs. The first transfer transfers the VM completely.
|
||||
- [**Incremental replication**](./incremental_replication): Transfer and stores only the changes since the last backup to storage repositories (on the same pool or on another), reducing network needs. The first transfer transfers the VM completely.
|
||||
- [**Long-term retention**](./backups#long-term-backup-retention-with-gfs-strategy): Keeps backups over extended periods (weeks, months, or years) for compliance or archival purposes.
|
||||
- [**Mirror backup**](./mirror_backup): Mirror a backup repository to another. Retention and encryption of source and destination can be different.
|
||||
- [**Distributed backup and replication**](../distributed_backups): Distribute the backups and replications across multiple targets.
|
||||
- [**Remote**](./backups#remotes): A storage location for backups. For instance:
|
||||
- Local storage (not recommended)
|
||||
- NFS
|
||||
- SMB
|
||||
- Amazon S3 and compatible
|
||||
- Microsoft Azure
|
||||
- Azurite
|
||||
|
||||
---
|
||||
|
||||
## What should I do before setting up my backup?
|
||||
|
||||
Before creating your first backup job in Xen Orchestra, consider the following:
|
||||
|
||||
### Remote
|
||||
|
||||
Choose and configure your remote storage.
|
||||
|
||||
- Supported types: NFS, SMB/CIFS, S3-compatible object storage, Microsoft Azure, or local storage.
|
||||
- Ensure proper permissions and network connectivity.
|
||||
- Test write/read performance before relying on it.
|
||||
- If you're using block storage, check whether your solution supports encryption (for data-at-rest protection) and immutability (to prevent backups from being modified or deleted, even by mistake or maliciously).
|
||||
|
||||
### Resources available
|
||||
|
||||
- **Storage**: Calculate how much space will be required based on your backup type and retention.
|
||||
- **Network**: Backups are network-intensive; ensure sufficient bandwidth.
|
||||
- **Compute**: Avoid backup schedules that overlap with heavy VM workloads.
|
||||
|
||||
### Criticality
|
||||
|
||||
Identify which VMs are business-critical. These should have more frequent backups and possibly replications for minimal downtime.
|
||||
|
||||
### Retention
|
||||
|
||||
Determine how long backups should be kept. This depends on:
|
||||
|
||||
- Compliance requirements
|
||||
- Recovery Point Objective (RPO)
|
||||
- Recovery Time Objective (RTO)
|
||||
- Storage capacity
|
||||
|
||||
---
|
||||
|
||||
## What kind of backup should I set up?
|
||||
|
||||
Below are the main backup and replication types available in Xen Orchestra.
|
||||
|
||||
### Full backup
|
||||
|
||||
**Pros:**
|
||||
|
||||
- Complete independent copy each time
|
||||
- Simplifies restore process
|
||||
- only the allocated blocs are transfered
|
||||
- can be compressed from xcp 8.2 (not sure of the exact version)
|
||||
|
||||
**Cons:**
|
||||
|
||||
- Requires the most storage and network bandwidth
|
||||
- Slower than incremental options
|
||||
|
||||
**Limitations and extensions:**
|
||||
|
||||
- Can be combined with long-term retention
|
||||
- No deduplication between runs
|
||||
|
||||
**First steps:**
|
||||
|
||||
1. Configure a reliable remote with sufficient capacity
|
||||
2. Schedule during low I/O periods
|
||||
|
||||
---
|
||||
|
||||
### Delta backup
|
||||
|
||||
**Pros:**
|
||||
|
||||
- Saves only modified blocks after the first full run
|
||||
- Faster and more storage-efficient than full backups
|
||||
|
||||
**Cons:**
|
||||
|
||||
- Restore requires the initial full backup plus subsequent deltas
|
||||
- Slightly more complex restore process
|
||||
|
||||
**Limitations and extensions:**
|
||||
|
||||
- Requires initial full backup
|
||||
- Can be combined with long-term retention
|
||||
|
||||
---
|
||||
|
||||
### Incremental replication
|
||||
|
||||
**Pros:**
|
||||
|
||||
- only transfer the modified data blocks since last replication
|
||||
- Rapid failover to replicated VM
|
||||
|
||||
**Cons:**
|
||||
|
||||
- Requires a secondary host or pool
|
||||
- Not suitable for long-term retention
|
||||
|
||||
**Limitations and extensions:**
|
||||
|
||||
- Must keep the chain short ( < 10): Not intended as an archival method
|
||||
|
||||
**First steps:**
|
||||
|
||||
1. Configure target storage inside the same pool or another pool
|
||||
2. Ensure compatible storage and network settings
|
||||
|
||||
---
|
||||
|
||||
### Full replication
|
||||
|
||||
**Pros:**
|
||||
|
||||
- Creates a complete VM copy on another storage (same pool or another pool)
|
||||
- Ideal for disaster recovery
|
||||
|
||||
**Cons:**
|
||||
|
||||
- Longer replication times than incremental
|
||||
- Requires more bandwidth and storage
|
||||
|
||||
**Limitations and extensions:**
|
||||
|
||||
- Run less frequently than incremental replication
|
||||
- Suitable for DR plans
|
||||
|
||||
**First steps:**
|
||||
|
||||
1. Configure DR target storage (same pool or another pool)
|
||||
2. Test failover procedures
|
||||
|
||||
---
|
||||
|
||||
### Sequence
|
||||
|
||||
**Advantages:**
|
||||
|
||||
- Allows chaining multiple jobs in order
|
||||
- Useful for complex backup and replication workflows
|
||||
|
||||
**Cons:**
|
||||
|
||||
- Increases job complexity
|
||||
- Requires careful planning
|
||||
|
||||
**Limitations and extensions:**
|
||||
|
||||
- Limited by the capabilities of individual job types
|
||||
|
||||
**First steps:**
|
||||
|
||||
1. Identify required job order
|
||||
2. Create and test sequence on non-critical VMs
|
||||
|
||||
---
|
||||
|
||||
### Mirror backup
|
||||
|
||||
**Pros:**
|
||||
|
||||
- Always keeps the latest backup version
|
||||
|
||||
**Limitations and extensions:**
|
||||
|
||||
- Best suited for replication to storage with low bandwidth
|
||||
- You can mirror incremental backups or full backups
|
||||
|
||||
**First steps:**
|
||||
|
||||
1. Set up a dedicated remote
|
||||
2. Test restore from latest mirror
|
||||
|
||||
---
|
||||
|
||||
## What settings are available?
|
||||
|
||||
### Advanced settings
|
||||
|
||||
- **Compression**: Reduces backup size at the cost of CPU usage and backup speed.
|
||||
- **Encryption**: Protects backup data at rest.
|
||||
- **Concurrency**: Controls how many VMs run in parallel in this backup job.
|
||||
- **Retention policy**: Fine-tunes how many backups to keep over certain periods of time.
|
||||
- **Full backup interval**: Defines the maximum backup chain size (only for delta backups and incremental replications).
|
||||
|
||||
:::tip
|
||||
|
||||
- **Compression** is configured at the backup job level, and applies only to full backups. For full backups, prefer [Zstandard (Zstd)](https://en.wikipedia.org/wiki/Zstd) if your host supports it.
|
||||
- **Encryption** is configured at the backup repository level, not per individual backup job. To use encryption with incremental backups, the **use VHD blocks** setting must be enabled.
|
||||
- Setting a **Full backup interval** prevents infinite backup chains, which may degrade resilience against block corruption over time. We recommend either defining a regular interval or enabling health checks for your Delta backup and Continuous Replication jobs.
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
## Restore options
|
||||
|
||||
### VM restore
|
||||
|
||||
- Restore a VM to the same host/pool or another location.
|
||||
- When restoring, Xen Orchestra can attempt a **differential restore**, which reuses the current VM disk to speed up the process.
|
||||
|
||||
### File restore
|
||||
|
||||
- Access individual files within a VM backup
|
||||
- Ideal for quick recovery of deleted or corrupted files without a full VM restore
|
||||
|
||||
### Limitations
|
||||
|
||||
The file restore feature includes the following constraints:
|
||||
|
||||
- **Supported partition types** are limited to those compatible with Debian systems and NTFS. ReFS and Windows dynamic disks are not supported.
|
||||
- **LVM support** is limited and may fail in certain edge cases.
|
||||
- File restore is designed for **small file sets** and is not suitable for large-scale recovery.
|
||||
|
||||
:::tip
|
||||
For **advanced scenarios**, you can use the `fuse-vhd` helper script to manually mount backup chains as raw disks and perform partition discovery:
|
||||
[View fuse-vhd on GitHub](https://github.com/vatesfr/xen-orchestra/tree/master/%40vates/fuse-vhd).
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
## Long-term retention strategy
|
||||
|
||||
- Define retention periods based on compliance and operational needs
|
||||
- Regularly test restore from long-term backups
|
||||
|
||||
:::warning
|
||||
To prevent backup duplication, do not mix long-term retention with multiple schedules.
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
## Putting it all together
|
||||
|
||||
When designing your backup strategy with Xen Orchestra:
|
||||
|
||||
1. Assess criticality and resources.
|
||||
2. Choose backup types that match your RPO/RTO goals.
|
||||
3. Configure remotes and test them.
|
||||
4. Set up schedules to avoid peak loads.
|
||||
5. Apply retention policies.
|
||||
6. Test restores regularly.
|
||||
|
||||
---
|
||||
|
||||
## How to ensure XOA is always available
|
||||
|
||||
Making sure XOA is always available should be a top priority for every administrator. Here’s how you can maximize its reliability:
|
||||
|
||||
Since XOA runs as a virtual machine, you can apply standard VM protection measures:
|
||||
|
||||
- Back up regularly (full or incremental).
|
||||
- Replicate the VM (full disaster recovery or incremental replication).
|
||||
- Take snapshots for quick rollback if needed.
|
||||
|
||||
### Specific steps for the XOA VM
|
||||
|
||||
- **Back up XO backup metadata:** This is the most efficient way to ensure you can quickly restore your XOA environment. If you lose your XOA VM: download and install a new XOA, restore the XO backup metadata, and you’ll be able to restore all other backups and settings.
|
||||
- Use the **XO Config** feature to back up your XOA settings. This lets you restore them to any XOA VM if necessary.
|
||||
|
||||
### Managing the loss of your XOA VM
|
||||
|
||||
If you lose the host running your XOA VM:
|
||||
|
||||
- **If the XOA VM was on shared storage**, you can restart it on another host in your pool.
|
||||
- **If the XOA VM was stored locally** or your host was alone in its pool, deploy a new XOA VM. You can do this proactively, as there’s no limit to the number of XOA VMs in your infrastructure. Register the new VM with the same Vates account, update it, and migrate your XOA license from the old VM if needed.
|
||||
- **If you are running XCP-ng 8.3**, you can use XO-lite by connecting to your master host’s IP address to manage your VMs.
|
||||
|
||||
:::warning
|
||||
Avoid using multiple XOAs to back up the same VMs, as this can cause backup failures.
|
||||
:::
|
||||
+125
-86
@@ -1,31 +1,40 @@
|
||||
# Backup reports
|
||||
|
||||
At the end of a backup job, you can configure Xen Orchestra to send backup reports directly by email, Slack or in Mattermost. It's up to you.
|
||||
At the end of a backup job, Xen Orchestra can send you a report through the channel of your choice: email, XMPP, Slack or Mattermost, and even straight into your Nagios or Icinga 2 monitoring.
|
||||
|
||||
Whatever the channel, the logic is always the same, in three steps:
|
||||
|
||||
1. Enable and configure the **backup-reports** plugin, which builds the report and lists the recipients.
|
||||
2. Enable and configure the **transport** plugin matching your channel (`transport-email`, `transport-xmpp`, `transport-slack`, `transport-nagios` or `transport-icinga2`).
|
||||
3. In the backup job itself, pick a **report condition**: **Always**, **Skipped and failure**, **Failure** (errors only) or **Never**.
|
||||
|
||||
## Email
|
||||
|
||||
### Step-by-step
|
||||
|
||||
1. In the **Settings → Plugins** view, enable and configure the **Backup-reports** plugin.
|
||||

|
||||
1. In the **Settings → Plugins** view, enable and configure the **backup-reports** plugin. This is where you add the list of email recipients. You can also set a custom subject suffix, appended to the subject of every backup report email.
|
||||
|
||||
2. Configure also the `transport-email` plugin (see detailed configuration below).
|
||||

|
||||
<UiDetail src="/img/xo5/backup-reports-plugin.png" alt="The backup-reports plugin in Settings, Plugins, with its list of email recipients" width={700} />
|
||||
|
||||
3. Once it's done, you can now create your backup job. In the "report" selection you can choose the situation in wish you want to receive an email (always, never or failure).
|
||||

|
||||
2. Enable and configure the `transport-email` plugin: sender name and address, then the SMTP transport itself (host, port, security mode, user and password). See the provider walkthroughs below for concrete values.
|
||||
|
||||
<UiDetail src="/img/xo5/transport-email-plugin.png" alt="The transport-email plugin configuration form with the sender and SMTP transport fields" width={700} />
|
||||
|
||||
3. Once done, create your backup job. In the **Report** selector, choose when you want to receive an email: **Always**, **Skipped and failure**, **Failure** (errors only) or **Never**.
|
||||
|
||||
<UiDetail src="/img/xo5/backup-report-config.png" alt="The Report selector of a backup job, set to send a report on skipped and failed runs" width={700} />
|
||||
|
||||
:::tip
|
||||
You can also modify existing backup jobs and change the behaviour of the report system.
|
||||
You can also modify existing backup jobs and change the behavior of the report system at any time.
|
||||
:::
|
||||
|
||||
### Email Provider Configuration
|
||||
|
||||
:::info
|
||||
**Authentication Requirements**
|
||||
**Authentication requirements**
|
||||
|
||||
- **Gmail**: Standard passwords no longer work - App Passwords with 2FA are required
|
||||
- **Microsoft 365**: Basic authentication still works but will be disabled in March 2026
|
||||
- **Gmail**: standard passwords no longer work. App Passwords with 2FA are required.
|
||||
- **Microsoft 365**: basic authentication is now permanently disabled (since spring 2026). Direct SMTP submission with a plain password no longer works, see below.
|
||||
|
||||
:::
|
||||
|
||||
@@ -41,12 +50,12 @@ Gmail users must use App Passwords for SMTP authentication.
|
||||
|
||||
1. **Enable 2FA**: Go to [Google Account Security](https://myaccount.google.com/security) → 2-Step Verification
|
||||
2. **Generate App Password**: Visit [App Passwords](https://myaccount.google.com/apppasswords) → Select "Mail" → Generate
|
||||
3. **Configure transport-email plugin:**
|
||||
3. **Configure the transport-email plugin:**
|
||||
- Host: `smtp.gmail.com`
|
||||
- Port: `587`
|
||||
- Secure: `Auto` or `STARTTLS`
|
||||
- Username: Your Gmail address
|
||||
- Password: The 16-character App Password (no spaces)
|
||||
- Secure: `auto (uses STARTTLS if available)` or `force (requires STARTTLS or fail)`
|
||||
- User: your Gmail address
|
||||
- Password: the 16-character App Password (no spaces)
|
||||
|
||||
:::tip
|
||||
App Passwords are more secure than regular passwords, as they require 2FA and can be revoked individually.
|
||||
@@ -54,25 +63,23 @@ App Passwords are more secure than regular passwords, as they require 2FA and ca
|
||||
|
||||
#### Microsoft 365 Configuration
|
||||
|
||||
**Current Configuration :**
|
||||
|
||||
- Host: `smtp.office365.com`
|
||||
- Port: `587`
|
||||
- Secure: `STARTTLS`
|
||||
- Username: Your Office 365 email
|
||||
- Password: Your Office 365 password
|
||||
|
||||
:::warning
|
||||
Microsoft will permanently disable basic authentication between March 1 and April 30, 2026. After this date, your email notifications will stop working
|
||||
Microsoft permanently disabled basic authentication for SMTP submission between March and April 2026. The historical configuration (`smtp.office365.com`, port `587`, your Microsoft 365 email address and password) **no longer works**, and the `transport-email` plugin does not support the OAuth2 flow that Microsoft now requires for direct submission.
|
||||
:::
|
||||
|
||||
If your email notifications went through Microsoft 365 and stopped working, you have several honest ways forward:
|
||||
|
||||
- **Use an SMTP relay in front of Microsoft 365**: point `transport-email` at an internal relay (a Postfix or similar MTA) and let that relay deliver to Microsoft 365, for example through an Exchange Online connector restricted to your relay's IP address.
|
||||
- **Use Microsoft's replacement services**: Azure Communication Services Email and Exchange Online High Volume Email both provide SMTP endpoints with their own credentials, designed for application-generated mail such as these reports.
|
||||
- **Switch to another SMTP provider**: any provider that still supports user and password authentication works out of the box with the plugin (see below).
|
||||
|
||||
#### Other SMTP Providers
|
||||
|
||||
For providers supporting basic authentication:
|
||||
|
||||
- Host: Your SMTP server
|
||||
- Host: your SMTP server
|
||||
- Port: `587` (STARTTLS) or `465` (TLS)
|
||||
- Username/Password: As provided by your service
|
||||
- User/Password: as provided by your service
|
||||
|
||||
### Network Requirements
|
||||
|
||||
@@ -87,86 +94,98 @@ The transport-email plugin requires outbound access to:
|
||||
**Gmail "Authentication failed":**
|
||||
|
||||
- Ensure you're using an App Password, not your regular password.
|
||||
- Verify 2FA is enabled
|
||||
- Verify 2FA is enabled.
|
||||
|
||||
**Microsoft 365 "Authentication unsuccessful":**
|
||||
|
||||
- Check if your organization has disabled SMTP AUTH
|
||||
- Contact your IT administrator
|
||||
- Basic authentication is permanently disabled since spring 2026: a direct password-based configuration cannot work anymore. Use one of the alternatives described in the [Microsoft 365 section](#microsoft-365-configuration).
|
||||
|
||||
**Connection timeouts:**
|
||||
|
||||
- Verify firewall allows outbound SMTP
|
||||
- Test connectivity: `telnet [smtp-server] 587`
|
||||
- Verify your firewall allows outbound SMTP.
|
||||
- Test connectivity:
|
||||
|
||||
<Terminal shell title="xoa — test SMTP connectivity">{`
|
||||
telnet smtp-server.example.com 587
|
||||
`}</Terminal>
|
||||
|
||||
## XMPP
|
||||
|
||||
You can **be notified via XMPP** after the backup task is finished (scheduled "full backup", "snapshots" or "disaster recovery").
|
||||
You can be notified via XMPP after a backup job run. The flow is the same as for email:
|
||||
|
||||
To configure it, 2 steps are needed in the plugin section (under "Settings"):
|
||||
|
||||
1. add a list of recipient(s) for the notifications (in the plugin "backup-reports" and for XMPP)
|
||||
2. set the XMPP server
|
||||
1. In the **backup-reports** plugin, add the list of XMPP recipients (the **xmpp address** field).
|
||||
2. Enable and configure the `transport-xmpp` plugin: XMPP server host, port (`5222` by default), the user (XMPP address) and password used to authenticate.
|
||||
3. Choose the report condition in your backup job.
|
||||
|
||||
That's it: your next scheduled job will be recapped in a message:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/xmpp-report.png" alt="A backup report recap received as an XMPP message" width={620} />
|
||||
|
||||
## Slack or Mattermost
|
||||
|
||||
Xen Orchestra is able to send backup reports to Slack or Mattermost.
|
||||
Xen Orchestra is able to send backup reports to Slack or Mattermost. Both are handled by the same `transport-slack` plugin, which posts the report to an incoming webhook URL.
|
||||
|
||||
### Plugin configuration
|
||||
|
||||
Like all other xo-server plugins, it can be configured directly via the web interface, see [the plugin documentation](architecture#plugins).
|
||||
Like all other xo-server plugins, it can be configured directly via the web interface, see [the plugin documentation](../architecture.md#plugins). The plugin needs:
|
||||
|
||||
- **Webhook URI**: the Mattermost or Slack webhook URL (see below to generate it)
|
||||
- **Channel**: the channel, private group or IM channel to send the message to
|
||||
- Optionally, a bot **username** and **icon** (a Slack emoji or an image URL)
|
||||
|
||||
Then choose the report condition in your backup job, as for any other transport.
|
||||
|
||||
### Generate the Webhook
|
||||
|
||||
#### Slack
|
||||
|
||||
1. Log in your Slack team account
|
||||
1. Log in to your Slack team account.
|
||||
|
||||
2. Click on the **Main menu** at the top and choose **Apps & Integrations**
|
||||
2. Click on the **Main menu** at the top and choose **Apps & Integrations**.
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/slack-apps-menu.png" alt="The Slack main menu with the Apps and Integrations entry" width={188} />
|
||||
|
||||
3. Search **Incoming WebHooks**
|
||||
3. Search for **Incoming WebHooks**.
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/slack-incoming-webhooks-search.png" alt="The Incoming WebHooks app in the Slack app directory search results" width={620} />
|
||||
|
||||
4. Click on **Add Configuration**
|
||||
4. Click on **Add Configuration**.
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/slack-add-configuration.png" alt="The Add Configuration button on the Incoming WebHooks app page" width={264} />
|
||||
|
||||
5. Choose the default channel and click on **Add Incoming WebHooks integration**
|
||||
5. Choose the default channel and click on **Add Incoming WebHooks integration**.
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/slack-add-webhook-integration.png" alt="Channel selection followed by the Add Incoming WebHooks integration button" width={620} />
|
||||
|
||||
6. Modify the default settings and click on **Save Settings**
|
||||
6. Modify the default settings and click on **Save Settings**.
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/slack-webhook-settings.png" alt="The webhook integration settings with the generated webhook URL" width={620} />
|
||||
|
||||
#### Mattermost
|
||||
|
||||
You need to be an admin:
|
||||
|
||||
- Go into the MatterMost menu, then Integration
|
||||
- Click on "Add Incoming webhook"
|
||||
- "Add Incoming Webhook"
|
||||
1. Go into the Mattermost menu, then **Integrations**.
|
||||
2. Click on **Add Incoming webhook**.
|
||||
3. Copy the generated webhook URL into the plugin configuration.
|
||||
|
||||
### Testing the plugin
|
||||
|
||||
#### Slack
|
||||
#### Slack {#slack-1}
|
||||
|
||||

|
||||
Fill the plugin configuration with your webhook URL and channel, then use the test button:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/slack-plugin-configuration.png" alt="The transport-slack plugin configuration filled with a Slack webhook URL and channel" width={700} />
|
||||
|
||||
#### Mattermost
|
||||
<UiDetail src="/img/xo5/slack-report-example.png" alt="The test message posted by the Xen Orchestra bot in a Slack channel" width={620} />
|
||||
|
||||

|
||||
#### Mattermost {#mattermost-1}
|
||||
|
||||

|
||||
The same plugin works for Mattermost, only the webhook URL changes:
|
||||
|
||||
<UiDetail src="/img/xo5/mattermost-plugin-configuration.png" alt="The transport-slack plugin configuration filled with a Mattermost webhook URL" width={700} />
|
||||
|
||||
<UiDetail src="/img/xo5/mattermost-report-example.png" alt="The test message posted by the Xen Orchestra bot in a Mattermost channel" width={700} />
|
||||
|
||||
## Nagios
|
||||
|
||||
@@ -174,21 +193,23 @@ The `transport-nagios` plugin allows you to integrate Xen Orchestra backup repor
|
||||
|
||||
Instead of relying solely on email notifications, this plugin sends the status of your backup jobs as **passive checks** to Nagios. This ensures that your infrastructure monitoring dashboard remains the single source of truth for your backup health.
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/nagios-preview.jpg" alt="A Nagios services view showing backup job results reported by Xen Orchestra" width={620} />
|
||||
|
||||
### Overview
|
||||
|
||||
When a backup job completes, Xen Orchestra sends a report. By using the plugin, the result (`Success`, `Warning`, or `Error`) is pushed to the Nagios command file.
|
||||
|
||||
* **Success**: Sends an `OK` status.
|
||||
* **Warning**: Sends a `WARNING` status.
|
||||
* **Error/Partial Success**: Sends a `CRITICAL` status.
|
||||
- **Success**: sends an `OK` status.
|
||||
- **Warning**: sends a `WARNING` status.
|
||||
- **Error/Partial Success**: sends a `CRITICAL` status.
|
||||
|
||||
By default, the plugin reports each VM under a Nagios **host** named after the VM (`{vm.name_label}`) and a **service** named after the backup job (`{job.name}`). You can customize both patterns in the plugin configuration, as long as the custom values still include the `{vm.name_label}` and `{job.name}` templates respectively.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
#### NSCA
|
||||
|
||||
In order to contact Nagios, you must have NSCA (Nagios Service Check Acceptor) running on this Nagios host.
|
||||
In order to contact Nagios, you must have NSCA (Nagios Service Check Acceptor) running on the Nagios host.
|
||||
|
||||
:::note
|
||||
NSCA is a Linux/Unix daemon that lets remote systems "push" status updates to a Nagios server as passive checks. It basically acts as a bridge, by sending data from a client to a server-side daemon that feeds the results directly into Nagios's command file.
|
||||
@@ -196,36 +217,40 @@ NSCA is a Linux/Unix daemon that lets remote systems "push" status updates to a
|
||||
|
||||
The architecture is like this:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/nsca.png" alt="Schema of Xen Orchestra pushing passive checks to Nagios through the NSCA daemon" width={480} />
|
||||
|
||||
Check your config file and add a password and a least XOR encryption:
|
||||
Check your NSCA config file and add a password and at least XOR encryption:
|
||||
|
||||
```
|
||||
<Terminal title="nsca.cfg — password and encryption">{`
|
||||
password=mypassword
|
||||
decryption_method=1
|
||||
```
|
||||
`}</Terminal>
|
||||
|
||||
#### Nagios configuration
|
||||
|
||||
#### 1. Create a host for XOA
|
||||
#### 1. Create a host for each backed-up VM {#1-create-a-host-for-xoa}
|
||||
|
||||
```
|
||||
With the default plugin configuration, the Nagios host name must match the VM name:
|
||||
|
||||
<Terminal title="Nagios — host definition">{`
|
||||
define host{
|
||||
use generic-host ; Name of $
|
||||
host_name xoa
|
||||
alias Xen Orchestra Appliance
|
||||
use generic-host
|
||||
host_name my-vm-name ; must match the VM name in XO
|
||||
alias My VM
|
||||
address 192.168.0.245
|
||||
}
|
||||
```
|
||||
`}</Terminal>
|
||||
|
||||
#### 2. Create a dedicated service for XOA backups
|
||||
#### 2. Create a dedicated service for the backup reports {#2-create-a-dedicated-service-for-xoa-backups}
|
||||
|
||||
```
|
||||
With the default plugin configuration, the service description must match the backup job name:
|
||||
|
||||
<Terminal title="Nagios — passive service definition">{`
|
||||
define service{
|
||||
name passif-generic
|
||||
use generic-service
|
||||
service_description xoabackups
|
||||
host_name xoa
|
||||
service_description my backup job ; must match the job name in XO
|
||||
host_name my-vm-name
|
||||
active_checks_enabled 0
|
||||
passive_checks_enabled 1
|
||||
is_volatile 1
|
||||
@@ -234,13 +259,13 @@ define service{
|
||||
freshness_threshold 86400
|
||||
check_command no-backup-report!0!No backup message sent in the last 24 hours
|
||||
}
|
||||
```
|
||||
`}</Terminal>
|
||||
|
||||
This service will wait for XOA to send backup news in the last 24 hours.
|
||||
This service will wait for Xen Orchestra to send backup news in the last 24 hours.
|
||||
|
||||
Your Nagios setup is now ready. If the service doesn't have news from XOA, it will be in `CRITICAL` state, like this:
|
||||
Your Nagios setup is now ready. If the service doesn't hear from Xen Orchestra in time, it will be in `CRITICAL` state, like this:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/xo5nagiosset.png" alt="A Nagios service row in CRITICAL state because no backup report was received in the last 24 hours" width={700} />
|
||||
|
||||
### Installation in XOA
|
||||
|
||||
@@ -256,9 +281,9 @@ Once the plugin is enabled, you need to configure the connection to your Nagios
|
||||
|
||||
1. Click the edit icon (+) for the `transport-nagios` plugin to show the configuration form:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/nagios-plugin-configuration.png" alt="The transport-nagios configuration form with the server address, NSCA port, encryption key, and the host and service name patterns" width={620} />
|
||||
|
||||
2. Enter your desired values.
|
||||
2. Enter the Nagios server address, the NSCA port and the encryption key, and adjust the host and service name patterns if needed.
|
||||
3. Click **Save configuration** to save and apply your changes.
|
||||
|
||||
### Test the plugin
|
||||
@@ -267,17 +292,31 @@ In the transport-nagios configuration form, you can test the plugin.
|
||||
|
||||
If the plugin works correctly, the result should look like this:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/transport-nagios-test.png" alt="A Nagios service row showing the transport-nagios test message, the plugin works fine" width={700} />
|
||||
|
||||
If your backup was completed successfully, the result should look like this:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/transport-nagios-backup-successful.png" alt="A Nagios service row in OK state after a successful backup job" width={700} />
|
||||
|
||||
### Further resources
|
||||
|
||||
- [Nagios website](https://www.nagios.org/)
|
||||
- [Official Nagios documentation](https://www.nagios.org/documentation/)
|
||||
|
||||
## Icinga 2
|
||||
|
||||
The `transport-icinga2` plugin does the same job for Icinga 2: it pushes the backup result as a **passive check result** through the Icinga 2 REST API (`/v1/actions/process-check-result`), so no NSCA daemon is needed.
|
||||
|
||||
1. In **Settings → Plugins**, enable `transport-icinga2`.
|
||||
2. Configure it:
|
||||
- **Server**: the Icinga 2 HTTP/HTTPS API address (e.g. `https://icinga2.example.com`). If no port is given in the URL, `5665` is used.
|
||||
- **User** and **password**: the Icinga 2 API credentials.
|
||||
- **Filter**: an [Icinga 2 API filter](https://icinga.com/docs/icinga2/latest/doc/12-icinga2-api/#filters) selecting the service(s) to update, e.g. `host.name=="xoa.example.com" && service.name=="xo-backup"`.
|
||||
- Optionally, accept unauthorized (self-signed) certificates.
|
||||
3. Choose the report condition in your backup job.
|
||||
|
||||
Backup results are mapped to the standard Icinga 2 states: `OK` for a success, `WARNING` for a partial success, `CRITICAL` for a failure.
|
||||
|
||||
## Web hooks
|
||||
|
||||
You can also configure web hooks to be sent to a custom server before and/or after a backup job runs. This won't send a formatted report but raw JSON data that you can use in custom scripts on your side. Follow the [web-hooks plugin documentation](./advanced#web-hooks) to configure it.
|
||||
|
||||
@@ -1,63 +1,77 @@
|
||||
# Backup troubleshooting
|
||||
|
||||
This section is dedicated to help you if you have problems with XO Backups.
|
||||
This page lists the most common errors you can meet with XO backups, what they mean and how to fix them.
|
||||
|
||||
## Backup progress
|
||||
|
||||
While a backup job is running, you should see activity in the "Tasks" view (Menu/Tasks), like this:
|
||||
While a backup job is running, you should see activity in the Tasks view (main menu, then Tasks):
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/export-task.png" alt="The Tasks view during a backup run, showing a VDI export task at 49% with its progress bar" width={700} />
|
||||
|
||||
Another good way to check if there is activity is the XOA VM stats view (on the Network graph).
|
||||
Another good way to check for activity is the XOA VM stats view: the Network graph shows the transfer traffic while data is being moved.
|
||||
|
||||
## Unexpected key (full) export
|
||||
|
||||
_Incremental Backup_ and _Incremental Replication_ usually produce delta exports after the initial seed.
|
||||
|
||||
Nevertheless, there may be some reasons for XO to trigger a key (full) export instead:
|
||||
Nevertheless, there are several reasons for XO to trigger a key (full) export instead:
|
||||
|
||||
- the configured [_Full backup interval_](incremental_backups#key-backup-interval) advanced setting has been reached for this VM
|
||||
- the _Force full backup_ is enabled for the current schedule
|
||||
- the _Force full backup_ option is enabled for the current schedule
|
||||
- a new disk has been added to the VM (only this disk is completely exported)
|
||||
- the reference snapshot for this backup job on the source VM is missing
|
||||
- the previous exported backup/replication is either missing or corrupted
|
||||
- the reference snapshot for this backup job is missing on the source VM
|
||||
- the previously exported backup/replication is missing or corrupted
|
||||
- XO could not compute a safe delta for a disk (for example a qcow2 disk exported without NBD): it forces a full rather than risking a broken chain
|
||||
|
||||
:::tip
|
||||
Recent XO releases record the cause of the fallback as a warning in the backup job log, for example `can't compute delta <VDI> from <base>, fall back to a full`. When a run is unexpectedly full, check the job log first.
|
||||
:::
|
||||
|
||||
## VDI chain protection
|
||||
|
||||
Backup jobs regularly delete snapshots. When a snapshot is deleted, either manually or via a backup job, it triggers the need for XCP-ng/XenServer to coalesce the VDI chain - to merge the remaining VDIs and base copies in the chain. This means generally we cannot take too many new snapshots on said VM until XCP-ng/XenServer has finished running a coalesce job on the VDI chain.
|
||||
Backup jobs regularly delete snapshots. Every time a snapshot is deleted, manually or by a backup job, XCP-ng/XenServer needs to coalesce the VDI chain, that is merge the remaining VDIs and base copies. Until that coalesce is done, taking more snapshots on the VM keeps growing the chain.
|
||||
|
||||
This mechanism and scheduling is handled by XCP-ng/XenServer itself, not Xen Orchestra. But we can check your existing VDI chain and avoid creating more snapshots than your storage can merge. If we don't, this will lead to catastrophic consequences. Xen Orchestra is the **only** XCP-ng/XenServer backup product that takes this into account and offers protection.
|
||||
Coalescing is scheduled and performed by XCP-ng/XenServer itself, not by Xen Orchestra. But XO checks the existing VDI chain before snapshotting, and refuses to create more snapshots than your storage can merge. Xen Orchestra is the **only** XCP-ng/XenServer backup product offering this protection.
|
||||
|
||||
Without this detection, you could have 2 potential issues:
|
||||
Without this detection, you would eventually hit one of these:
|
||||
|
||||
- `The Snapshot Chain is too Long`
|
||||
- `SR_BACKEND_FAILURE_44 (insufficient space)`
|
||||
- `The Snapshot Chain is too Long`: the chain contains more than 30 elements, a fixed XCP-ng/XenServer limit
|
||||
- `SR_BACKEND_FAILURE_44 (insufficient space)`: the coalesce process couldn't keep up and the storage filled up
|
||||
|
||||
The first issue is a chain that contains more than 30 elements (fixed XCP-ng/XenServer limit), and the other one means it's full because the "coalesce" process couldn't keep up the pace and the storage filled up.
|
||||
|
||||
In the end, this message is a **protection mechanism preventing damage to your SR**. The backup job will fail, but XCP-ng/XenServer itself should eventually automatically coalesce the snapshot chain, and the next time the backup job should complete.
|
||||
So when a run is skipped with the `unhealthy VDI chain` message, it's a **protection mechanism preventing damage to your SR**, not a failure: XCP-ng/XenServer should coalesce the chain on its own, and the next run should complete normally.
|
||||
|
||||
Just remember this: **a coalesce should happen every time a snapshot is removed**.
|
||||
|
||||
> You can read more on this on our dedicated blog post regarding [XCP-ng/XenServer coalesce detection](https://xen-orchestra.com/blog/xenserver-coalesce-detection-in-xen-orchestra/).
|
||||
:::tip
|
||||
You can read more about this in our dedicated blog post on [XCP-ng/XenServer coalesce detection](https://xen-orchestra.com/blog/xenserver-coalesce-detection-in-xen-orchestra/).
|
||||
:::
|
||||
|
||||
### Troubleshooting a constant VDI Chain Protection message (XCP-ng/XenServer failure to coalesce)
|
||||
|
||||
As previously mentioned, this message can be normal and it just means XCP-ng/XenServer needs to perform a coalesce to merge old snapshots. However if you repeatedly get this message and it seems XCP-ng/XenServer is not coalescing, You can take a few steps to determine why.
|
||||
As explained above, this message can be normal: XCP-ng/XenServer simply needs time to merge old snapshots. However, if you get it repeatedly and the host never seems to coalesce, take the following steps to find out why.
|
||||
|
||||
First check SMlog on the XCP-ng/XenServer host for messages relating to VDI corruption or coalesce job failure. For example, by running `cat /var/log/SMlog | grep -i exception` or `cat /var/log/SMlog | grep -i error` on the XCP-ng/XenServer host with the affected storage.
|
||||
First, check `SMlog` on the XCP-ng/XenServer host holding the affected storage, looking for VDI corruption or coalesce job failures:
|
||||
|
||||
Coalesce jobs can also fail to run if the SR does not have enough free space. Check the problematic SR and make sure it has enough free space, generally 30% or more free is recommended depending on VM size. You can check if this is the issue by searching `SMlog` with `grep -i coales /var/log/SMlog` (you may have to look at previous logs such as `SMlog.1`).
|
||||
<Terminal shell title="XCP-ng host: search SMlog for coalesce failures">{`
|
||||
grep -i exception /var/log/SMlog
|
||||
grep -i error /var/log/SMlog
|
||||
`}</Terminal>
|
||||
|
||||
You can check if a coalesce job is currently active by running `ps axf | grep vhd` on the XCP-ng/XenServer host and looking for a VHD process in the results (one of the resulting processes will be the grep command you just ran, ignore that one).
|
||||
Coalesce jobs can also fail to run if the SR is short on free space. Check the problematic SR: 30% or more free space is generally recommended, depending on VM size. You can confirm this scenario by searching the logs (also look at rotated files such as `SMlog.1`):
|
||||
|
||||
If you don't see any running coalesce jobs, and can't find any other reason that XCP-ng/XenServer has not started one, you can attempt to make it start a coalesce job by rescanning the SR. This is harmless to try, but will not always result in a coalesce. Visit the problematic SR in the XOA UI, then click the "Rescan All Disks" button towards the top right: it looks like a refresh circle icon. This should begin the coalesce process - if you click the Advanced tab in the SR view, the "disks needing to be coalesced" list should become smaller and smaller.
|
||||
<Terminal shell title="XCP-ng host: check coalesce attempts in SMlog">{`
|
||||
grep -i coales /var/log/SMlog
|
||||
`}</Terminal>
|
||||
|
||||
As a last resort, migrating the VM (more specifically, its disks) to a new storage repository will also force a coalesce and solve this issue. That means migrating a VM to another host (with its own storage) and back will force the VDI chain for that VM to be coalesced, and get rid of the `VDI Chain Protection` message.
|
||||
To check whether a coalesce job is currently active, look for a VHD process on the host (one of the results will be the `grep` command itself, ignore it):
|
||||
|
||||
## Parse Error
|
||||
<Terminal shell title="XCP-ng host: look for a running coalesce process">{`
|
||||
ps axf | grep vhd
|
||||
`}</Terminal>
|
||||
|
||||
This is most likely due to running a backup job that uses Delta functionality (eg: delta backups, or continuous replication) on a version of XenServer older than 6.5. To use delta functionality you must run [XenServer 6.5 or later](./supported_hosts#xenserver-formerly-citrix-hypervisor).
|
||||
If no coalesce job is running and you can't find a reason why XCP-ng/XenServer hasn't started one, you can try to trigger it by rescanning the SR. This is harmless, but doesn't always start a coalesce. Open the problematic SR in the XOA UI and click the "Rescan All Disks" button towards the top right (the refresh circle icon). In the SR's Advanced tab, the "disks needing to be coalesced" list should then shrink progressively.
|
||||
|
||||
As a last resort, migrating the VM disks to another storage repository forces a coalesce: moving the VM to another host with its own storage and back will merge the VDI chain and get rid of the `VDI Chain Protection` message.
|
||||
|
||||
## SR_BACKEND_FAILURE_44
|
||||
|
||||
@@ -65,59 +79,70 @@ This is most likely due to running a backup job that uses Delta functionality (e
|
||||
This message can be triggered by any backup method.
|
||||
:::
|
||||
|
||||
`SR_BACKEND_FAILURE_44 (insufficient space)` means the Storage Repository (where your VM disks are currently stored) is full. Note that doing a snapshot on a thick provisioned SR (LVM family for all block devices, like iSCSI, HBA or Local LVM) will consume the current disk size. Eg if you are using this kind of SR at more than 50% and you want to backup ALL VM disks on it, you'll hit this wall.
|
||||
`SR_BACKEND_FAILURE_44 (insufficient space)` means the Storage Repository (where your VM disks are currently stored) is full. Keep in mind that a snapshot on a thick provisioned SR (the LVM family used by all block devices: iSCSI, HBA, local LVM) consumes the full current disk size. For example, if this kind of SR is more than 50% full and you back up ALL the VM disks on it, you will hit this wall.
|
||||
|
||||
Workarounds:
|
||||
|
||||
- use a thin provisioned SR (local ext, NFS, XOSAN)
|
||||
- wait for Citrix to release thin provisioning on LVM
|
||||
- wait for Citrix to allow another mechanism besides snapshot to be able to export disks
|
||||
- use less than 50% of SR space or don't backup all VMs
|
||||
- use a thin provisioned SR (local ext, NFS)
|
||||
- stay under 50% SR usage, or don't back up all the VMs stored on it
|
||||
|
||||
## Could not find the base VM
|
||||
|
||||
This message appears when the previous replicated VM has been deleted on the target side which breaks the replication. To reset the process it's necessary to delete VM snapshot related to this CR job on the original VM. The name of this snapshot is: `XO_DELTA_EXPORT: <name label of target SR> (<UUID of target SR>)`
|
||||
This error historically appeared when the previously replicated VM had been deleted on the target side, breaking the incremental replication chain.
|
||||
|
||||
Current XO releases no longer fail in this situation: when the base cannot be found, the job automatically falls back to a full export and continues (see [Unexpected key (full) export](#unexpected-key-full-export)).
|
||||
|
||||
If you still see this error on an older XO version, delete the reference snapshot of this replication job on the source VM, then run the job again to restart the chain from a new full. The snapshot is named `[XO Backup <job name>] <VM name>` (or `XO_DELTA_EXPORT: <name label of target SR> (<UUID of target SR>)` on very old versions).
|
||||
|
||||
## LICENSE_RESTRICTION
|
||||
|
||||
`LICENSE_RESTRICTION (PCI_device_for_auto_update)` message appears when you try to do a backup/snapshot from a VM that was previously on a host with an **active commercial XenServer license** but is now on a host with a free edition of XenServer/Citrix Hypervisor.
|
||||
`LICENSE_RESTRICTION (PCI_device_for_auto_update)` appears when you try to back up or snapshot a VM that previously ran on a host with an **active commercial XenServer license**, but now runs on a host with a free edition of XenServer/Citrix Hypervisor.
|
||||
|
||||
To solve it, you have to change a parameter in your VM. `xe vm-param-set has-vendor-device=false uuid=<VM_UUID>`.
|
||||
To solve it, disable the vendor device on the VM:
|
||||
|
||||
<Terminal shell title="XCP-ng host: disable the vendor device on the VM">{`
|
||||
xe vm-param-set has-vendor-device=false uuid=<VM_UUID>
|
||||
`}</Terminal>
|
||||
|
||||
## ENOSPC: no space left on device
|
||||
|
||||
This message appears when you do not have enough free space on the target remote when running a backup to it.
|
||||
This message appears when the target backup repository (BR) runs out of free space during a backup.
|
||||
|
||||
To check your free space, enter your XOA and run `xoa check` to check free system space and `df -h` to check free space on your chosen remote storage.
|
||||
From your XOA, check the free system space and the free space on the BR:
|
||||
|
||||
<Terminal shell title="xoa: check free space">{`
|
||||
xoa check
|
||||
df -h
|
||||
`}</Terminal>
|
||||
|
||||
## Error: no VMs match this pattern
|
||||
|
||||
This is happening when you have a _smart backup job_ that doesn't match any VMs. For example: you created a job to backup all running VMs. If no VMs are running on backup schedule, you'll have this message. This could also happen if you lost connection with your pool master (the VMs aren't visible anymore from Xen Orchestra).
|
||||
This happens when a _smart backup job_ doesn't match any VMs. For example: you created a job to back up all running VMs, and no VM is running when the schedule fires. It can also happen if you lost the connection to your pool master, since the VMs are no longer visible to Xen Orchestra.
|
||||
|
||||
Edit your job and try to see matching VMs or check if your pool is connected to XOA.
|
||||
Edit your job to review the matching VMs, or check that your pool is connected to XOA. Note that the run is reported as **skipped** rather than failed, so you are notified without the whole sequence being interrupted.
|
||||
|
||||
## Error: SR_OPERATION_NOT_SUPPORTED
|
||||
|
||||
This error can be caused by leaving any removable device (such as USB storage) attached to the VM that you are backing up or snapshotting, detach the device and retry. This can also be caused if you created a VM disk using the [RAW format](https://xcp-ng.org/docs/storage.html#using-raw-format).
|
||||
This error can be caused by a removable device (such as USB storage) left attached to the VM you are backing up or snapshotting: detach the device and retry. It can also happen if the VM has a disk using the [RAW format](https://xcp-ng.org/docs/storage.html#using-raw-format), which cannot be snapshotted.
|
||||
|
||||
## Error: Lock file is already being held
|
||||
|
||||
This error message appears in the logs in some instances of a failed backup job. It means that the VM’s folder on the remote is already used by a process. This could be:
|
||||
This error appears in the logs of some failed backup runs. It means the VM's folder on the backup repository (BR) is already in use by another process. This could be:
|
||||
|
||||
- another backup job
|
||||
- a merge process on the Virtual Hard Disk (VHD)
|
||||
|
||||
To solve this issue, we recommend that you:
|
||||
|
||||
- wait until the other backup job is completed/the merge process is done
|
||||
- make sure your remote storage is not being overworked
|
||||
- wait until the other backup job or the merge process is done
|
||||
- make sure your backup repository is not being overworked
|
||||
|
||||
## Error: HTTP connection has timed out
|
||||
|
||||
This error occurs when XO tries to fetch data from a host, via the HTTP GET method. This error essentially means that the host (dom0 specifically) isn't responding anymore, after we asked it to expose the disk to be exported. This could be a symptom of having an overloaded dom0 that couldn't respond fast enough. It can also be caused by dom0 having trouble attaching the disk in question to expose it for fetching via HTTP, or just not having enough resources to answer our GET request.
|
||||
This error occurs when XO fetches disk data from a host via an HTTP GET request, and the host (the dom0 specifically) stops responding after being asked to expose the disk to export. It's usually a symptom of an overloaded dom0: not enough resources to answer the request, or trouble attaching the disk to expose it.
|
||||
|
||||
::: warning
|
||||
As a temporary workaround you can increase the timeout greater than the default value, to allow the host more time to respond. But you will need to eventually diagnose the root cause of the slow host response or else you risk the issue returning.
|
||||
:::warning
|
||||
As a temporary workaround, you can raise the inactivity timeout above the default value (5 minutes) to give the host more time to respond. But you still need to diagnose the root cause of the slow host response, or the issue will come back.
|
||||
:::
|
||||
|
||||
Create the following file:
|
||||
@@ -134,18 +159,20 @@ Add the following lines:
|
||||
httpInactivityTimeout = 1800000 # 30 mins
|
||||
```
|
||||
|
||||
Then restart the `xo-server` service to apply the change.
|
||||
|
||||
## Error: Expected values to be strictly equal
|
||||
|
||||
This error occurs at the end of the transfer. XO checks the exported VM disk integrity, to ensure it's a valid VHD file (we check the VHD header as well as the footer of the received file). This error means the header and footage did not match, so the file is incomplete (likely the export from dom0 failed at some point and we only received a partial HD/VM disk).
|
||||
This error occurs at the end of the transfer, when XO checks the integrity of the exported VM disk to ensure it's a valid VHD file (both the VHD header and the footer of the received file are verified). The error means the check failed: the file is incomplete, most likely because the export from the dom0 stopped at some point and XO only received a partial disk.
|
||||
|
||||
## Error: the job is already running
|
||||
|
||||
This means the same job is still running, typically from the last scheduled run. This happens when you have a backup job scheduled too often. It can also occur if you have a long timeout configured for the job, and a slow VM export or slow transfer to your remote. In either case, you need to adjust your backup schedule to allow time for the job to finish or timeout before the next scheduled run. We consider this an error to ensure you'll be notified that the planned schedule won't run this time because the previous one isn't finished.
|
||||
The full message is `the job (<id>) is already running`: the same job is still busy, typically from the previous scheduled run. This happens when a backup job is scheduled too often, or when a long timeout is configured and a VM export or the transfer to the backup repository (BR) is slow. In either case, adjust the schedule so the job has time to finish (or time out) before the next run. XO treats this as an error on purpose, so you are notified that the planned run was not executed because the previous one wasn't finished.
|
||||
|
||||
## Error: VDI_IO_ERROR
|
||||
|
||||
This error comes directly from your host/dom0, and not XO. Essentially, XO asked the host to expose a VM disk to export via HTTP (as usual), XO managed to make the HTTP GET connection, and even start the transfer. But then at some point the host couldn't read the VM disk any further, causing this error on the host side. This might happen if the VDI is corrupted on the storage, or if there's a race condition during snapshots. More rarely, this can also occur if your SR is just too slow to keep up with the export as well as live VM traffic.
|
||||
This error comes directly from your host/dom0, not from XO. XO asked the host to expose a VM disk over HTTP as usual, established the connection and even started the transfer, but at some point the host couldn't read the VM disk any further. This can happen if the VDI is corrupted on the storage or if there's a race condition during snapshots. More rarely, it can also mean your SR is too slow to keep up with the export on top of the live VM traffic.
|
||||
|
||||
## Error: no XAPI associated to `UUID`
|
||||
|
||||
This message means that XO had a UUID of a VM to backup, but when the job ran it couldn't find any object matching it. This could be caused by the pool where this VM lived no longer being connected to XO. Double-check that the pool hosting the VM is currently connected under Settings > Servers. You can also search for the VM UUID in the Home > VMs search bar. If you can see it, run the backup job again and it will work. If you cannot, either the VM was removed or the pool is not connected.
|
||||
This message means XO had the UUID of a VM to back up, but couldn't find any matching object when the job ran. The usual cause is that the pool hosting this VM is no longer connected to XO. Double-check that the pool is connected under Settings > Servers, and search for the VM UUID in the Home > VMs search bar. If you can see the VM, run the backup job again and it will work. If you cannot, either the VM was removed or its pool is disconnected.
|
||||
|
||||
+280
-141
@@ -1,7 +1,24 @@
|
||||
# Concepts
|
||||
---
|
||||
sidebar_label: Features and settings
|
||||
---
|
||||
|
||||
# Backup features and settings
|
||||
|
||||
<InterfaceNote>This page describes the backup configuration in the XO 5 interface. XO 6 already shows your jobs, their runs and each VM's protection status; creating, editing and restoring still happens here.</InterfaceNote>
|
||||
|
||||
This section is dedicated to all general concepts about Xen Orchestra backups.
|
||||
|
||||
:::note Replication modes have been renamed
|
||||
The two replication job types now have clearer names, but the XO 5 screens below still show the former ones:
|
||||
|
||||
| Current name | Former name, still shown in XO 5 |
|
||||
| ------------------------------------------------------------------ | -------------------------------- |
|
||||
| [Full replication](../full_replication.md) | Disaster Recovery (DR) |
|
||||
| [Incremental replication](incremental_replication.md) | Continuous Replication (CR) |
|
||||
|
||||
Nothing changed in behaviour: only the labels differ. XO 6 uses the current names, and the tags XO puts on replicas (`Disaster Recovery`, `Continuous Replication`) kept the former ones.
|
||||
:::
|
||||
|
||||
## Interface
|
||||
|
||||
### Overview
|
||||
@@ -10,7 +27,7 @@ This is the welcome panel for the backup view. It recaps all existing scheduled
|
||||
|
||||
### Logs
|
||||
|
||||
All the scheduled operations (backup, snapshots and even DR) are displayed in the main backup view.
|
||||
All the scheduled operations (backup, snapshots and even replication) are displayed in the main backup view.
|
||||
|
||||
A successful backup task will be displayed in green, a faulty one in red. You can click on the arrow to see each entry detail.
|
||||
|
||||
@@ -36,13 +53,13 @@ Here's an example:
|
||||
|
||||
`<34>Jun 24 14:32:01 server1 CRON[1234]: (root) CMD (/usr/bin/backup.sh)`
|
||||
|
||||
##### Using Syslog with Xen Orchestra
|
||||
##### Using syslog with Xen Orchestra
|
||||
|
||||
You can send all your XO logs to an external syslog server.
|
||||
|
||||
To enable syslog, add this to your configuration file (`/etc/xo-server/config.toml`):
|
||||
|
||||
```
|
||||
```toml
|
||||
[logs.transport.syslog]
|
||||
target = 'tcp://syslog.example.org:514'
|
||||
```
|
||||
@@ -55,38 +72,39 @@ This setup is compatible with any syslog server, such as [Rsyslog](https://www.r
|
||||
|
||||
### Backups execution
|
||||
|
||||
Each backups' job execution is identified by a `runId`. You can find this `runId` in its detailed log.
|
||||
Each backup job execution is identified by a `runId`. You can find this `runId` in its detailed log.
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/backup-log-run-id.png" alt="Detailed log of a backup run: the runId is displayed next to the job name, with the copy and report-a-bug buttons" width={480} />
|
||||
|
||||
## Backup Encryption
|
||||
## Backup encryption
|
||||
|
||||
Xen Orchestra ensures robust data security for backups stored remotely, by leveraging advanced encryption algorithms. Here's a closer look at how encryption works and the technology behind it:
|
||||
|
||||
### Authentication
|
||||
|
||||
The encryption algorithms are authenticated, meaning additional metadata is appended to the end of each saved file. During restoration, this metadata ensures that the restored data matches the original encrypted data, allowing the system to detect issues like bit rot or tampering by an attacker without the encryption key. However, it's important to note that this is not a recoverable error—if the verification fails, the file will be unusable.
|
||||
The encryption algorithms are authenticated, meaning additional metadata is appended to the end of each saved file. During restoration, this metadata ensures that the restored data matches the original encrypted data, allowing the system to detect issues like bit rot or tampering by an attacker without the encryption key. However, it's important to note that this is not a recoverable error: if the verification fails, the file will be unusable.
|
||||
|
||||
### Configuring encryption
|
||||
|
||||
Encryption is opt-in and requires configuring an encryption key on the remote.
|
||||
Encryption is opt-in and requires configuring an encryption key on the backup repository.
|
||||
|
||||
:::warning
|
||||
|
||||
- Encryption is only compatible with block-based remotes.
|
||||
- Encryption cannot be changed (such as enabling, disabling or changing the encryption key) if a remote contains any backup.
|
||||
:::
|
||||
- Encryption is only compatible with block-based backup repositories: incremental backups sent to an encrypted repository must be stored as multiple data blocks, not as a whole VHD file.
|
||||
- Encryption cannot be changed (such as enabling, disabling or changing the encryption key) if a backup repository contains any backup.
|
||||
|
||||
1. Go to the Settings → Remote menu.
|
||||
2. Go to the section called **New file system remote**, or edit an existing remote.
|
||||
:::
|
||||
|
||||
1. Go to the **Settings → Remotes** menu.
|
||||
2. Go to the section called **New file system remote**, or edit an existing backup repository.
|
||||
3. In the subsection called **Encrypt all new data sent to this remote** you will find a text area. Enter your encryption key there.
|
||||
4. Click the **Save configuration** Button to finish the encryption setup.
|
||||
4. Click the **Save configuration** button to finish the encryption setup.
|
||||
|
||||
### `ChaCha20-Poly1305`
|
||||
|
||||
To improve flexibility and performance, Xen Orchestra will transition to the [`ChaCha20-Poly1305`](https://en.wikipedia.org/wiki/ChaCha20-Poly1305) encryption algorithm by February 2025. This update addresses the file size limitations of `AES-256-GCM` while maintaining a high level of security and compliance with ANSSI guidelines.
|
||||
Since February 2025, Xen Orchestra encrypts backup repositories with the [`ChaCha20-Poly1305`](https://en.wikipedia.org/wiki/ChaCha20-Poly1305) algorithm. This update addresses the file size limitations of `AES-256-GCM` while maintaining a high level of security and compliance with ANSSI guidelines.
|
||||
|
||||
Backup repositories that were encrypted with `AES-256-GCM` will remain accessible, to ensure a smooth transition.
|
||||
Backup repositories that were encrypted with `AES-256-GCM` remain accessible, to ensure a smooth transition.
|
||||
|
||||
### `AES-256-GCM`
|
||||
|
||||
@@ -94,9 +112,9 @@ Backup repositories that were encrypted with `AES-256-GCM` will remain accessibl
|
||||
|
||||
#### What is AES-256-GCM?
|
||||
|
||||
Currently, backups use the [`AES-256-GCM`](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard) encryption algorithm. While this is a highly secure option, it does have a file size limitation of 64 GiB. This isn't an issue when working with incremental backups, as the data is split into smaller blocks, making it fully compatible with any remote (S3-compatible or file-based).
|
||||
Backups on repositories encrypted before February 2025 use the [`AES-256-GCM`](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard) encryption algorithm. While this is a highly secure option, it has a file size limitation of 64 GiB. This isn't an issue when working with incremental backups, as the data is split into smaller blocks, making it fully compatible with any backup repository (S3-compatible or file-based).
|
||||
|
||||
Full backups create one file per backup with all the data, that can go over 64 GB, even when using XCP-ng zstd encryption.
|
||||
Full backups create one file per backup with all the data, which can go over 64 GiB, even with XCP-ng zstd compression enabled.
|
||||
|
||||
#### Compliance
|
||||
|
||||
@@ -104,13 +122,13 @@ The `AES-256-GCM` algorithm is fully compliant with [ANSSI guidelines (in French
|
||||
|
||||
### Switching to the new encryption algorithm
|
||||
|
||||
If you see an exclamation mark next to the encryption icon on a remote, it means the encryption algorithm isn't the recommended one.
|
||||
If you see an exclamation mark next to the encryption icon on a backup repository, it means the encryption algorithm isn't the recommended one.
|
||||
|
||||
To switch to `ChaCha20-Poly1305`, follow these steps:
|
||||
|
||||
1. Make sure the remote doesn't contain any backups encrypted with the old algorithm.
|
||||
2. If the remote has `AES-256-GCM` backups, create a new remote and do a full backup to that location.
|
||||
3. Once all backups with the old encryption are gone, set up encryption on the remote with the new algorithm.
|
||||
1. Make sure the backup repository doesn't contain any backups encrypted with the old algorithm.
|
||||
2. If the repository has `AES-256-GCM` backups, create a new backup repository and do a full backup to that location.
|
||||
3. Once all backups with the old encryption are gone, set up encryption on the repository with the new algorithm.
|
||||
4. The exclamation mark should disappear.
|
||||
|
||||
If the warning icon is still there, double-check that no encrypted backups remain before switching algorithms.
|
||||
@@ -121,6 +139,10 @@ During a backup job, you can avoid saving all disks of the VM. To do that is tri
|
||||
|
||||
The disks marked with `[NOBAK]` will be now ignored in all following backups.
|
||||
|
||||
:::tip
|
||||
To exclude a whole VM from every backup job, give the VM the `xo:no-bak` tag instead. See [backup modifier tags](#backup-modifier-tags).
|
||||
:::
|
||||
|
||||
## Schedule
|
||||
|
||||
### Introduction
|
||||
@@ -135,39 +157,42 @@ To see the schedules associated with a specific backup job:
|
||||
|
||||
1. Navigate to the **Backup** menu.\
|
||||
A list of backup jobs will be displayed.
|
||||
2. For the backup job you're interested in, click the **pencil** ✏️ icon in the **Notes** column.\
|
||||
2. For the backup job you're interested in, click the **pencil** icon in the **Notes** column.\
|
||||
This will open the backup job details screen.
|
||||
3. In the **Schedules** section of the details screen, you'll find the list of schedules for that backup job:
|
||||
|
||||

|
||||
<UiShot light="/img/xo5/backup-schedule-list.png" alt="An incremental replication job in edit mode, with the Schedules section highlighted on the right" url="https://your-xo/v5/#/backup" />
|
||||
|
||||
### Creating a schedule
|
||||
|
||||
To set up a schedule for a backup job:
|
||||
|
||||
1. Navigate to the details page of your backup job (refer to the previous section, "Viewing Schedules for a Backup Job").
|
||||
2. In the **Schedules** section of your backup job, click the **Add a schedule** button, represented by a ➕ icon.\
|
||||
1. Navigate to the details page of your backup job (refer to the previous section, "Viewing schedules for a backup job").
|
||||
2. In the **Schedules** section of your backup job, click the **Add a schedule** button, represented by a plus icon.\
|
||||
A form for creating a schedule will appear:
|
||||

|
||||
|
||||
<UiDetail src="/img/xo5/create-backup-schedule.png" alt="The Schedule creation form: name, retention, health check, force full backup, then the month/day/hour/minute pickers, timezone, cron pattern and run preview" width={480} />
|
||||
|
||||
3. Use the form to configure your schedule.\
|
||||
Here's a list of the parameters you can adjust:
|
||||
|
||||
| Parameter | Description |
|
||||
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | --- |
|
||||
| **Name** | A label to identify your schedule. Useful when managing multiple jobs. |
|
||||
| **Pool retention** | Number of snapshots to keep for pool metadata. Older snapshots beyond this count will be automatically removed. |
|
||||
| **XO retention** | Number of snapshots to keep for XO metadata. Older snapshots beyond this count will be automatically removed. | |
|
||||
| **Replication retention** | Number of replicated snapshots to keep. Older snapshots beyond this count will be automatically removed. |
|
||||
| **Health check** | If enabled, a VM [health check](#backup-health-check) is performed after the backup to detect issues early (e.g., boot errors). |
|
||||
| **Force full backup** | Forces a full backup at every run, even if incremental backups are enabled. |
|
||||
| **Month(s)** | Select specific months during which the schedule should run. |
|
||||
| **Day(s)** | Select days of the month for the job to execute. You can choose specific dates or all days. |
|
||||
| **Hour** | Choose the hour of the day the backup job should start. |
|
||||
| **Minute** | Choose the exact minute the job should start. |
|
||||
| **Timezone** | Determines the timezone in which the schedule should apply. You can also use your browser's local timezone. |
|
||||
| **Cron Pattern** | Automatically generated from your selections to define when the job will run. |
|
||||
| **Preview** | A list of upcoming executions based on your current configuration. Useful to verify the setup. |
|
||||
| Parameter | Description |
|
||||
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| **Name** | A label to identify your schedule. Useful when managing multiple jobs. |
|
||||
| **Backup retention** | Number of backups to keep on the backup repository (shown for _Backup_ and _Delta Backup_ jobs). Older backups beyond this count are automatically removed. |
|
||||
| **Replication retention** | Number of replicated VMs to keep on the target SR (shown for _DR_ and _CR_ jobs). Older copies beyond this count are automatically removed. |
|
||||
| **Snapshot retention** | Number of rolling snapshots to keep on the VM itself (shown when _Rolling Snapshot_ is enabled). |
|
||||
| **Pool retention** | Number of pool metadata backups to keep (metadata backup jobs only). |
|
||||
| **XO retention** | Number of XO configuration backups to keep (metadata backup jobs only). |
|
||||
| **Health check** | If enabled, a VM [health check](#backup-health-check) is performed after the backup to detect issues early (e.g., boot errors). |
|
||||
| **Force full backup** | Forces a full backup at every run of this schedule, even if the job is incremental (delta jobs only). |
|
||||
| **Month(s)** | Select specific months during which the schedule should run. |
|
||||
| **Day(s)** | Select days of the month for the job to execute. You can choose specific dates or all days. |
|
||||
| **Hour** | Choose the hour of the day the backup job should start. |
|
||||
| **Minute** | Choose the exact minute the job should start. |
|
||||
| **Timezone** | Determines the timezone in which the schedule should apply. You can also use your browser's local timezone. |
|
||||
| **Cron Pattern** | Automatically generated from your selections to define when the job will run. |
|
||||
| **Preview** | A list of upcoming executions based on your current configuration. Useful to verify the setup. |
|
||||
|
||||
:::tip
|
||||
|
||||
@@ -178,55 +203,68 @@ Depending on your backup type, not all settings may be visible, particularly tho
|
||||
4. Click the **OK** button.\
|
||||
Your schedule will be created and applied to the backup job.
|
||||
|
||||
## Smart Backup
|
||||
## Backup sequences {#sequences}
|
||||
|
||||
By default, every schedule fires on its own cron: two jobs planned at the same time will run in parallel and compete for resources. A **sequence** chains existing schedules instead: pick the schedules to include, order them, and give the sequence its own cron. When it fires, the schedules run **one after the other**, in the order you defined.
|
||||
|
||||
To create one, go to the **Backup** view, open the **Sequences** tab and click **New sequence**: name it, add the schedules in the desired order, and set when the sequence itself runs.
|
||||
|
||||
Typical use: run the backup job first, then the replication job on the same VMs, without guessing how long the first one takes.
|
||||
|
||||
## Smart backup {#smart-backup}
|
||||
|
||||
There are two ways to select which VMs will be backed up:
|
||||
|
||||
1. Manually selecting multiple VM's
|
||||
1. Manually selecting multiple VMs
|
||||
1. Smart backup
|
||||
|
||||
Picking VMs manually can be a limitation if your environment moves fast (i.e. having new VMs you need to backup often). In that situation you would previously need to constantly go back and edit the backup job to add new VM's.
|
||||
Picking VMs manually can be a limitation if your environment moves fast (i.e. new VMs to protect are created often). In that situation you would previously need to constantly go back and edit the backup job to add the new VMs.
|
||||
|
||||
But thanks to _smart backup_, you now have more flexibility: you won't select specific VMs, but VMs status/tag/placement **at the time backup job will be executed**. Let's see some examples!
|
||||
Thanks to _smart backup_, you have more flexibility: instead of specific VMs, you select criteria (power state, pool placement, tags), and the job resolves them **at the time the backup job is executed**. Let's see some examples!
|
||||
|
||||
### Backup all VMs on a pool
|
||||
|
||||
This job will backup all VMs on a pool "Lab Pool" when scheduled:
|
||||
This job will back up all VMs on the pool "Lab Pool" when scheduled:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/smart-backup-pool.png" alt="Smart mode in a backup job: VMs statuses set to All and Resident on set to Lab Pool" width={620} />
|
||||
|
||||
It means: **every VM existing on this pool at the time of the backup job will be backed up**. Doesn't matter if you create a new VM, it will be backed up too without editing any backup job.
|
||||
|
||||
**You now have the ability to intelligently backup VM's in production pools!**
|
||||
**You now have the ability to intelligently backup VMs in production pools!**
|
||||
|
||||
Want to narrow the job a bit? See below.
|
||||
|
||||
### Backup filters
|
||||
|
||||
You can also:
|
||||
Smart mode offers the following criteria, evaluated at each run:
|
||||
|
||||
- backup only running (or halted) VMs when the job is executed
|
||||
- backup only VMs with a specific tag
|
||||
- **VMs statuses**: back up all VMs, only running VMs, or only halted VMs
|
||||
- **Pools**: only VMs resident on the selected pools, with an optional exclusion list (**Not resident on**)
|
||||
- **Tags**: only VMs carrying at least one of the selected tags, with an optional list of excluded tags
|
||||
|
||||
Remember the Prod VMs? I added a tag "prod" to each of them:
|
||||
:::tip
|
||||
XO pre-fills the excluded tags with `Continuous Replication`, `Disaster Recovery` and the XO proxy tag, so a smart backup job doesn't back up the replicas created by your own replication jobs. Those two tag values kept the former names of the incremental and full replication modes, and XO still writes them as such on the replicas. VMs tagged `xo:no-bak` are always excluded, whatever the job configuration.
|
||||
:::
|
||||
|
||||

|
||||
Remember the prod VMs? I added a tag "prod" to each of them:
|
||||
|
||||
<UiDetail src="/img/xo5/vm-prod-tag.png" alt="The Home view with four VMs, each carrying the prod tag" width={620} />
|
||||
|
||||
Now if you do this:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/smart-backup-pool-tag.png" alt="Smart mode combining Resident on Lab Pool with the prod tag" width={420} />
|
||||
|
||||
It means any VMs on "Lab Pool" with the "prod" tag will be backed up.
|
||||
|
||||
## RAM Enabled backup
|
||||
## RAM enabled backup
|
||||
|
||||
:::tip
|
||||
This feature is **only compatible** with XCP-ng 8.0 or more recent. Citrix Hypervisor didn't yet merge our changes, despite we contributed to their code directly.
|
||||
This feature is **only compatible** with XCP-ng 8.0 or more recent. Citrix Hypervisor never merged our changes, even though we contributed them to their code directly.
|
||||
:::
|
||||
|
||||

|
||||
XCP-ng modified XAPI is able to create VMs in a `Suspended` state with a `suspend_VDI` property set. When a VM is suspended, all of its memory contents are written into a disk called `suspend_VDI`. When the VM is restored, the `suspend_VDI` is read to recreate the memory of the VM. Once the resuming is done it's as if the VM was never suspended.
|
||||
|
||||
XCP-ng modified XAPI is now able to create VMs in a `Suspended` state with a `suspend_VDI` property set. When a VM is suspended, all of its memory contents are written into a disk called `suspend_VDI`. When the VM is restored, the `suspend_VDI` is read to recreate the memory of the VM. Once the resuming is done it's as if the VM was never suspended.
|
||||
In practice, a RAM enabled backup takes a **checkpoint** of the VM: a snapshot that includes both the disks and the memory contents. You can enable it per job with the snapshot mode setting, or per VM with the `xo-memory-backup` tag (see [backup modifier tags](#backup-modifier-tags)).
|
||||
|
||||
### Use cases
|
||||
|
||||
@@ -240,11 +278,11 @@ This can be very useful when you're running a VM that needs RAM coherence to run
|
||||
|
||||
In a nutshell this functionality can be seen as _hot copy_, similar to _hot migration_ but the original VM is not deleted.
|
||||
|
||||
### Continuous replication with RAM
|
||||
### Incremental replication with RAM {#continuous-replication-with-ram}
|
||||
|
||||
This feature allows you to regularly send a copy of a VM to a target SR. The copied VM will be `Suspended` and ready to be resumed if the original VM encounters issues. As the copied VM is `Suspended`, no reboot will be required, resuming it is much faster.
|
||||
|
||||
For instance, if an hourly continuous replication is configured on a VM, if the VM is lost, you can quickly resume a running VM with a memory loss of one hour tops.
|
||||
For instance, if an hourly incremental replication is configured on a VM, if the VM is lost, you can quickly resume a running VM with a memory loss of one hour tops.
|
||||
|
||||
:::warning
|
||||
In order to use this functionality, the CPU of the host the VM is restored on should be the same or more recent than the CPU of the host the VM was originally running on.
|
||||
@@ -252,44 +290,43 @@ In order to use this functionality, the CPU of the host the VM is restored on sh
|
||||
|
||||
### Future of RAM enabled backup
|
||||
|
||||
- Better analyze of compatible CPUs to avoid manual compatibility checks
|
||||
- RAM snapshot using Xen copy-on-write memory capabilities (time to snapshot reduce to almost 0)
|
||||
- Better analysis of compatible CPUs to avoid manual compatibility checks
|
||||
- RAM snapshot using Xen copy-on-write memory capabilities (time to snapshot reduced to almost 0)
|
||||
|
||||
## Consistent backup
|
||||
|
||||
:::warning
|
||||
This feature is being deprecated in XCP-ng and Citrix Hypervisor. It's now replaced by RAM enabled backup!
|
||||
Quiesced (VSS) snapshots are gone: the feature was removed from XCP-ng and Citrix Hypervisor, and Xen Orchestra no longer attempts them. Use [RAM enabled backup](#ram-enabled-backup) instead when you need consistency beyond a plain disk snapshot.
|
||||
:::
|
||||
|
||||
All backup types rely on snapshots. But what about data consistency? By default, Xen Orchestra will try to take a **quiesced snapshot** every time a snapshot is done (and fall back to normal snapshots if it's not possible).
|
||||
All backup types rely on snapshots. But what about data consistency? Older XenServer releases could take a **quiesced snapshot** of a Windows VM: with the guest tools and the extra VSS provider installed, the operating system was notified and flushed its caches to disk before the snapshot, making backups of services like MS SQL or Exchange consistent. Xen Orchestra used to try a quiesced snapshot first and fall back to a normal snapshot when it wasn't possible.
|
||||
|
||||
Snapshots of Windows VMs can be quiesced (especially MS SQL or Exchange services) after you have installed Xen Tools in your VMs. However, [there is an extra step to install the VSS provider on windows](https://xen-orchestra.com/blog/xenserver-quiesce-snapshots/). A quiesced snapshot means the operating system will be notified and the cache will be flushed to disks. This way, your backups will always be consistent.
|
||||
Since the VSS provider was removed from the guest tools and the `snapshot_with_quiesce` capability was dropped from the platform, this mechanism no longer exists. Xen Orchestra now always takes normal snapshots, and offers two ways to get a stronger consistency level per VM:
|
||||
|
||||
To see if you have quiesced snapshots for a VM, just go into its snapshot tab, then the "info" icon means it is a quiesced snapshot:
|
||||
- [RAM enabled backup](#ram-enabled-backup) (checkpoint): the memory is captured together with the disks, so caches and transient transactions are preserved.
|
||||
- Offline snapshot or offline backup: the VM is cleanly shut down before the export, guaranteeing on-disk consistency.
|
||||
|
||||

|
||||
Both can be applied per VM with [backup modifier tags](#backup-modifier-tags). Old quiesced snapshots taken before the removal are still identified by an "info" icon in the VM's Snapshots tab.
|
||||
|
||||
The tooltip confirms this:
|
||||
## Backup repositories (BR) {#remotes}
|
||||
|
||||

|
||||
Backup repositories (BR), formerly called _remotes_, are places where your _backup_ and _delta backup_ files will be stored.
|
||||
|
||||
## Remotes
|
||||
To add one, go to the **Settings/Remotes** menu (the XO 5 screens still use the former name).
|
||||
|
||||
Remotes are places where your _backup_ and _delta backup_ files will be stored.
|
||||
|
||||
To add a _remote_, go to the **Settings/Remotes** menu.
|
||||
|
||||
Supported remote types:
|
||||
Supported backup repository types:
|
||||
|
||||
- Local (any folder in XOA filesystem)
|
||||
- NFS
|
||||
- SMB (CIFS)
|
||||
- Amazon S3 and S3-compatible object storage
|
||||
- Microsoft Azure Blob Storage
|
||||
|
||||
:::warning
|
||||
|
||||
- The initial "/" or "\\" is automatically added.
|
||||
- For disks larger than **2 TB**, store backups on **block-based remotes**.
|
||||
- For **qcow2** disks, enable [NBD](https://docs.xen-orchestra.com/incremental_backups#nbd-enabled-backups) for incremental backups — without it, each run falls back to a full backup.
|
||||
- For disks larger than **2 TiB**, store backups on **block-based backup repositories**. Since QCOW2 reached general availability in XCP-ng, a single disk can grow up to **16 TiB**, so this matters more than ever.
|
||||
- For **qcow2** disks, enable [NBD](./incremental_backups.md#nbd-enabled-backups) for incremental backups: without it, each run falls back to a full backup.
|
||||
|
||||
:::
|
||||
|
||||
@@ -299,7 +336,7 @@ On your NFS server, authorize XOA's IP address and permissions for subfolders. T
|
||||
|
||||
### SMB
|
||||
|
||||
We support SMB storage on _Windows Server 2012 R2_.
|
||||
We support SMB storage on _Windows Server 2012 R2_ and later.
|
||||
|
||||
:::warning
|
||||
For continuous delta backup, SMB is **NOT** recommended (or only for small VMs, eg < 50GB)
|
||||
@@ -313,7 +350,7 @@ Also, read the UI twice when you add an SMB store. If you have:
|
||||
|
||||
You'll have to fill it like this:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/smb-remote-settings.png" alt="New file system remote form for SMB: host and share on the first field, the optional path field left empty, then username, password and domain" width={480} />
|
||||
|
||||
:::warning
|
||||
PATH TO BACKUP is only needed if you have subfolders in your share.
|
||||
@@ -327,7 +364,7 @@ PATH TO BACKUP is only needed if you have subfolders in your share.
|
||||
|
||||
If you need to mount an unsupported store (FTP for example), you can always do it manually:
|
||||
|
||||
1. mount your remote store inside the XOA filesystem manually, e.g in `/media/myStore`
|
||||
1. mount your storage inside the XOA filesystem manually, e.g in `/media/myStore`
|
||||
2. in the web interface, select a "local" store and point it to your `/media/myStore` folder.
|
||||
|
||||
Any Debian Linux mount point could be supported this way, until we add further options directly in the web interface.
|
||||
@@ -338,18 +375,22 @@ Xen Orchestra supports Amazon S3 storage and other S3-compatible providers, so y
|
||||
|
||||
:::warning
|
||||
|
||||
- Not all S3-compatible providers adhere perfectly to Amazon S3 standards. Make sure to test your setup before trusting it with critical backups.
|
||||
- Not all S3-compatible providers adhere perfectly to Amazon S3 standards. Check the [supported object storage providers](../object-storage-support.md) list and its support tiers, and test your setup before trusting it with critical backups.
|
||||
- Losing your encryption key means your backups will be permanently inaccessible. If you enable encryption, make sure your key is stored securely, and outside of the backed up infrastructure, as there's no way to recover your data without it.
|
||||
|
||||
:::
|
||||
|
||||

|
||||
:::note
|
||||
XO identifies itself to object storage providers with a `User-Agent: Xen Orchestra FS <version>` header, which helps S3-compatible services (Wasabi and others) with compatibility tracking.
|
||||
:::
|
||||
|
||||
<UiDetail src="/img/xo5/s3-remote-settings.png" alt="New file system remote form with the Amazon Web Services S3 type selected: endpoint, region, bucket, directory, credentials and the optional encryption key" width={620} />
|
||||
|
||||
### Microsoft Azure
|
||||
|
||||
Xen Orchestra supports Microsoft Azure Blob Storage as a remote, as well as [Azurite](https://learn.microsoft.com/en-us/azure/storage/common/storage-use-azurite) (the Azure Storage emulator) for testing purposes.
|
||||
Xen Orchestra supports Microsoft Azure Blob Storage as a backup repository, as well as [Azurite](https://learn.microsoft.com/en-us/azure/storage/common/storage-use-azurite) (the Azure Storage emulator) for testing purposes.
|
||||
|
||||
To configure an Azure remote, you'll need:
|
||||
To configure an Azure backup repository, you'll need:
|
||||
|
||||
- **Storage account name**, used as the username
|
||||
- **Access key**, used as the password
|
||||
@@ -359,9 +400,21 @@ To configure an Azure remote, you'll need:
|
||||
|
||||
- When using Azurite instead of real Azure, select the **Azurite** type and provide the emulator's host/port.
|
||||
- Container names must be **lowercase**.
|
||||
:::
|
||||
|
||||

|
||||
:::
|
||||
|
||||
<UiDetail src="/img/xo5/azure-remote-settings.png" alt="New file system remote form with the Azure type selected: host, account name, key, container and path" width={620} />
|
||||
|
||||
### Inspect and repair a BR from the command line {#backups-cli}
|
||||
|
||||
The `xo-backups` CLI (from the [`@xen-orchestra/backups-cli`](https://www.npmjs.com/package/@xen-orchestra/backups-cli) package) lets you explore the contents of a backup repository, verify backup sets and repair issues from a terminal, without going through the web interface:
|
||||
|
||||
<Terminal shell title="check and clean the VM backups of a repository">{`
|
||||
npm install --global @xen-orchestra/backups-cli
|
||||
xo-backups clean-vms --merge xo-vm-backups/*
|
||||
`}</Terminal>
|
||||
|
||||
It also works against a whole repository URL (including S3, Azure or encrypted ones) with `--remote=<BR URL>`. Run `xo-backups --help` for the full command list.
|
||||
|
||||
## Restore a backup
|
||||
|
||||
@@ -395,7 +448,7 @@ Make sure the following conditions are met in order to do a differential restore
|
||||
|
||||
- Restore the VM to the **same Storage Repository** that contains the VM to be restored.
|
||||
- The backup you're restoring must be a **delta backup** (not a full backup).
|
||||
- The delta chain — from the original snapshot to the backup you're restoring, excluding the base VM — must be **uninterrupted**.
|
||||
- The delta chain, from the original snapshot to the backup you're restoring (excluding the base VM), must be **uninterrupted**.
|
||||
|
||||
:::
|
||||
|
||||
@@ -409,7 +462,9 @@ To perform a differential restore:
|
||||
More parameters appear, including a drop-down list for your destination Storage Repository (SR).
|
||||
4. From that drop-down list, choose your destination SR.
|
||||
5. Activate the switch called **Use differential restore**:
|
||||

|
||||
|
||||
<UiDetail src="/img/xo5/use-differential-restore.png" alt="The Restore VM modal with the Use differential restore switch enabled" width={620} />
|
||||
|
||||
6. Click **OK** to start the restore.
|
||||
|
||||
## File level restore
|
||||
@@ -418,7 +473,7 @@ You can also restore specific files and directories inside a VM. It works with a
|
||||
|
||||
:::warning
|
||||
|
||||
- File level restore **is only possible on incremental backups**. Also, due of some technical limitations, you won't be able to do file level restore if you have a chain longer than 99 (ie retention longer than 99 records without any full between). Take a look at the [key backup interval section](./incremental_backups/#key-backup-interval) to set this correctly.
|
||||
- File level restore **is only possible on incremental backups**. Also, due to some technical limitations, you won't be able to do file level restore if you have a chain longer than 99 (ie retention longer than 99 records without any full between). Take a look at the [key backup interval section](./incremental_backups.md#key-backup-interval) to set this correctly.
|
||||
- File level restore **is only possible on a single VDI**, it does not support LVM Volume Groups that span multiple VDIs.
|
||||
- The following Microsoft solutions are **not supported**:
|
||||
- [Data Deduplication](https://learn.microsoft.com/en-us/windows-server/storage/data-deduplication/overview)
|
||||
@@ -430,10 +485,13 @@ You can also restore specific files and directories inside a VM. It works with a
|
||||
### Restore a file
|
||||
|
||||
1. Go to the **Backup → File restore** section:
|
||||

|
||||
|
||||
<UiShot light="/img/xo5/file-level-restore-list.png" alt="The File restore tab lists the VMs with available backups and their last backup date" url="https://your-xo/v5/#/backup/file-restore" />
|
||||
|
||||
2. Choose the VM whose files you want to restore and click the **Restore** icon at the corresponding line.
|
||||
3. Follow the instructions as shown below:
|
||||

|
||||
|
||||
<UiDetail src="/img/xo5/file-level-restore-modal.png" alt="The Restore file modal: pick a backup, a disk, browse to the file, then choose the export format (tar+gzip or ZIP)" width={620} />
|
||||
|
||||
That's it! Your chosen file will be restored.
|
||||
|
||||
@@ -463,11 +521,9 @@ First, after your disk is attached to XOA, you'll have to find the new disk name
|
||||
|
||||
Then, create a filesystem on it:
|
||||
|
||||
```sh
|
||||
mkfs.ext4 /dev/xvdb
|
||||
```
|
||||
<Terminal shell title="Format the new disk">{`mkfs.ext4 /dev/xvdb`}</Terminal>
|
||||
|
||||
If you already have backups done, you can move them to the new disk. The orignal backups folder is in `/var/lib/xoa-backups`.
|
||||
If you already have backups done, you can move them to the new disk. The original backups folder is in `/var/lib/xoa-backups`.
|
||||
|
||||
To make the mount point persistent in XOA, edit the `/etc/fstab` file, and add:
|
||||
|
||||
@@ -479,18 +535,23 @@ This way, without modifying your previous scheduled snapshot, they will be writt
|
||||
|
||||
## HA behavior
|
||||
|
||||
Replicated VMs HA are taken into account by XCP-ng. To avoid the resultant troubles, HA will be disabled from the replicated VMs and a tag indicating this change will be added.
|
||||
XCP-ng takes replicated VMs into account for High Availability. To avoid the resulting trouble (HA trying to restart your replicas), XO disables HA on the replicated VMs and adds a tag indicating this change.
|
||||
|
||||

|
||||

|
||||
A full replication replica, carrying the `Disaster Recovery` and `HA disabled` tags:
|
||||
|
||||
<UiDetail src="/img/xo5/disabled-dr-ha-tag.png" alt="A full replication replica: the VM carries the Disaster Recovery and HA disabled tags" width={620} />
|
||||
|
||||
An incremental replication replica, carrying the `Continuous Replication` and `HA disabled` tags:
|
||||
|
||||
<UiDetail src="/img/xo5/disabled-cr-ha-tag.png" alt="An incremental replication replica: the VM carries the Continuous Replication and HA disabled tags" width={620} />
|
||||
|
||||
:::tip
|
||||
The tag won't be automatically removed by XO on the replicated VMs, even if HA is re-enabled.
|
||||
:::
|
||||
|
||||
## Backup Concurrency
|
||||
## Backup concurrency
|
||||
|
||||
Xen Orchestra 5.20 introduces new tools to manage backup concurrency. Below is an overview of the backup process and ways you can control concurrency in your own environment.
|
||||
Xen Orchestra 5.20 introduced new tools to manage backup concurrency. Below is an overview of the backup process and ways you can control concurrency in your own environment.
|
||||
|
||||
### Backup process
|
||||
|
||||
@@ -508,7 +569,7 @@ When it's done exporting, we'll remove the snapshot. Note: this operation will t
|
||||
|
||||
### Concurrency
|
||||
|
||||
Concurrency is a parameter that let you define how many VMs your backup job will manage simultaneously.
|
||||
Concurrency is a parameter that lets you define how many VMs your backup job will manage simultaneously.
|
||||
|
||||
:::tip
|
||||
|
||||
@@ -538,7 +599,7 @@ High concurrency could impact your dom0 and network performances.
|
||||
You should be aware of your hardware limitation when defining the best concurrency for your XCP-ng infrastructure, never put concurrency too high or you could impact your VMs performances.
|
||||
The best way to define the best concurrency for you is by increasing it slowly and watching the result on backup time.
|
||||
|
||||
So to summarize, if you set your concurrency at 6 and you have 20 Vms to backup the process will be the following:
|
||||
So to summarize, if you set your concurrency at 6 and you have 20 VMs to backup the process will be the following:
|
||||
|
||||
- We start the backup of the first 6 VMs.
|
||||
- When one VM backup has ended we will launch the next VM backup.
|
||||
@@ -550,23 +611,24 @@ Removing the snapshot will trigger the coalesce process for the first VM, this i
|
||||
|
||||
When a backup job is configured using Normal snapshot mode, it's possible to use VM tags to apply a different snapshot mode to individual VMs.
|
||||
|
||||
- **xo-offline-backup** to apply offline snapshotting mode (VM will be shut down prior to snapshot)
|
||||
- **xo-memory-backup** to apply RAM-enabled snapshotting
|
||||
- **xo-backup-health-check-xenstore** to use a script during [backup healthcheck](#backup-health-check)
|
||||
- **xo:no-health-check** ignore this VM during [backup healthcheck](#backup-health-check)
|
||||
- **xo-offline-backup** to apply offline snapshotting mode (VM will be shut down prior to snapshot, then restarted)
|
||||
- **xo-memory-backup** to apply RAM-enabled snapshotting (checkpoint, see [RAM enabled backup](#ram-enabled-backup))
|
||||
- **xo-backup-health-check-xenstore** to use a script during [backup health check](#backup-health-check)
|
||||
- **xo:no-health-check** (or **xo:no-health-check=reason**) to ignore this VM during [backup health check](#backup-health-check)
|
||||
- **xo:no-bak** (or **xo:no-bak=reason**) to exclude this VM from **all** backup jobs, even if it's explicitly selected. XO itself uses `xo:no-bak=Health Check` on the ephemeral VMs restored during health checks.
|
||||
|
||||
For example, you could have a regular backup job with 10 VMs configured with Normal snapshotting, including two which are database servers. Since database servers are generally more sensitive to being restored from snapshots, you could apply the **xo-memory-backup** tag to those two VMs and only those will be backed up in RAM-enabled mode. This will avoid the need to manage a separate backup job and schedule.
|
||||
|
||||
## Retention and Scheduling
|
||||
## Retention and scheduling
|
||||
|
||||
Just a refresher/summary: You can select multiple backup methods for the same job:
|
||||
|
||||
- Full: _Backup_ and _Disaster Recovery_ (DR)
|
||||
- Deltas: _Delta Backup_ and _Continuous Replication_ (CR)
|
||||
- Full: _Backup_ and _Full replication_ (the XO 5 button still reads _Disaster Recovery_)
|
||||
- Deltas: _Delta Backup_ and _Incremental replication_ (the XO 5 button still reads _Continuous Replication_)
|
||||
|
||||
The Full and Delta options are mutually exclusive; Rolling Snapshots are compatible with both. The Backup and Delta Backup go to a remote Target (e.g, NFS); DR and CR back up to another XCP-ng storage repository (i.e., not the one on which the VM's being backed up reside). In the Schedule configuration, you will have the option to select the number of "Backup Retention" if your backup includes a _Backup_ (or _Delta Backup_); you will have the option to select the number "Replication Retention" if you have selected _DR_ or _CR_ in the backup configuration.
|
||||
The Full and Delta options are mutually exclusive; Rolling Snapshots are compatible with both. The Backup and Delta Backup go to a backup repository (e.g. NFS); both replication modes write to another XCP-ng storage repository (i.e., not the one on which the VMs being backed up reside). In the Schedule configuration, you will have the option to select the number of "Backup Retention" if your backup includes a _Backup_ (or _Delta Backup_); you will have the option to select the number "Replication Retention" if you have selected a replication mode in the backup configuration.
|
||||
|
||||
### Rolling Snapshots
|
||||
### Rolling snapshots
|
||||
|
||||
This feature is close to Backups, but it creates a snapshot when planned to do so. It also handles the retention (to remove the oldest snapshot).
|
||||
|
||||
@@ -578,13 +640,13 @@ Vates recommends keeping the Rolling Snapshots retention to a minimum; if you ch
|
||||
|
||||
To know more, read this [blog article](https://xen-orchestra.com/blog/xen-orchestra-4-2/#schedulerollingsnapshots).
|
||||
|
||||
### Retention of Backups and CR/DR
|
||||
### Retention of backups and replications {#retention-of-backups-and-cr-dr}
|
||||
|
||||
If your backup includes both a (Delta) Backup _and_ a CR/DR, you will have the option to select the number you wish for both "Backup retention" and "Replication retention" in the Schedule configuration; make sure to assign the number you want to the correct retention.
|
||||
If your backup includes both a (Delta) Backup _and_ a replication, you will have the option to select the number you wish for both "Backup retention" and "Replication retention" in the Schedule configuration; make sure to assign the number you want to the correct retention.
|
||||
|
||||
If you need to restore a (Delta) Backup (or clone and spin up a VM from CR/DR), you will be able to select all the available backups or VMs, regardless of the retention or delta scheme. If you have multiple backup jobs backing up the same VM, you'll see all the backups in the restore list, sorted by date.
|
||||
If you need to restore a (Delta) Backup (or clone and spin up a VM from a replica), you will be able to select all the available backups or VMs, regardless of the retention or delta scheme. If you have multiple backup jobs backing up the same VM, you'll see all the backups in the restore list, sorted by date.
|
||||
|
||||
### Decreasing Retention Frequency with Age
|
||||
### Decreasing retention frequency with age
|
||||
|
||||
It is often a good idea to configure retention of older backups with decreasing frequency. For example, you may want a nightly backup, but you don't want 365 backups to be able to restore from a year ago. The solution is to set several different schedules/retention policies for the same backup job. A reasonable approach might be to schedule...
|
||||
|
||||
@@ -594,9 +656,53 @@ It is often a good idea to configure retention of older backups with decreasing
|
||||
|
||||
Again, all of these can be assigned to the same backup job. Note that if you do a weekly and a monthly backup, at some point, these will fall on the same day. Xen Orchestra is designed to fail gracefully (with an error message) if a backup job for a VM is already running. For this reason, you will want to set the time on the monthly job to run before the weekly job so that if one fails, it will be the weekly rather than the monthly one; if the weekly one fails, the monthly will be there for that spot in the retention plan; if the monthly one fails, the weekly one will only be retained for 4 weeks, and then there will be a gap in the monthly retention.
|
||||
|
||||
### Long-term Backup Retention with GFS Strategy
|
||||
### Long-term backup retention with GFS strategy
|
||||
|
||||
Xen Orchestra supports the **Grandfather-Father-Son (GFS)** backup retention strategy, providing an efficient way to manage long-term backups. Backups are organized into daily, weekly, and monthly intervals, optimizing storage while keeping important recovery points over time.
|
||||
Xen Orchestra supports the **Grandfather-Father-Son (GFS)** backup retention strategy, providing an efficient way to manage long-term backups. Backups are organized into daily, weekly, monthly and yearly intervals, optimizing storage while keeping important recovery points over time.
|
||||
|
||||
<Schema label="GFS on a month of nightly runs, with 7 daily, 4 weekly and 1 monthly restore points kept" legend={[["#56c288", "daily"], ["#6aabf0", "weekly"], ["#e0a94a", "monthly"], ["#7a8699", "rotated out"]]} maxWidth="640px">
|
||||
<svg viewBox="0 0 640 232" role="img" aria-label="A calendar of 28 nightly backups: the last 7 are kept as daily restore points, the first backup of each week is kept as a weekly one, the first of the month as a monthly one, and every other backup is rotated out">
|
||||
<g fontSize="11" fill="#7a8699">
|
||||
<text x="24" y="69">week 1</text>
|
||||
<text x="24" y="111">week 2</text>
|
||||
<text x="24" y="153">week 3</text>
|
||||
<text x="24" y="195">week 4</text>
|
||||
</g>
|
||||
{/* Rotated-out runs (dim) */}
|
||||
<g opacity="0.35">
|
||||
<g fill="rgba(255,255,255,0.04)" stroke="rgba(255,255,255,0.28)">
|
||||
<rect x="156" y="50" width="40" height="28" rx="4"/><rect x="222" y="50" width="40" height="28" rx="4"/><rect x="288" y="50" width="40" height="28" rx="4"/><rect x="354" y="50" width="40" height="28" rx="4"/><rect x="420" y="50" width="40" height="28" rx="4"/><rect x="486" y="50" width="40" height="28" rx="4"/>
|
||||
<rect x="156" y="92" width="40" height="28" rx="4"/><rect x="222" y="92" width="40" height="28" rx="4"/><rect x="288" y="92" width="40" height="28" rx="4"/><rect x="354" y="92" width="40" height="28" rx="4"/><rect x="420" y="92" width="40" height="28" rx="4"/><rect x="486" y="92" width="40" height="28" rx="4"/>
|
||||
<rect x="156" y="134" width="40" height="28" rx="4"/><rect x="222" y="134" width="40" height="28" rx="4"/><rect x="288" y="134" width="40" height="28" rx="4"/><rect x="354" y="134" width="40" height="28" rx="4"/><rect x="420" y="134" width="40" height="28" rx="4"/><rect x="486" y="134" width="40" height="28" rx="4"/>
|
||||
</g>
|
||||
<g fontSize="12" fill="#c6d2e1" textAnchor="middle">
|
||||
<text x="176" y="68">2</text><text x="242" y="68">3</text><text x="308" y="68">4</text><text x="374" y="68">5</text><text x="440" y="68">6</text><text x="506" y="68">7</text>
|
||||
<text x="176" y="110">9</text><text x="242" y="110">10</text><text x="308" y="110">11</text><text x="374" y="110">12</text><text x="440" y="110">13</text><text x="506" y="110">14</text>
|
||||
<text x="176" y="152">16</text><text x="242" y="152">17</text><text x="308" y="152">18</text><text x="374" y="152">19</text><text x="440" y="152">20</text><text x="506" y="152">21</text>
|
||||
</g>
|
||||
</g>
|
||||
{/* Weekly keeps: first backup of each week */}
|
||||
<g fill="rgba(106,171,240,0.14)" stroke="#6aabf0" strokeWidth="1.5">
|
||||
<rect x="90" y="50" width="40" height="28" rx="4" fill="rgba(224,169,74,0.16)" stroke="#e0a94a"/>
|
||||
<rect x="90" y="92" width="40" height="28" rx="4"/>
|
||||
<rect x="90" y="134" width="40" height="28" rx="4"/>
|
||||
</g>
|
||||
<text x="110" y="42" fontSize="10" fill="#e0a94a" textAnchor="middle">monthly</text>
|
||||
{/* Daily keeps: the last 7 runs */}
|
||||
<g fill="rgba(86,194,136,0.14)" stroke="#56c288" strokeWidth="1.5">
|
||||
<rect x="90" y="176" width="40" height="28" rx="4" strokeWidth="2.4" stroke="#6aabf0" fill="rgba(86,194,136,0.14)"/>
|
||||
<rect x="156" y="176" width="40" height="28" rx="4"/><rect x="222" y="176" width="40" height="28" rx="4"/><rect x="288" y="176" width="40" height="28" rx="4"/><rect x="354" y="176" width="40" height="28" rx="4"/><rect x="420" y="176" width="40" height="28" rx="4"/><rect x="486" y="176" width="40" height="28" rx="4"/>
|
||||
</g>
|
||||
<g fontSize="12" fill="#c6d2e1" textAnchor="middle">
|
||||
<text x="110" y="68">1</text>
|
||||
<text x="110" y="110">8</text>
|
||||
<text x="110" y="152">15</text>
|
||||
<text x="110" y="194">22</text><text x="176" y="194">23</text><text x="242" y="194">24</text><text x="308" y="194">25</text><text x="374" y="194">26</text><text x="440" y="194">27</text><text x="506" y="194">28</text>
|
||||
</g>
|
||||
<text x="560" y="194" fontSize="11" fill="#56c288">today</text>
|
||||
<text x="320" y="224" fontSize="10.5" fill="#7a8699" textAnchor="middle">day 1 counts as monthly and weekly · day 22 counts as weekly and daily</text>
|
||||
</svg>
|
||||
</Schema>
|
||||
|
||||
#### FAQ
|
||||
|
||||
@@ -607,7 +713,7 @@ Xen Orchestra supports the **Grandfather-Father-Son (GFS)** backup retention str
|
||||
GFS retention is applied on a per-repository basis, allowing you to manage retention independently for different storage locations.
|
||||
|
||||
- **How does Xen Orchestra decide which backups to retain?**\
|
||||
The oldest backup within each retention period (daily, weekly, or monthly) is preserved. For example, the first backup of the week is saved as the weekly backup.
|
||||
The oldest backup within each retention period (daily, weekly, monthly or yearly) is preserved. For example, the first backup of the week is saved as the weekly backup.
|
||||
|
||||
:::warning
|
||||
|
||||
@@ -619,20 +725,20 @@ Xen Orchestra supports the **Grandfather-Father-Son (GFS)** backup retention str
|
||||
|
||||
:::
|
||||
|
||||
#### Enabling GFS Retention
|
||||
#### Enabling GFS retention
|
||||
|
||||
To enable GFS retention:
|
||||
|
||||
1. Go to the **Backup** menu.
|
||||
2. Create a new backup job or open an existing one.
|
||||
3. Click the **Delta Backup** button.\
|
||||
3. Click the **Backup** or **Delta Backup** button.\
|
||||
The section called **Long-term retention of backups** appears.
|
||||
4. In that section, you can define the following:
|
||||
|
||||
- **Daily backups**: The number of daily backups to keep.
|
||||
- **Weekly backups** (Son): The number of weekly backups to keep.
|
||||
- **Monthly backups** (Father): The number of monthly backups to keep.
|
||||
- **Yearly backups** (Grandfather): The number of yearly backups to keep.
|
||||
- **Weekly backups**: The number of weekly backups to keep.
|
||||
- **Monthly backups**: The number of monthly backups to keep.
|
||||
- **Yearly backups**: The number of yearly backups to keep.
|
||||
|
||||
5. Click the **Save** button.
|
||||
|
||||
@@ -640,17 +746,50 @@ During each backup run, Xen Orchestra evaluates existing backups and removes any
|
||||
|
||||
### Implementation in Xen Orchestra
|
||||
|
||||
To enable GFS retention, configure the settings in the backup job's "Retention" section. During each backup run, Xen Orchestra evaluates existing backups and removes any excess backups based on the configured policy.
|
||||
To enable GFS retention, configure the settings in the backup job's "Long-term retention of backups" section. During each backup run, Xen Orchestra evaluates existing backups and removes any excess backups based on the configured policy.
|
||||
|
||||
## Backup Health Check
|
||||
## Backup health check
|
||||
|
||||
Backup health check ensures the backups are ready to be restored.
|
||||
Backup health check ensures the backups are ready to be restored: after a run, XO restores the backup for real, boots it, and only marks it healthy if the guest comes up.
|
||||
|
||||
<Schema label="Health check: every step a real restore would take, run automatically" legend={[["#e0a94a", "backup"], ["#6aabf0", "test VM"], ["#56c288", "verified"]]} maxWidth="640px">
|
||||
<svg viewBox="0 0 640 140" role="img" aria-label="A backup stored on the backup repository is restored as a test VM, booted until the guest tools respond, then the test VM is deleted and the backup run is marked healthy">
|
||||
<rect x="14" y="38" width="132" height="58" rx="8" fill="rgba(224,169,74,0.12)" stroke="#e0a94a"/>
|
||||
<text x="80" y="63" fontSize="12.5" fill="#c6d2e1" textAnchor="middle">backup on BR</text>
|
||||
<text x="80" y="81" fontSize="10" fill="#7a8699" textAnchor="middle">or replica on SR</text>
|
||||
<g className="schema-flow" stroke="#6aabf0" strokeWidth="1.5" strokeDasharray="5 4">
|
||||
<line x1="146" y1="67" x2="176" y2="67"/>
|
||||
</g>
|
||||
<polygon points="182,67 174,63 174,71" fill="#6aabf0"/>
|
||||
<text x="163" y="54" fontSize="9.5" fill="#6aabf0" textAnchor="middle">restore</text>
|
||||
<rect x="184" y="38" width="118" height="58" rx="8" fill="rgba(106,171,240,0.12)" stroke="#6aabf0"/>
|
||||
<text x="243" y="63" fontSize="12.5" fill="#c6d2e1" textAnchor="middle">test VM</text>
|
||||
<text x="243" y="81" fontSize="10" fill="#7a8699" textAnchor="middle">on the chosen SR</text>
|
||||
<g className="schema-flow" stroke="#6aabf0" strokeWidth="1.5" strokeDasharray="5 4">
|
||||
<line x1="302" y1="67" x2="332" y2="67"/>
|
||||
</g>
|
||||
<polygon points="338,67 330,63 330,71" fill="#6aabf0"/>
|
||||
<text x="319" y="54" fontSize="9.5" fill="#6aabf0" textAnchor="middle">boot</text>
|
||||
<rect x="340" y="38" width="158" height="58" rx="8" fill="rgba(106,171,240,0.12)" stroke="#6aabf0"/>
|
||||
<text x="419" y="58" fontSize="12.5" fill="#c6d2e1" textAnchor="middle">guest tools up</text>
|
||||
<text x="419" y="74" fontSize="10" fill="#7a8699" textAnchor="middle">within 10 minutes</text>
|
||||
<text x="419" y="89" fontSize="10" fill="#7a8699" textAnchor="middle">or your script's verdict</text>
|
||||
<g className="schema-flow" stroke="#56c288" strokeWidth="1.5" strokeDasharray="5 4">
|
||||
<line x1="498" y1="67" x2="524" y2="67"/>
|
||||
</g>
|
||||
<polygon points="530,67 522,63 522,71" fill="#56c288"/>
|
||||
<rect x="532" y="38" width="94" height="58" rx="8" fill="rgba(86,194,136,0.14)" stroke="#56c288"/>
|
||||
<text x="579" y="63" fontSize="12.5" fill="#56c288" textAnchor="middle">healthy ✓</text>
|
||||
<text x="579" y="81" fontSize="10" fill="#7a8699" textAnchor="middle">test VM deleted</text>
|
||||
<text x="320" y="122" fontSize="10.5" fill="#7a8699" textAnchor="middle">a VM without guest tools fails the check · failures show up in the job report</text>
|
||||
</svg>
|
||||
</Schema>
|
||||
|
||||
### Different level of checking
|
||||
|
||||
#### Check for boot
|
||||
|
||||
XO will restore the VM, either by downloading it for a delta/full backup or by cloning it for a disaster recovery or continuous replication and then wait for the guest tools to be loaded before the end of a timeout of 10 minutes (boot + guest tools).
|
||||
XO will restore the VM, either by downloading it for a delta/full backup or by cloning it for a full or incremental replication, start it, and then wait for the guest tools to be loaded before the end of a timeout of 10 minutes (boot + guest tools).
|
||||
|
||||
A VM without guest tools will fail its health check.
|
||||
|
||||
@@ -660,37 +799,37 @@ The restored VM is then deleted.
|
||||
|
||||
If a VM has the tag **xo-backup-health-check-xenstore** during a backup health check, then XO will wait for a script to change the value of the xenstore `vm-data/xo-backup-health-check` key to be either `success` or `failure`.
|
||||
|
||||
In case of `failure`, it will mark the health check as failed, and will show the (optional) message contained in `vm-data/xo-backup-health-check-error`
|
||||
In case of `failure`, it will mark the health check as failed, and will show the (optional) message contained in `vm-data/xo-backup-health-check-error`.
|
||||
|
||||
The script needs to be planned on boot. It can check if the record `vm-data/xo-backup-health-check` of the local xenstore contains `planned`
|
||||
to differentiate a normal boot and a boot during health check.
|
||||
On success it must write `success`in `vm-data/xo-backup-health-check`.
|
||||
On failure it must write `failure` in `vm-data/xo-backup-health-check`, and may optionally add details in `vm-data/xo-backup-health-check-error` .
|
||||
On success it must write `success` in `vm-data/xo-backup-health-check`.
|
||||
On failure it must write `failure` in `vm-data/xo-backup-health-check`, and may optionally add details in `vm-data/xo-backup-health-check-error`.
|
||||
|
||||
The total timeout of a backup health check (boot + guest tools + scripts) is 10min.
|
||||
The total timeout of a backup health check (boot + guest tools + scripts) is 10 minutes.
|
||||
|
||||
The restored VM is then deleted.
|
||||
|
||||
An example in bash is shown in `@xen-orchestra/backups/docs/healthcheck example/wait30seconds.sh`
|
||||
An example script in shell is available in the repository: [`@xen-orchestra/backups/docs/healthcheck/example.sh`](https://github.com/vatesfr/xen-orchestra/blob/master/%40xen-orchestra/backups/docs/healthcheck/example.sh)
|
||||
|
||||
### Running Health checks
|
||||
### Running health checks
|
||||
|
||||
#### Checking a backup
|
||||
|
||||
Go to backup > restore and click on the tick to launch a health check.
|
||||
Go to **Backup → Restore** and click on the tick icon to launch a health check.
|
||||
|
||||

|
||||
<UiShot light="/img/xo5/restore-health-check.png" alt="The Restore tab: each backup row ends with the health check (tick), restore and delete buttons" url="https://your-xo/v5/#/backup/restore" />
|
||||
|
||||
Then, you will select the backup to be checked and a destination SR, which must have enough space for the full restore.
|
||||
|
||||
#### Scheduling health check after backups
|
||||
|
||||
Go to Backup > overview > edit.
|
||||
Go to **Backup → Overview** and edit your job.
|
||||
|
||||
Then edit the schedule and check the healthcheck box.
|
||||
Then edit the schedule and check the **Health check** box.
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/schedule-health-check.png" alt="The Schedule form with Health check enabled: optional VM tags filter and the SR used for the test restore" width={620} />
|
||||
|
||||
You will then need to select the SR used, which must have enough space to restore the VMs. Healthcheck will be done after each VM backup, before starting the next one.
|
||||
You will then need to select the SR used, which must have enough space to restore the VMs. Health check will be done after each VM backup, before starting the next one.
|
||||
|
||||
You can filter the VMs list by providing tags, only the VMs with these tags will be checked.
|
||||
|
||||
@@ -1,170 +0,0 @@
|
||||
# Credential Database Encryption
|
||||
|
||||
Xen Orchestra stores credentials for XenServer connections, remotes, users, and tokens in Redis. When credential encryption is enabled, all records are encrypted at rest using AES-256-GCM, and index keys are replaced with HMAC blind indexes so indexed field values (emails, hostnames, etc.) are not stored as plaintext. The performance impact is negligible for typical deployments.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- XO must be running as a VM on a XenServer/XCP-ng host and must be able to execute xenstore-read and xenstore-write commands (XenStore is required to store one of the two key halves)
|
||||
- The path `/var/lib/xo-server/data/` must be writable by the xo-server process
|
||||
|
||||
## Enabling Encryption
|
||||
|
||||
Add the following to your configuration file:
|
||||
|
||||
See [Configuration](./configuration.md)
|
||||
|
||||
```toml
|
||||
[redis]
|
||||
encryptCredentialDatabase = true
|
||||
```
|
||||
|
||||
On the next startup after enabling encryption, XO will:
|
||||
|
||||
1. Generate two random 32-byte key halves
|
||||
2. Store one half in XenStore (`vm-data/xo-encryption-key`) and one in `/var/lib/xo-server/data/xo-encryption-key` (mode `0400`)
|
||||
3. Derive an AES-256 encryption key and an HMAC key from the two halves using HKDF-SHA256
|
||||
4. Encrypt all existing Redis records and rebuild indexes as HMAC blind indexes
|
||||
5. Verify the migration and delete the plaintext backup on success
|
||||
|
||||
A plaintext backup is written to `/var/lib/xo-server/data/encryption-backup.json` before migration begins and deleted on success. If migration fails, this file is preserved for manual recovery.
|
||||
|
||||
## Key Management
|
||||
|
||||
The encryption key is split across two locations, compromise of one alone is not sufficient to decrypt the database:
|
||||
|
||||
| Half | Location |
|
||||
| ---- | ------------------------------------------- |
|
||||
| A | XenStore: `vm-data/xo-encryption-key` |
|
||||
| B | `/var/lib/xo-server/data/xo-encryption-key` |
|
||||
|
||||
Both halves are required to derive the actual encryption key. Neither half should be backed up in plaintext.
|
||||
|
||||
:::warning
|
||||
If either key half is lost, the database cannot be decrypted and XO will enter degraded mode until both key are setup correctly. Users won't be able to use XO while in degraded mode. Keep your config backup up to date.
|
||||
:::
|
||||
|
||||
## Config Backup
|
||||
|
||||
When credential encryption is enabled, exporting the XO configuration **requires a passphrase**. The passphrase protects the exported credentials with OpenPGP encryption.
|
||||
|
||||
See [Back up XO backup metadata](./backup_howto.md#specific-steps-for-the-xoa-vm)
|
||||
|
||||
The backup contains the decrypted credential data. When restored on any XO instance, it will be re-encrypted with that instance's keys automatically, no manual key transfer needed.
|
||||
|
||||
:::tip
|
||||
Always export a fresh config backup after enabling encryption and store it securely.
|
||||
:::
|
||||
|
||||
## Disabling Encryption
|
||||
|
||||
Set `encryptCredentialDatabase = false` (or remove the option) and restart. XO will detect the existing key files, decrypt all records, rebuild plaintext indexes, and delete the key files. The process is automatic.
|
||||
|
||||
An encrypted backup is written to `/var/lib/xo-server/data/encryption-backup.json` before migration begins and deleted on success. If migration fails, both key halves are kept and this file is preserved for manual recovery.
|
||||
|
||||
## Recovering from a Failed Migration
|
||||
|
||||
Both the encryption and decryption migrations write a backup of all Redis records to `/var/lib/xo-server/data/encryption-backup.json` before touching any data. The backup is deleted only on success.
|
||||
|
||||
### Failed Encryption Migration
|
||||
|
||||
If enabling encryption fails, XO will log:
|
||||
|
||||
```
|
||||
xo:crypto-credentials ERROR Credential database migration failed - running in degraded mode { backupPath: '/var/lib/xo-server/data/encryption-backup.json' }
|
||||
```
|
||||
|
||||
The backup file contains the original **plaintext** Redis records.
|
||||
|
||||
**Option 1 — Retry**
|
||||
|
||||
If the failure was transient (Redis timeout, XenStore momentarily unavailable), simply restart xo-server. Because the key files already exist, XO will load them and attempt to serve data normally. If the Redis data was not yet written (the migration is atomic), the data is still plaintext and readable.
|
||||
|
||||
**Option 2 — Roll back to plaintext**
|
||||
|
||||
If you want to abandon the migration and restore a clean state:
|
||||
|
||||
1. Stop xo-server.
|
||||
2. Remove both key halves:
|
||||
```bash
|
||||
xenstore-rm vm-data/xo-encryption-key
|
||||
rm /var/lib/xo-server/data/xo-encryption-key
|
||||
```
|
||||
3. If Redis data was partially written, restore it from the backup:
|
||||
```bash
|
||||
cat /var/lib/xo-server/data/encryption-backup.json
|
||||
```
|
||||
Use `xo-cli system.importConfig` with a pre-encryption config backup if one is available - this is the safest path.
|
||||
4. Set `encryptCredentialDatabase = false` (or remove the option) and restart.
|
||||
|
||||
**Option 3 — Restore from a config backup**
|
||||
|
||||
If you exported a config backup before enabling encryption, restore it:
|
||||
|
||||
```bash
|
||||
xo-cli system.importConfig
|
||||
```
|
||||
|
||||
This re-imports all credentials in plaintext and re-encrypts them with the current instance's keys automatically.
|
||||
|
||||
### Failed Decryption Migration
|
||||
|
||||
If disabling encryption fails, XO will log:
|
||||
|
||||
```
|
||||
xo:crypto-credentials ERROR Credential database migration failed - running in degraded mode { backupPath: '/var/lib/xo-server/data/encryption-backup.json' }
|
||||
```
|
||||
|
||||
The backup file contains the **encrypted** Redis records (the pre-decryption snapshot).
|
||||
|
||||
**Option 1 — Retry**
|
||||
|
||||
Both key halves are kept on disk after a decryption migration failure. Simply restart xo-server with `encryptCredentialDatabase` still unset or `false`, XO will detect the key files and retry the decryption migration automatically.
|
||||
|
||||
**Option 2 — Re-enable encryption, export config, then disable cleanly**
|
||||
|
||||
If retrying does not work, use the existing keys to get back to a working state and then perform a clean transition to plaintext:
|
||||
|
||||
1. Set `encryptCredentialDatabase = true` again and restart. XO will load the existing keys and serve the encrypted data normally without triggering any migration.
|
||||
2. Export your configuration with a passphrase:
|
||||
```bash
|
||||
xo-cli system.exportConfig passphrase=<your-passphrase>
|
||||
```
|
||||
or via the interface
|
||||
3. Set `encryptCredentialDatabase = false`, remove both key halves:
|
||||
```bash
|
||||
xenstore-rm vm-data/xo-encryption-key
|
||||
rm /var/lib/xo-server/data/xo-encryption-key
|
||||
```
|
||||
flush redis:
|
||||
```bash
|
||||
redis-cli FLUSHALL
|
||||
```
|
||||
and restart.
|
||||
4. XO will start with an empty credential database. Import the config backup:
|
||||
```bash
|
||||
xo-cli system.importConfig
|
||||
```
|
||||
The credentials are re-imported in plaintext with no encryption active.
|
||||
|
||||
## Degraded Mode
|
||||
|
||||
If XO cannot load or use the encryption keys at startup (missing keys, corrupted data, or a key mismatch), it enters degraded mode:
|
||||
|
||||
- The HTTP server remains available (support tunnel can connect)
|
||||
- All API calls are rejected with a clear error message
|
||||
- No server connections, logins, or remote access are possible
|
||||
|
||||
Check the server logs for details:
|
||||
|
||||
```
|
||||
xo:crypto-credentials ERROR Credential database encryption failed - running in degraded mode
|
||||
xo:crypto-credentials ERROR Credential database decryption failed — running in degraded mode
|
||||
xo:crypto-credentials ERROR Credential database migration failed - running in degraded mode
|
||||
xo:crypto-credentials ERROR Only one encryption key half found - running in degraded mode
|
||||
xo:crypto-credentials ERROR Existing key loading failed, decryption migration impossible - running in degraded mode
|
||||
```
|
||||
|
||||
**Recovery options:**
|
||||
|
||||
- Restore from a config backup made before the key was lost: `xo-cli system.importConfig`
|
||||
- Contact support — the HTTP server being available means a support tunnel can be established
|
||||
@@ -1,18 +0,0 @@
|
||||
# Full backups
|
||||
|
||||
You can schedule full backups of your VMs, by exporting them to the local XOA file-system, or directly to an NFS or SMB share. The "retention" parameter allows you to modify how many backups are retained (by removing the oldest one).
|
||||
|
||||
[](https://xen-orchestra.com/blog/backup-your-xenserver-vms-with-xen-orchestra/)
|
||||
|
||||
:::tip
|
||||
Full backups are space consuming! But they allow a very simple restoration without anything to think of (the file will contain all the VM disks and information). To use less space and data transferred, take a look at the [delta backups](./incremental_backups/) feature.
|
||||
:::
|
||||
|
||||
## Backup without snapshot
|
||||
|
||||
In some cases you will need to do a backup without doing a snapshot.
|
||||
|
||||
The most common use case for this is a large VM on a small local SR where you just don't have the space to do a snapshot before backup.
|
||||
So for that you need to open the advanced settings of your backup job, and check the offline backup check box:
|
||||
|
||||

|
||||
@@ -1,43 +0,0 @@
|
||||
# Full Replication
|
||||
|
||||
> **_NOTE:_** Formerly known as Disaster recovery
|
||||
|
||||
Full Replication (FR) encompasses all the ways to recover after losing hosts or storage repositories.
|
||||
|
||||
In this guide we'll only see the technical aspect of DR, which is a small part of this vast topic.
|
||||
|
||||
## Best practices
|
||||
|
||||
We strongly encourage you to read some literature on this topic. Basically, you should be able to recover from a major disaster within an appropriate amount of time and minimal acceptable data loss.
|
||||
|
||||
To avoid a potentially very long import process (restoring all your backup VMs), we implemented a streaming feature. [Streaming allows exporting and importing at the same time](https://xen-orchestra.com/blog/vm-streaming-export-in-xenserver/).
|
||||
|
||||
**The goal is to have your DR VMs ready to boot on a dedicated host. This also provides a way to check if you export was successful (if the VM boots).**
|
||||
|
||||

|
||||
|
||||
## Schedule a DR task
|
||||
|
||||
Planning a DR task is very similar to planning a backup or a snapshot. The only difference is that you select a storage destination.
|
||||
|
||||
You DR VMs will be visible "on the other side" as soon the task is done.
|
||||
|
||||
### Retention
|
||||
|
||||
Retention, or **depth**, applies to the VM name. **If you change the VM name for any reason, it won't be rotated anymore.** This way, you can play with your DR VM without the fear of losing it.
|
||||
|
||||
Also, by default, the DR VM will have a "Disaster Recovery" tag.
|
||||
|
||||
:::warning
|
||||
A higher retention number will lead to huge space occupation on your SR.
|
||||
:::
|
||||
|
||||
## Network conflicts
|
||||
|
||||
If you boot a copy of your production VM, be careful: if they share the same static IP, you'll have troubles.
|
||||
|
||||
A good way to avoid this kind of problem is to remove the network interface on the DR VM and check if the export is correctly done.
|
||||
|
||||
:::warning
|
||||
For each DR replicated VM, we add "start" as a blocked operation, meaning even VMs with "Auto power on" enabled will not be started on your DR destination if it reboots.
|
||||
:::
|
||||
@@ -1,144 +0,0 @@
|
||||
# Immutability
|
||||
|
||||
## What You’ll Find on This Page
|
||||
|
||||
This page covers the immutability feature: what it is, why it’s important, and how to set it up, including integration with Amazon S3.
|
||||
|
||||
## What Is Immutability?
|
||||
|
||||
In backup systems, immutability means that once a backup is created, it cannot be altered or deleted for a set period. This safeguards your backups against ransomware attacks, accidental deletion, or data corruption.
|
||||
|
||||
Here’s how it works: You designate a storage repository that Xen Orchestra can write to, but cannot modify during the specified immutability period. Even if an attacker compromises XO, your backups remain untouched. The goal is to ensure that your backup data cannot be deleted, encrypted, or tampered with, unless someone with direct physical or root access to the storage intervenes.
|
||||
|
||||
Immutability can be implemented using external services like AWS S3 Object Lock, but Xen Orchestra also offers a native, on-premises solution that doesn’t rely on third-party infrastructure.
|
||||
|
||||
### Data Protection Modes
|
||||
|
||||
Immutability offers two distinct approaches in data protection, to meet different security and operational needs.
|
||||
|
||||
## Why It Matters
|
||||
|
||||
Immutability guarantees that your backups stay secure and verifiable over time. It acts as a critical defense against ransomware, human mistakes, or intentional tampering. Additionally, it helps organizations comply with legal requirements by ensuring that data remains unaltered for mandatory retention periods. In essence, immutability turns your backup storage into a write-once, read-many (WORM) archive, protecting your data when it matters most.
|
||||
|
||||
## Immutability Approaches
|
||||
|
||||
There are two primary models for achieving immutability:
|
||||
|
||||
### Object Storage
|
||||
|
||||
The first approach leverages **object storage solutions** like Amazon S3, where immutability is enforced using features such as [Object Lock](https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lock.html). In this setup, the storage provider itself manages the retention period. Once enabled, backups created by XO cannot be deleted or modified until the lock expires, providing an extra layer of security.
|
||||
|
||||
### On-prem Immmutability
|
||||
|
||||
The second model is an **on‑premises immutable repository**. It uses a lightweight package, installed on the backup repository. This program monitors and enforces immutability at the file-system level, ensuring that XO itself cannot delete or overwrite existing backups before the end of the retention period.
|
||||
|
||||
## Configuring on-Prem Immutability
|
||||
|
||||
To set up immutability on your local infrastructure, follow these steps:
|
||||
|
||||
### 1. Install the Required Package
|
||||
|
||||
1. Make sure **Node.js** is installed on your backup repository machine
|
||||
2. Install the dedicated XO package globally:
|
||||
|
||||
```bash
|
||||
npm install -g @xen-orchestra/immutable-backups
|
||||
```
|
||||
|
||||
### 2. Configure the Immutability Settings
|
||||
|
||||
Create a configuration file at `/etc/xo-immutable-backups/config.toml`, with the following structure:
|
||||
|
||||
```toml
|
||||
|
||||
liftEvery = "1h"
|
||||
[remotes.remote1]
|
||||
root = "/mnt/ssd/vhdblock/"
|
||||
immutabilityDuration = "7d"
|
||||
```
|
||||
|
||||
#### Mandatory Parameters
|
||||
|
||||
- **`liftEvery`**: Define how often the script will check and lift immutabiltiy (e.g., `1h` for every hour).
|
||||
- Per remote
|
||||
- **`root`**: Specifies the directory where Xen Orchestra stores backups.
|
||||
- **`immutabilityDuration`**: Defines how long files remain protected from deletion (e.g., `7d` for 7 days).
|
||||
|
||||
### 3. Start the Service
|
||||
|
||||
Launch the `xo-immutable-remote` service and check its logs (use `systemd`, for example) to confirm it is running correctly. For persistent operation, configure it as a system service.
|
||||
|
||||
## How It Works
|
||||
|
||||
Once active, any backups written by Xen Orchestra to this repository will be protected for the specified duration. Even if Xen Orchestra is compromised, the immutability configuration remains secure, as it is managed entirely on the backup host.
|
||||
|
||||
### Locking
|
||||
|
||||
The service watches the backup directory tree in real time. When a backup completes, it waits until the final file (the metadata `.json`) has been fully written to disk, then locks all files belonging to that backup run with the Linux `chattr +i` attribute. This prevents any process — including Xen Orchestra — from modifying or deleting them.
|
||||
|
||||
### Lifting
|
||||
|
||||
Protection is released automatically once the `immutabilityDuration` has elapsed. The service periodically (every `liftEvery` interval) scans the backup tree, computes the age of each backup from the datetime encoded in its filename, and removes the immutable attribute from any backup that has expired.
|
||||
|
||||
The expiry reference is the **datetime in the filename**, not the file's modification time. XO periodically rewrites metadata files for cache updates and reconciliation, which would reset `mtime` and indefinitely defer expiry if that were used instead.
|
||||
|
||||
On the first scan after the service starts, all files are checked unconditionally regardless of their current state, to catch anything that may have been missed (e.g. after a crash or restart).
|
||||
|
||||
## Working With Immutable Backups
|
||||
|
||||
When setting up backup jobs in Xen Orchestra, select your configured immutable remote (whether it's an S3 bucket or an on-premises repository). Define your retention and rotation policies as you normally would. Immutability ensures that existing backups cannot be deleted or altered before their protection period expires, while still allowing new backups to be added.
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Only Enable on Stable, Healthy Backup Jobs
|
||||
|
||||
:::warning
|
||||
Immutability should only be enabled on backup jobs that are already running correctly and whose retention policy is fully settled. Nothing will be lost, but there will be a lot of EACCESS/EPERM errors in the backup log.
|
||||
:::
|
||||
|
||||
Immutability and retention are two independent mechanisms, and they can conflict if a backup job is not in a clean state:
|
||||
|
||||
- **Jobs that run more than once per schedule** (accidental duplicates, misconfigured triggers) will accumulate extra backups that XO cannot clean up while they are protected. Those backups count against storage but cannot be removed until their immutability duration expires.
|
||||
- **Backups in an incorrect or partial state** (failed mid-run, inconsistent chain) will be locked in place for the full immutability duration. The normal cleanup scripts cannot remove them, because any attempt to delete or overwrite a protected file raises a permission error (`EPERM`). Those errors are logged, but the files stay.
|
||||
- **Retention and immutability durations must be aligned.** If the immutability duration is longer than the retention window, XO will keep trying — and failing — to delete backups it considers expired. Set `immutabilityDuration` to be at most equal to the retention period, so that files are only released after XO has already rotated them out.
|
||||
- **Do not use Long Term Retention (LTR) with immutability.** LTR may select and remove intermediate backups from within a chain — for example, to keep only one backup per month. If any of those intermediate files are still immutable, the deletion fails with `EPERM`. The backup chain is left in an inconsistent state that XO cannot repair until the immutability duration expires.
|
||||
- **A broken chain root blocks cleanup of the rest of the chain.** In delta backup chains, removing any backup requires starting from the root. If the chain root is in a bad state (missing, corrupted, or partially written) and the remaining files are immutable, the cleanup script cannot remove them either — it encounters `EPERM` on each attempt and leaves the orphaned files in place until they age out naturally.
|
||||
- **Disks are not protected during upload.** The immutable attribute is applied only after all disk images for a given backup run have been fully uploaded. During the upload window, those files can still be modified or deleted. Coupling immutability with XO's at-rest encryption reduces this exposure, since an encrypted file is useless even if tampered with before locking.
|
||||
|
||||
In short: make sure your backup jobs are stable and producing clean results before adding immutability. Applying it to a job that already has problems will lock those problems in place.
|
||||
|
||||
### Define a Clear Immutability Policy
|
||||
|
||||
Align the **lock duration** with your data retention strategy, compliance requirements, and disaster recovery goals. Make sure the policy reflects both legal obligations and operational needs.
|
||||
|
||||
### Secure Your Encryption Keys
|
||||
|
||||
Store encryption keys **separately** from your backup data.
|
||||
|
||||
:::warning
|
||||
Losing encryption keys will render backups **permanently unrecoverable**.
|
||||
:::
|
||||
|
||||
### Maintain Independence from Xen Orchestra
|
||||
|
||||
The immutability enforcement mechanism **must** operate independently of Xen Orchestra. This ensures that even if an attacker compromises XO, they **cannot** delete or alter existing backups.
|
||||
|
||||
### Monitor Storage and Test Recovery
|
||||
|
||||
- Track storage capacity closely, as immutability prevents immediate deletion of older backups.
|
||||
- Plan for additional space to accommodate protected backups over time.
|
||||
- Test recovery procedures regularly, to make sure immutability does not disrupt your ability to restore data when needed.
|
||||
|
||||
## Limitations
|
||||
|
||||
Cloud-based solutions such as S3 Object Lock depend on your provider’s implementation; not all S3‑compatible systems behave identically, so always test before production use.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
the main point for troubleshooiting resource is directly in the package documentation https://github.com/vatesfr/xen-orchestra/blob/master/%40xen-orchestra/immutable-backups/README.md
|
||||
|
||||
## Conclusion
|
||||
|
||||
Immutability adds a critical layer of protection to your backups in Xen Orchestra. Whether you use Amazon S3 or an on-premises repository, the core principle is simple: once a backup is created, you cannot change or delete it until the retention period expires.
|
||||
|
||||
By integrating immutability with strong encryption, proactive monitoring, and regular testing, you ensure that your backup data stays secure, reliable, and recoverable, even in the face of ransomware, human error, or malicious attacks. This approach transforms your backup strategy into a robust defense against data loss and corruption.
|
||||
@@ -1,49 +1,108 @@
|
||||
---
|
||||
sidebar_label: Incremental backups
|
||||
---
|
||||
|
||||
# Incremental Backups
|
||||
|
||||
> **_NOTE:_** Formerly known as Continuous Delta backups
|
||||
|
||||
You can export only the delta (difference) between your current VM disks and a previous snapshot (called here the _reference_). They are called _continuous_ because you'll **never export a full backup** after the first one.
|
||||
Incremental backups export only the blocks that changed since the previous backup, instead of exporting the whole VM every time. After the first complete export (the _key_ backup), every run compares the current VM disks to the previous snapshot (the _reference_) and only transfers the difference (the _delta_) to the backup repository (BR).
|
||||
|
||||
## Introduction
|
||||
|
||||
Full backups can be represented like this:
|
||||
A full backup job exports the complete VM disks at every run, which means large archives and long transfer windows. An incremental backup exports the complete disks once, then only the difference from the previous run:
|
||||
|
||||

|
||||
<Schema label="Same schedule, very different footprint: full backups re-export everything every day, incremental backups export one key backup then small deltas" legend={[["#56c288", "full (key) backup"], ["#6aabf0", "delta"]]} maxWidth="640px">
|
||||
<svg viewBox="0 0 640 230" role="img" aria-label="Two lanes over the same five days: the full backups lane holds five equally large archives, the incremental lane holds one large key backup on day 1 followed by four small deltas">
|
||||
<text x="168" y="24" fill="#7a8699" fontSize="11" textAnchor="middle">day 1</text>
|
||||
<text x="264" y="24" fill="#7a8699" fontSize="11" textAnchor="middle">day 2</text>
|
||||
<text x="360" y="24" fill="#7a8699" fontSize="11" textAnchor="middle">day 3</text>
|
||||
<text x="456" y="24" fill="#7a8699" fontSize="11" textAnchor="middle">day 4</text>
|
||||
<text x="552" y="24" fill="#7a8699" fontSize="11" textAnchor="middle">day 5</text>
|
||||
<text x="16" y="70" fill="#c6d2e1" fontSize="12">Full</text>
|
||||
<text x="16" y="86" fill="#c6d2e1" fontSize="12">backups</text>
|
||||
<rect x="132" y="36" width="72" height="60" rx="6" fill="rgba(255,255,255,0.04)" stroke="#56c288" />
|
||||
<text x="168" y="70" fill="#c6d2e1" fontSize="12" textAnchor="middle">full</text>
|
||||
<rect x="228" y="36" width="72" height="60" rx="6" fill="rgba(255,255,255,0.04)" stroke="#56c288" />
|
||||
<text x="264" y="70" fill="#c6d2e1" fontSize="12" textAnchor="middle">full</text>
|
||||
<rect x="324" y="36" width="72" height="60" rx="6" fill="rgba(255,255,255,0.04)" stroke="#56c288" />
|
||||
<text x="360" y="70" fill="#c6d2e1" fontSize="12" textAnchor="middle">full</text>
|
||||
<rect x="420" y="36" width="72" height="60" rx="6" fill="rgba(255,255,255,0.04)" stroke="#56c288" />
|
||||
<text x="456" y="70" fill="#c6d2e1" fontSize="12" textAnchor="middle">full</text>
|
||||
<rect x="516" y="36" width="72" height="60" rx="6" fill="rgba(255,255,255,0.04)" stroke="#56c288" />
|
||||
<text x="552" y="70" fill="#c6d2e1" fontSize="12" textAnchor="middle">full</text>
|
||||
<text x="16" y="162" fill="#c6d2e1" fontSize="12">Incremental</text>
|
||||
<rect x="132" y="126" width="72" height="60" rx="6" fill="rgba(255,255,255,0.04)" stroke="#56c288" />
|
||||
<text x="168" y="160" fill="#c6d2e1" fontSize="12" textAnchor="middle">full</text>
|
||||
<rect x="242" y="166" width="44" height="20" rx="4" fill="rgba(255,255,255,0.04)" stroke="#6aabf0" />
|
||||
<text x="264" y="180" fill="#c6d2e1" fontSize="9" textAnchor="middle">delta</text>
|
||||
<rect x="338" y="166" width="44" height="20" rx="4" fill="rgba(255,255,255,0.04)" stroke="#6aabf0" />
|
||||
<text x="360" y="180" fill="#c6d2e1" fontSize="9" textAnchor="middle">delta</text>
|
||||
<rect x="434" y="166" width="44" height="20" rx="4" fill="rgba(255,255,255,0.04)" stroke="#6aabf0" />
|
||||
<text x="456" y="180" fill="#c6d2e1" fontSize="9" textAnchor="middle">delta</text>
|
||||
<rect x="530" y="166" width="44" height="20" rx="4" fill="rgba(255,255,255,0.04)" stroke="#6aabf0" />
|
||||
<text x="552" y="180" fill="#c6d2e1" fontSize="9" textAnchor="middle">delta</text>
|
||||
</svg>
|
||||
</Schema>
|
||||
|
||||
It means huge files for each backup. Incremental backups will only export the difference between the previous backup:
|
||||
You can, for example, run the initial key backup during a weekend, then only delta backups every night. This combines the flexibility of snapshots with the safety of full backups:
|
||||
|
||||

|
||||
- deltas are stored on a backup repository (BR), away from the VM storage
|
||||
- they are small and quick to create
|
||||
- restores are simple: XO reads the whole chain and rebuilds the VM automatically
|
||||
|
||||
You can imagine making your first initial key(complete) backup during a weekend, and then only delta backups every night. It combines the flexibility of snapshots and the power of full backups, because:
|
||||
If you want to roll back a VM to a previous state, the cost is only one snapshot on your SR (far less than the [rolling snapshot](../rolling_snapshots.md) mechanism). And even if you lose your whole SR or VM, XOA will restore the VM entirely and automatically, at any backup date.
|
||||
|
||||
- delta are stored somewhere else than the current VM storage
|
||||
- they are small
|
||||
- quick to create
|
||||
- easy to restore
|
||||
|
||||
So, if you want to rollback your VM to a previous state, the cost is only one snapshot on your SR (far less than the [rolling snapshot](rolling_snapshots.md) mechanism).
|
||||
|
||||
Even if you lost your whole SR or VM, XOA will restore your VM entirely and automatically, at any date of backup.
|
||||
|
||||
You can even imagine using this to backup more often! Because deltas will be smaller, and will **always be deltas**.
|
||||
You can even use this to back up more often: deltas stay small, and they will **always be deltas**.
|
||||
|
||||
### Continuous
|
||||
|
||||
They are called continuous because you'll **never export a full backup** after the first one. We'll merge the oldest delta into the full:
|
||||
Incremental backups in XO are called continuous because after the initial key backup, **a full export is never needed again** (unless you configure a [key backup interval](#key-backup-interval)). When the retention is exceeded, instead of exporting a new full, XO merges the oldest delta into the full, directly on the BR:
|
||||
|
||||

|
||||
<Schema label="Rolling merge: when retention is exceeded, the oldest delta is merged into the full on the BR and the chain window slides forward, without ever re-exporting a full" legend={[["#56c288", "full (key) backup"], ["#6aabf0", "delta"], ["#e0a94a", "merge"]]} maxWidth="640px">
|
||||
<svg viewBox="0 0 640 250" role="img" aria-label="Top row: a chain made of a full backup and three deltas exceeds a retention of 3, and an animated arrow merges the oldest delta d1 into the full; bottom row: the resulting chain holds the merged full plus d2 and d3, with a dashed d4 slot showing the next run">
|
||||
<text x="24" y="26" fill="#7a8699" fontSize="11">Retention 3 exceeded: the chain holds 4 restore points</text>
|
||||
<rect x="24" y="36" width="104" height="42" rx="6" fill="rgba(255,255,255,0.04)" stroke="#56c288" />
|
||||
<text x="76" y="61" fill="#c6d2e1" fontSize="12" textAnchor="middle">full</text>
|
||||
<line x1="128" y1="57" x2="144" y2="57" stroke="rgba(255,255,255,0.28)" />
|
||||
<rect x="144" y="36" width="64" height="42" rx="6" fill="rgba(255,255,255,0.04)" stroke="#6aabf0" />
|
||||
<text x="176" y="61" fill="#c6d2e1" fontSize="12" textAnchor="middle">d1</text>
|
||||
<line x1="208" y1="57" x2="224" y2="57" stroke="rgba(255,255,255,0.28)" />
|
||||
<rect x="224" y="36" width="64" height="42" rx="6" fill="rgba(255,255,255,0.04)" stroke="#6aabf0" />
|
||||
<text x="256" y="61" fill="#c6d2e1" fontSize="12" textAnchor="middle">d2</text>
|
||||
<line x1="288" y1="57" x2="304" y2="57" stroke="rgba(255,255,255,0.28)" />
|
||||
<rect x="304" y="36" width="64" height="42" rx="6" fill="rgba(255,255,255,0.04)" stroke="#6aabf0" />
|
||||
<text x="336" y="61" fill="#c6d2e1" fontSize="12" textAnchor="middle">d3</text>
|
||||
<path d="M 176 84 C 176 120, 76 120, 76 94" fill="none" stroke="#e0a94a" strokeWidth="1.5" className="schema-flow" strokeDasharray="5 4" />
|
||||
<polygon points="76,82 70,94 82,94" fill="#e0a94a" />
|
||||
<text x="126" y="136" fill="#e0a94a" fontSize="11" textAnchor="middle">merge d1 into the full</text>
|
||||
<text x="24" y="168" fill="#7a8699" fontSize="11">After the merge: 3 restore points, no new full export</text>
|
||||
<rect x="24" y="178" width="104" height="42" rx="6" fill="rgba(255,255,255,0.04)" stroke="#56c288" />
|
||||
<text x="76" y="203" fill="#c6d2e1" fontSize="11" textAnchor="middle">full + d1</text>
|
||||
<line x1="128" y1="199" x2="144" y2="199" stroke="rgba(255,255,255,0.28)" />
|
||||
<rect x="144" y="178" width="64" height="42" rx="6" fill="rgba(255,255,255,0.04)" stroke="#6aabf0" />
|
||||
<text x="176" y="203" fill="#c6d2e1" fontSize="12" textAnchor="middle">d2</text>
|
||||
<line x1="208" y1="199" x2="224" y2="199" stroke="rgba(255,255,255,0.28)" />
|
||||
<rect x="224" y="178" width="64" height="42" rx="6" fill="rgba(255,255,255,0.04)" stroke="#6aabf0" />
|
||||
<text x="256" y="203" fill="#c6d2e1" fontSize="12" textAnchor="middle">d3</text>
|
||||
<line x1="288" y1="199" x2="304" y2="199" stroke="rgba(255,255,255,0.28)" />
|
||||
<rect x="304" y="178" width="64" height="42" rx="6" fill="rgba(255,255,255,0.02)" stroke="#6aabf0" strokeDasharray="6 5" />
|
||||
<text x="336" y="203" fill="#7a8699" fontSize="12" textAnchor="middle">d4</text>
|
||||
<text x="336" y="238" fill="#7a8699" fontSize="10" textAnchor="middle">next run</text>
|
||||
</svg>
|
||||
</Schema>
|
||||
|
||||
This way we can go "forward" and remove this oldest VHD after the merge:
|
||||
The merge is performed on the files stored on the BR: the hosts are not involved and no data is re-exported from the pool.
|
||||
|
||||

|
||||
## Create an incremental backup {#create-delta-backup}
|
||||
|
||||
## Create Delta backup
|
||||
|
||||
Just go into your "Backup" view, and select Delta Backup. Then, it's the same as a normal backup.
|
||||
In the Backup view, create a new VM backup job and enable the **Delta Backup** mode: this is the incremental mode (the XO 5 interface still uses the historical Delta Backup name for this toggle). Everything else (VM selection, schedules, retention, choice of backup repository) works like a normal backup job.
|
||||
|
||||
## Snapshots
|
||||
|
||||
Unlike other types of backup jobs which delete the associated snapshot when the job is done and it has been exported, delta backups always keep a snapshot of every VM in the backup job, and uses it for the delta. Do not delete these snapshots!
|
||||
Incremental backups rely on a reference snapshot kept on the VM. Unlike other job types, which delete their snapshot once the export is done, an incremental job always keeps the latest snapshot of every VM in the job and uses it as the reference for the next delta. Do not delete these snapshots!
|
||||
|
||||
If keeping the snapshot data on the SR is a problem for you, see [Purge snapshot data (CBT)](#purge-snapshot-data-cbt).
|
||||
|
||||
## Incremental backup initial seed
|
||||
|
||||
@@ -51,10 +110,10 @@ If you don't want to do an initial full directly toward the destination, you can
|
||||
|
||||
Then, only the diff will be sent.
|
||||
|
||||
1. create a incremental backup job to the first remote
|
||||
1. create an incremental backup job to the first backup repository (BR)
|
||||
1. run the backup (full)
|
||||
1. edit the job to target the other remote
|
||||
1. copy files from the first remote to the other one
|
||||
1. edit the job to target the other repository
|
||||
1. copy files from the first repository to the other one
|
||||
1. run the backup (incremental)
|
||||
|
||||
## Key backup interval
|
||||
@@ -73,20 +132,19 @@ Migrating the VDIs of a VM to another SR will trigger a full export at the next
|
||||
|
||||
## NBD-enabled Backups
|
||||
|
||||
You have the option to utilize the NBD network protocol for data transfer instead of the VHD handler generated by the XAPI. NBD-enabled backups generally show improved speed as the load on the Dom0 is reduced.
|
||||
You have the option to use the NBD network protocol for data transfer instead of the VHD export handler exposed by the XAPI. NBD-enabled backups are generally faster, as the load on the Dom0 is reduced.
|
||||
|
||||
NBD must also be enabled on the network used to transfer the backups: select the relevant pool, and navigate to the Network tab to modify the parameter:
|
||||
NBD must first be enabled on the network used to transfer the backups: select the relevant pool, and navigate to the Network tab to modify the parameter. Data is then transferred from the host to XOA over an encrypted (TLS) NBD connection.
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/nbd-connection.png" alt="Enable NBD on the transfer network, in the pool's Network tab" width={700} />
|
||||
|
||||
This will securely transfer encrypted data from the host to the XOA.
|
||||
When creating or editing an incremental (previously known as delta) backup and replication for this pool in the future, you have the option to enable NBD in the Advanced settings, and use multiple connections per VDI.
|
||||
When creating or editing an incremental backup or replication job for this pool, you can then enable **Use NBD to transfer disk** in the Advanced settings, and raise the number of NBD connections per disk to parallelize the transfer:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/nbd-backup-settings.png" alt="The job's Advanced settings: enable NBD and set the number of connections per disk" width={620} />
|
||||
|
||||
After the job is completed, you can verify whether NBD was used for the transfer in the backup log:
|
||||
After the job has run, always verify in the backup log that NBD was actually used for the transfer:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/nbd-backup-log.png" alt="The backup log confirms the run with 'Transfer data using NBD'" width={620} />
|
||||
|
||||
:::warning
|
||||
**Incremental backups of qcow2 disks require NBD.** qcow2 disks are used for VDIs larger than 2 TiB and on storage repositories that store their disks in the qcow2 format.
|
||||
@@ -96,6 +154,35 @@ Enabling **Use NBD to transfer disk** in the job's Advanced settings is not suff
|
||||
|
||||
To learn more about the evolution of this feature across various XO releases, check out our blog posts for versions [5.76](https://xen-orchestra.com/blog/xen-orchestra-5-76/), [5.81](https://xen-orchestra.com/blog/xen-orchestra-5-81/), [5.82](https://xen-orchestra.com/blog/xen-orchestra-5-82/), and [5.86](https://xen-orchestra.com/blog/xen-orchestra-5-86/).
|
||||
|
||||
## Purge snapshot data (CBT) {#purge-snapshot-data-cbt}
|
||||
|
||||
By default, the reference snapshot kept for an incremental backup stores its data on the SR. XO can instead use the Changed Block Tracking (CBT) feature of XCP-ng and XenServer to discard that data: enable **Purge snapshot data when using CBT** in the Advanced settings of the backup job.
|
||||
|
||||
When this setting is enabled:
|
||||
|
||||
- XO automatically enables CBT on all the disks of the VM.
|
||||
- After each successful transfer, the data of the reference snapshot is destroyed: only a small CBT metadata VDI remains on the SR.
|
||||
- On the next run, XO uses this metadata to know exactly which blocks changed, and reads them from the active disk over NBD.
|
||||
|
||||
The benefit: the reference snapshot no longer uses any notable space on the SR, which is especially valuable on thick-provisioned storage where a snapshot can reserve the full size of the disk.
|
||||
|
||||
Requirements and limitations:
|
||||
|
||||
- NBD is required: **Use NBD to transfer disk** must be enabled in the job, and NBD must be [enabled on the network](#nbd-enabled-backups).
|
||||
- It is not compatible with rolling snapshots: the job's snapshot retention must be 0.
|
||||
- Since the purged snapshot only keeps metadata, it is not shown in the UI and can't be used for a rollback or a differential restore.
|
||||
- Reverting to an XO version without CBT support will trigger a full backup on the next run.
|
||||
|
||||
:::warning
|
||||
When using the **purge snapshot data** function, you might occasionally run into an issue where full backups are transferred on each run.
|
||||
|
||||
To prevent this:
|
||||
|
||||
1. Migrate the disk to another storage. This will reset the disk state.
|
||||
2. Disable **purge snapshot data** on the backup.
|
||||
|
||||
:::
|
||||
|
||||
## Understanding large deltas
|
||||
|
||||
Sometimes, you might notice that incremental backups are surprisingly large, almost as big as a full backup. This usually happens because of how block-level backups work: even small changes at the block level are included, even if the files themselves haven't changed much.
|
||||
@@ -106,7 +193,7 @@ Sometimes, you might notice that incremental backups are surprisingly large, alm
|
||||
- **System daemons or temp files**: Background processes that write data regularly.
|
||||
- **Random disk writes**: Applications or databases writing data across the disk.
|
||||
- **Filesystem maintenance**: Some filesystems move blocks internally, for instance during defragmentation.
|
||||
- **Memory pressure and paging**: When a VM is low on RAM, it may write heavily to disk —a process known as [memory paging](https://en.wikipedia.org/wiki/Memory_paging)—, which increases block-level changes.
|
||||
- **Memory pressure and paging**: When a VM is low on RAM, it may write heavily to disk (a process known as [memory paging](https://en.wikipedia.org/wiki/Memory_paging)), which increases block-level changes.
|
||||
|
||||
### Tips to keep deltas small
|
||||
|
||||
@@ -114,18 +201,6 @@ Sometimes, you might notice that incremental backups are surprisingly large, alm
|
||||
- Look out for cron jobs, log rotations, or background tasks that might be active during backup times.
|
||||
- Ensure your VM has enough memory to prevent excessive paging.
|
||||
- Create a separated disk with `[NOBAK]` in its name to handle temporary files. This disk won't be transferred.
|
||||
To know more on excluding disks from backup jobs, check out the [Exclude disks](https://docs.xen-orchestra.com/backups#exclude-disks) section.
|
||||
- For disks larger than **2 TB**, store backups on a remote in **block mode**.
|
||||
- For **qcow2** disks, [enable NBD](#nbd-enabled-backups) — without it, each incremental run falls back to a full backup.
|
||||
|
||||
### Known issues
|
||||
|
||||
:::warning
|
||||
When using the **purge snapshot data** function, you might occasionally run into an issue where full backups are transferred on each run.
|
||||
|
||||
To prevent this:
|
||||
|
||||
1. Migrate the disk to another storage. This will reset the disk state.
|
||||
2. Disable **purge snapshot data** on the backup.
|
||||
|
||||
:::
|
||||
To know more on excluding disks from backup jobs, check out the [Exclude disks](./backups.md#exclude-disks) section.
|
||||
- For disks larger than **2 TB**, store backups on a backup repository in **block mode**.
|
||||
- For **qcow2** disks, [enable NBD](#nbd-enabled-backups): without it, each incremental run falls back to a full backup.
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
---
|
||||
sidebar_label: Incremental replication (CR)
|
||||
---
|
||||
|
||||
# Incremental Replication
|
||||
|
||||
:::note
|
||||
Formerly known as Continuous replication
|
||||
**Incremental replication** is the current name of the job type formerly called **Continuous Replication (CR)**. Both names describe the same thing, and you will still meet the old one: XO 6 labels this mode **Incremental replication**, while the XO 5 interface still labels it **Continuous Replication**, and replicas keep a `Continuous Replication` tag.
|
||||
:::
|
||||
|
||||
This feature is an incremental replication system for your XCP-ng or Xenserver VMs **without any storage vendor lock-in**. You can replicate a VM every _X_ minutes/hours to any storage repository. It could be to a distant XCP-ng or XenServer host or just another local storage target.
|
||||
This feature is an incremental replication system for your XCP-ng or XenServer VMs, **without any storage vendor lock-in**. You can replicate a VM every _X_ minutes or hours to any storage repository (SR): a distant XCP-ng or XenServer host, or simply another local storage target. After the first full transfer, each run only sends the blocks that changed since the previous one.
|
||||
|
||||
This feature covers multiple objectives:
|
||||
|
||||
@@ -18,54 +22,123 @@ This feature covers multiple objectives:
|
||||
|
||||
If you lose your main pool, you can start the copy on the other side, with very recent data.
|
||||
|
||||

|
||||
<Schema label="Incremental replication: only the changed blocks travel to the DR side at each run" legend={[["#56c288", "Production VM"], ["#e0a94a", "Standby replica"], ["#6aabf0", "Xen Orchestra"], ["#8e83fe", "XCP-ng pool"]]} maxWidth="640px">
|
||||
<svg viewBox="0 0 640 270" role="img" aria-label="Xen Orchestra orchestrates an incremental replication job: small deltas of changed blocks travel from the running production VM to a standby replica on the DR SR, whose start operation is blocked">
|
||||
<rect x="250" y="12" width="140" height="34" rx="6" fill="rgba(255,255,255,0.04)" stroke="#6aabf0" strokeWidth="1.5" />
|
||||
<text x="320" y="34" fill="#6aabf0" fontSize="13" textAnchor="middle" fontWeight="600">Xen Orchestra</text>
|
||||
|
||||
<line x1="285" y1="46" x2="150" y2="88" stroke="#6aabf0" strokeWidth="1" strokeDasharray="3 4" opacity="0.7" />
|
||||
<line x1="355" y1="46" x2="490" y2="88" stroke="#6aabf0" strokeWidth="1" strokeDasharray="3 4" opacity="0.7" />
|
||||
|
||||
<rect x="30" y="90" width="240" height="150" rx="8" fill="none" stroke="rgba(255,255,255,0.22)" strokeDasharray="6 5" />
|
||||
<text x="42" y="112" fill="#7a8699" fontSize="11">Production pool</text>
|
||||
|
||||
<rect x="50" y="124" width="200" height="98" rx="6" fill="rgba(255,255,255,0.04)" stroke="#8e83fe" strokeWidth="1.5" />
|
||||
<text x="60" y="143" fill="#8e83fe" fontSize="11">XCP-ng host</text>
|
||||
<rect x="70" y="156" width="160" height="46" rx="5" fill="rgba(255,255,255,0.04)" stroke="#56c288" strokeWidth="1.5" />
|
||||
<text x="150" y="176" fill="#56c288" fontSize="12" textAnchor="middle" fontWeight="600">VM "web01"</text>
|
||||
<text x="150" y="192" fill="#7a8699" fontSize="10" textAnchor="middle">running</text>
|
||||
|
||||
<line x1="270" y1="165" x2="368" y2="165" stroke="#56c288" strokeWidth="1.5" strokeDasharray="5 4" className="schema-flow" />
|
||||
<path d="M368 165 l-8 -4 v8 z" fill="#56c288" />
|
||||
<text x="320" y="146" fill="#c6d2e1" fontSize="10" textAnchor="middle">delta: changed</text>
|
||||
<text x="320" y="158" fill="#c6d2e1" fontSize="10" textAnchor="middle">blocks only</text>
|
||||
|
||||
<g>
|
||||
<rect x="-7" y="-4" width="14" height="8" rx="2" fill="rgba(86,194,136,0.25)" stroke="#56c288" strokeWidth="1" />
|
||||
<animateMotion dur="4s" repeatCount="indefinite" calcMode="linear" path="M278,177 L360,177" keyPoints="0;1" keyTimes="0;1" />
|
||||
<animate attributeName="opacity" dur="4s" repeatCount="indefinite" values="0;1;1;0" keyTimes="0;0.1;0.85;1" />
|
||||
</g>
|
||||
<g>
|
||||
<rect x="-5" y="-3" width="10" height="6" rx="2" fill="rgba(86,194,136,0.25)" stroke="#56c288" strokeWidth="1" />
|
||||
<animateMotion dur="4s" begin="1.6s" repeatCount="indefinite" calcMode="linear" path="M278,177 L360,177" keyPoints="0;1" keyTimes="0;1" />
|
||||
<animate attributeName="opacity" dur="4s" begin="1.6s" repeatCount="indefinite" values="0;1;1;0" keyTimes="0;0.1;0.85;1" />
|
||||
</g>
|
||||
|
||||
<rect x="370" y="90" width="240" height="150" rx="8" fill="none" stroke="rgba(255,255,255,0.22)" strokeDasharray="6 5" />
|
||||
<text x="382" y="112" fill="#7a8699" fontSize="11">DR pool (destination SR)</text>
|
||||
|
||||
<rect x="390" y="124" width="200" height="46" rx="5" fill="rgba(255,255,255,0.04)" stroke="#e0a94a" strokeWidth="1.5" />
|
||||
<text x="490" y="143" fill="#e0a94a" fontSize="11" textAnchor="middle" fontWeight="600">web01 (replica)</text>
|
||||
<text x="490" y="159" fill="#7a8699" fontSize="10" textAnchor="middle">halted, start blocked</text>
|
||||
|
||||
<rect x="390" y="180" width="200" height="42" rx="5" fill="rgba(255,255,255,0.04)" stroke="#e0a94a" strokeWidth="1" opacity="0.6" />
|
||||
<text x="490" y="197" fill="#e0a94a" fontSize="11" textAnchor="middle" opacity="0.7">replication snapshots</text>
|
||||
<text x="490" y="213" fill="#7a8699" fontSize="10" textAnchor="middle" opacity="0.7">one per run (retention)</text>
|
||||
</svg>
|
||||
</Schema>
|
||||
|
||||
:::warning
|
||||
It is normal that you can't boot the copied VM directly: we protect it. The normal workflow is to make a clone and then work on it.
|
||||
It is normal that you can't boot the replicated VM directly: we protect it. The normal workflow is to make a clone and work on the clone.
|
||||
|
||||
This also affects VMs with "Auto Power On" enabled, because of our protections you can ensure these won't start on your Incremental replication destination if you happen to reboot it.
|
||||
This protection also covers VMs with "Auto power on" enabled: replicas will not start on your incremental replication destination if you happen to reboot it.
|
||||
:::
|
||||
|
||||
## Configure it
|
||||
|
||||
As you'll see, it is trivial to configure. Inside the "Backup/new" section, select "Incremental replication".
|
||||
As you'll see, it is trivial to configure. In the "Backup/new" section, select the incremental replication mode: this XO 5 screen still labels the button **Continuous Replication**.
|
||||
|
||||
Then:
|
||||
|
||||
1. Select the VMs you want to protect
|
||||
1. Schedule the replication interval
|
||||
1. Select the destination storage (could be any storage connected to any host!)
|
||||
1. Select the destination storage repository (it can be any SR connected to any host!)
|
||||
|
||||
That's it! Your VMs are protected and replicated as requested.
|
||||
|
||||
To protect the replication, we removed the possibility to boot your copied VM directly, because if you do that, it will break the next delta. The solution is to clone it if you need it (a clone is really quick). You can then do whatever you want with this clone!
|
||||
To protect the replication, we removed the possibility to boot your replicated VM directly: if you start it, it will break the next delta. The solution is to clone it when you need it (a clone is really quick). You can then do whatever you want with this clone!
|
||||
|
||||
## Reverse replication and failback {#reverse-replication}
|
||||
|
||||
Since Xen Orchestra 6.5, incremental replication works in both directions: the replication engine can reuse a snapshot it finds in common between the source and the destination, **even if that snapshot was created by another job, running the other way**. This is what the release notes call bidirectional (or symmetrical) replication.
|
||||
|
||||
There is no special job type for it. To replicate in the reverse direction, simply create a new incremental replication job going the other way:
|
||||
|
||||
1. Select the replica (or the VM running on your DR side) as the source VM
|
||||
1. Select your original production SR as the destination
|
||||
|
||||
On its first run, instead of sending a full copy, the job looks for a common snapshot on both sides (using the content metadata XO writes on every replicated disk) and only transfers the blocks that changed since that snapshot. Then, on the production side:
|
||||
|
||||
- If the original VM is halted (or suspended) and its disks haven't changed since the last replication, the job **updates the original VM in place**: no duplicate VM, your production VM simply catches up with what happened on the DR side.
|
||||
- If the original VM has diverged (or is running), the common snapshot is still used as the delta base, but the job creates a new VM next to it rather than overwriting anything.
|
||||
|
||||
This matters in two situations:
|
||||
|
||||
- **Failing back after a failover**: your production site went down, you force-started the replica and ran on the DR side for a few hours or days. Once production is repaired, a reverse job brings all the changes back as a delta, without transferring entire VMs across the WAN.
|
||||
- **Testing or executing a recovery plan**: you can do a planned switch to the DR site, work there, then switch back, with only deltas moving in each direction.
|
||||
|
||||
Constraints to be aware of:
|
||||
|
||||
- The cross-job snapshot reuse only kicks in when the job has **a single replication target SR** (no additional targets or backup repositories in the same job).
|
||||
- It relies on the content metadata introduced with this feature: both sides need replication snapshots created by a recent XO (the same-VM reuse arrived in XO 6.3, the cross-direction reuse in XO 6.5). Older chains fall back to a full transfer on the first reverse run.
|
||||
- As always with incremental replication, don't delete or alter the replication snapshots: they are the common base that makes the reverse run a delta instead of a full.
|
||||
|
||||
## Manual initial seed
|
||||
|
||||
**If you can't transfer the first backup through your network because it's too large**, you can make a seed locally. In order to do this, follow this procedure (until we make it accessible directly in XO).
|
||||
**If you can't transfer the first backup through your network because it's too large**, you can make a seed locally. To do so, follow this procedure (until we make it accessible directly in XO).
|
||||
|
||||
:::tip
|
||||
This is **only** if you need to make the initial copy without making the whole transfer through your network. Otherwise, **you don't need this**.
|
||||
This is **only** if you need to make the initial copy without pushing the whole transfer through your network. Otherwise, **you don't need this**.
|
||||
:::
|
||||
|
||||
### Job creation
|
||||
|
||||
Create the Incremental Replication backup job, and leave it disabled for now. On the main Backup page, copy the job's `backupJobId` by hovering to the left of the shortened ID and clicking the copy to clipboard button:
|
||||
Create the incremental replication backup job, and leave it disabled for now. On the main Backup page, copy the job's `backupJobId` by hovering to the left of the shortened ID and clicking the copy to clipboard button:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/cr-seed-1.png" alt="Copy the backup job ID from the main Backup page" width={700} />
|
||||
|
||||
Copy it somewhere temporarily. Now we need to also copy the ID of the job schedule, `backupScheduleId`. Do this by hovering over the schedule name in the same panel as before, and clicking the copy to clipboard button. Keep it with the `backupJobId` you copied previously as we will need them all later:
|
||||
Copy it somewhere temporarily. Now we also need to copy the ID of the job schedule, `backupScheduleId`. Do this by hovering over the schedule name in the same panel as before, and clicking the copy to clipboard button. Keep it with the `backupJobId` you copied previously, as we will need them all later:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/cr-seed-2.png" alt="Copy the schedule ID from the same panel" width={700} />
|
||||
|
||||
### Seed creation
|
||||
|
||||
Manually create a snapshot on the VM being backed up, then copy this snapshot UUID, `snapshotUuid` from the snapshot panel of the VM:
|
||||
Manually create a snapshot on the VM being backed up, then copy this snapshot UUID, `snapshotUuid`, from the snapshot panel of the VM:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/cr-seed-3.png" alt="Copy the snapshot UUID from the VM's snapshot panel" width={620} />
|
||||
|
||||
:::warning
|
||||
DO NOT ever delete or alter this snapshot, feel free to rename it to make that clear.
|
||||
DO NOT ever delete or alter this snapshot. Feel free to rename it to make that clear.
|
||||
:::
|
||||
|
||||
### Seed copy
|
||||
@@ -74,59 +147,63 @@ Export this snapshot to a file, then import it on the target SR.
|
||||
|
||||
We need to copy the UUID of this newly created VM as well, `targetVmUuid`:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/cr-seed-4.png" alt="Copy the UUID of the imported VM on the target SR" width={620} />
|
||||
|
||||
:::warning
|
||||
DO not start this VM or it will break the Incremental Replication job! You can rename this VM to more easily remember this.
|
||||
DO NOT start this VM or it will break the incremental replication job! You can rename this VM to more easily remember this.
|
||||
:::
|
||||
|
||||
### Set up metadata
|
||||
|
||||
The XOA backup system requires metadata to correctly associate the source snapshot and the target VM to the backup job. We're going to use the `xo-cr-seed` utility to help us set them up.
|
||||
The XOA backup system requires metadata to correctly associate the source snapshot and the target VM with the backup job. We're going to use the `xo-cr-seed` utility to set them up.
|
||||
|
||||
First install the tool (all the following is done from the XOA VM CLI):
|
||||
|
||||
```sh
|
||||
<Terminal shell title="xoa — install the seed utility">{`
|
||||
sudo npm i -g --unsafe-perm @xen-orchestra/cr-seed-cli
|
||||
```
|
||||
`}</Terminal>
|
||||
|
||||
Here is an example of how the utility expects the UUIDs and info passed to it:
|
||||
Here is how the utility expects the UUIDs and info passed to it:
|
||||
|
||||
```console
|
||||
$ xo-cr-seed
|
||||
<Terminal title="xoa — xo-cr-seed usage">{`
|
||||
xo-cr-seed
|
||||
Usage: xo-cr-seed <source XAPI URL> <source snapshot UUID> <target XAPI URL> <target VM UUID> <backup job id> <backup schedule id>
|
||||
|
||||
xo-cr-seed v0.2.0
|
||||
```
|
||||
`}</Terminal>
|
||||
|
||||
Putting it altogether and putting our values and UUID's into the command, it will look like this (it is a long command):
|
||||
Putting it all together with our values and UUIDs, the command will look like this (it is a long command):
|
||||
|
||||
```console
|
||||
$ xo-cr-seed https://root:[email protected] 4a21c1cd-e8bd-4466-910a-f7524ecc07b1 https://root:[email protected] 5aaf86ca-ae06-4a4e-b6e1-d04f0609e64d 90d11a94-a88f-4a84-b7c1-ed207d3de2f9 369a26f0-da77-41ab-a998-fa6b02c69b9a
|
||||
```
|
||||
<Terminal shell title="xoa — seed the replication job">{`
|
||||
xo-cr-seed https://root:[email protected] 4a21c1cd-e8bd-4466-910a-f7524ecc07b1 https://root:[email protected] 5aaf86ca-ae06-4a4e-b6e1-d04f0609e64d 90d11a94-a88f-4a84-b7c1-ed207d3de2f9 369a26f0-da77-41ab-a998-fa6b02c69b9a
|
||||
`}</Terminal>
|
||||
|
||||
:::warning
|
||||
If the username or the password for your XCP-ng/XenServer hosts contains special characters, they must use [percent encoding](https://en.wikipedia.org/wiki/Percent-encoding).
|
||||
If the username or the password of your XCP-ng/XenServer hosts contains special characters, they must use [percent encoding](https://en.wikipedia.org/wiki/Percent-encoding).
|
||||
|
||||
An easy way to do this with Node in command line:
|
||||
An easy way to do this with Node on the command line:
|
||||
|
||||
```console
|
||||
$ node -p 'encodeURIComponent(process.argv[1])' -- 'password with special chars :#@'
|
||||
<Terminal title="xoa — percent-encode a password">{`
|
||||
node -p 'encodeURIComponent(process.argv[1])' -- 'password with special chars :#@'
|
||||
password%20with%20special%20chars%20%3A%23%40
|
||||
```
|
||||
`}</Terminal>
|
||||
|
||||
:::
|
||||
|
||||
### Finished
|
||||
|
||||
Your backup job should now be working correctly! Manually run the job the first time to check if everything is OK. Then, enable the job. **Now only the deltas are sent, your initial seed saved you a LOT of time if you have a slow network.**
|
||||
Your backup job should now be working correctly! Manually run the job the first time to check that everything is OK, then enable it. **From now on, only the deltas are sent: your initial seed saved you a LOT of time if you have a slow network.**
|
||||
|
||||
### Failover process
|
||||
|
||||
In the situation where you need to failover to your destination host, you simply need to start all your VMs on the destination host.
|
||||
In the situation where you need to failover to your destination host, you simply need to start your VMs on the destination side.
|
||||
|
||||
:::tip
|
||||
If you want to start a VM on your destination host without breaking the CR jobs on the other side, you will need to make a copy of the VM and start the copy. Otherwise, you will be asked if you would like to force start the VMs.
|
||||
If you want to start a VM on your destination host without breaking the incremental replication jobs on the other side, make a copy of the VM and start the copy. Otherwise, you will be asked if you would like to force start the VM.
|
||||
:::
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/force-start.jpg" alt="The force start confirmation, shown when starting a protected replica" width={480} />
|
||||
|
||||
Force starting the most recent replica gets your services back quickly, but it consumes that replica: the job on the (now dead) production side would have to send a new full copy anyway.
|
||||
|
||||
Once your production site is back online, use [reverse replication](#reverse-replication) to fail back: create an incremental replication job from the DR side to your production SR. Everything that happened while you were running on the DR site comes back as a delta, and if your original VM is still there and untouched, it is updated in place. When production is up to date, shut down the DR side, restart the original job, and you are back to your normal replication flow.
|
||||
|
||||
@@ -1,431 +0,0 @@
|
||||
# Installation
|
||||
|
||||
:::tip
|
||||
If you want to deploy an XOA in an airgapped infrastructure, refer to the [dedicated documentation](airgap.md).
|
||||
:::
|
||||
|
||||
## XOA
|
||||
|
||||
Log in to your account and use the deploy form [available on this page](https://vates.tech/deploy/).
|
||||
|
||||
:::tip
|
||||
All the deploy code is within your browser, nothing is sent to our server!
|
||||
:::
|
||||
|
||||

|
||||
|
||||
### First Login
|
||||
|
||||
Once you have started the VM, you can access the web UI by putting the IP you configured during deployment into your web browser. If you did not configure an IP or are unsure, try one of the following methods to find it:
|
||||
|
||||
- Run `xe vm-list params=name-label,networks | grep -A 1 XOA` on your host
|
||||
- Check your router's DHCP leases for an `xoa` lease
|
||||
|
||||
:::tip
|
||||
|
||||
- Default Web UI credentials are `[email protected]` / `admin`
|
||||
- Default console/SSH credentials are not set, you need to set them [as described here](troubleshooting.md#set-or-recover-xoa-vm-password).
|
||||
:::
|
||||
|
||||
### Registration
|
||||
|
||||
**The first thing** you need to do with your XOA is register. [Read the documentation on the page dedicated to the updater/register interface](updater.md#register).
|
||||
|
||||
:::tip
|
||||
We don't generate virtual appliances every month (unlike XO code itself). It's very likely you'll need to update Xen Orchestra after the initial deploy. You need to register to do so!
|
||||
:::
|
||||
|
||||
### Trial
|
||||
|
||||
In your current Free XOA, register it in the "Updates" view in the main menu:
|
||||
|
||||

|
||||
|
||||
**To register your appliance, please use your email/password from your previous registration on xen-orchestra.com**:
|
||||
|
||||

|
||||
|
||||
Then you can click on "Start Trial", the green button:
|
||||
|
||||

|
||||
|
||||
Remember to click on the Upgrade button after requesting a trial - this will download the **Premium Edition** for 30 days!
|
||||
|
||||

|
||||
|
||||
### Trial availability
|
||||
|
||||
In this update view, you can see when your trial will end:
|
||||
|
||||

|
||||
|
||||
:::tip
|
||||
Don't worry! XOA will still work after the trial: you'll be forced to downgrade to Free version, but you won't lose any configuration data.
|
||||
:::
|
||||
|
||||
### More on XOA
|
||||
|
||||
You can get all the info you want on XOA in its [dedicated section](xoa.md).
|
||||
|
||||

|
||||
|
||||
## From the sources
|
||||
|
||||
:::warning
|
||||
We don't provide pro support for this installation method. We cannot guarantee anything if it's used in production. Use it at your own risk!
|
||||
:::
|
||||
|
||||
:::tip
|
||||
Please consider using XOA before trying to play with the manual build, which can be difficult if you are not used to NodeJS and NPM.
|
||||
:::
|
||||
|
||||
This installation has been validated against a fresh Debian 12 (Bookworm) x64 install. It should be nearly the same on other dpkg systems. For RPM based OS's, it should be close, as most of our dependencies come from NPM and not the OS itself.
|
||||
|
||||
As you may have seen in other parts of the documentation, XO is composed of two parts: [xo-server](https://github.com/vatesfr/xen-orchestra/tree/master/packages/xo-server/) and [xo-web](https://github.com/vatesfr/xen-orchestra/tree/master/packages/xo-web/). They can be installed separately, even on different machines, but for the sake of simplicity we will set them up together.
|
||||
|
||||
### Packages and Prerequisites
|
||||
|
||||
#### NodeJS
|
||||
|
||||
XO requires [Node.js](https://en.wikipedia.org/wiki/Node.js), **please always use [latest LTS](https://github.com/nodejs/release?tab=readme-ov-file#release-schedule)**.
|
||||
|
||||
We'll consider at this point that you've got a working node on your box. E.g:
|
||||
|
||||
```console
|
||||
$ node -v
|
||||
v20.14.0
|
||||
```
|
||||
|
||||
If not, see [this page](https://nodejs.org/en/download/package-manager/) for instructions on how to install Node.
|
||||
|
||||
#### Yarn
|
||||
|
||||
Yarn is a package manager that offers more guarantees than npm.
|
||||
|
||||
See [this page](https://yarnpkg.com/en/docs/install#debian-stable) for instructions on how to install Yarn.
|
||||
|
||||
#### Packages
|
||||
|
||||
XO needs the following packages to be installed. Redis is used as a database by XO.
|
||||
|
||||
For example, on Debian/Ubuntu:
|
||||
|
||||
```sh
|
||||
apt-get install build-essential redis-server libpng-dev git python3-minimal libvhdi-utils lvm2 cifs-utils nfs-common ntfs-3g openssl libfuse2
|
||||
```
|
||||
|
||||
On Fedora/CentOS like:
|
||||
|
||||
```sh
|
||||
dnf install redis libpng-devel git lvm2 cifs-utils make automake gcc gcc-c++ nfs-utils ntfs-3g openssl
|
||||
```
|
||||
|
||||
Starting with release 10 of CentOS, AlmaLinux, Rocky Linux (June 2025), Redis is no longer offered as a package.
|
||||
Valkey is a drop-in replacement key-value database.
|
||||
These distributions also include a package to ensure compatibility between Valkey and Redis called valkey-compat-redis.
|
||||
valkey-compat-redis is found in the `devel` repository in DNF.
|
||||
|
||||
Additionally, the `ntfs-3g` program has been moved to the EPEL repository.
|
||||
|
||||
```sh
|
||||
dnf install epel-release
|
||||
|
||||
dnf config-manager --enable devel
|
||||
|
||||
dnf install valkey valkey-compat-redis libpng-devel git lvm2 cifs-utils make automake gcc gcc-c++ nfs-utils ntfs-3g openssl
|
||||
```
|
||||
|
||||
### Make sure Redis is running
|
||||
|
||||
Start the service:
|
||||
|
||||
```sh
|
||||
systemctl restart redis.service
|
||||
```
|
||||
|
||||
or if you installed valkey
|
||||
|
||||
```sh
|
||||
systemctl restart valkey.service
|
||||
```
|
||||
|
||||
Ensure it's working:
|
||||
|
||||
```console
|
||||
$ redis-cli ping
|
||||
PONG
|
||||
```
|
||||
|
||||
If you installed the valkey-compat-redis package, then `redis-cli` will be installed as a compatibility script.
|
||||
|
||||
### Fetching the Code
|
||||
|
||||
You need to use the `git` source code manager to fetch the code. Ideally, you should run XO as a non-root user, and if you choose to, you need to set up `sudo` to be able to mount NFS remotes. As your chosen non-root (or root) user, run the following:
|
||||
|
||||
```sh
|
||||
git clone -b master https://github.com/vatesfr/xen-orchestra
|
||||
```
|
||||
|
||||
:::tip
|
||||
`xo-server` and `xo-web` have been migrated to the [xen-orchestra](https://github.com/vatesfr/xen-orchestra) mono-repository - so you only need the single clone command above
|
||||
:::
|
||||
|
||||
### Installing dependencies
|
||||
|
||||
Now that you have the code, you can enter the `xen-orchestra` directory and use `yarn` to install other dependencies. Then finally build it using `yarn build`. Be sure to run `yarn` commands as the same user you will be using to run Xen Orchestra:
|
||||
|
||||
```sh
|
||||
cd xen-orchestra
|
||||
yarn
|
||||
yarn build
|
||||
```
|
||||
|
||||
Now you have to create a config file for `xo-server`:
|
||||
|
||||
```sh
|
||||
cd packages/xo-server
|
||||
mkdir -p ~/.config/xo-server
|
||||
cp sample.config.toml ~/.config/xo-server/config.toml
|
||||
```
|
||||
|
||||
> Note: If you're installing `xo-server` as a global service, you may want to copy the file to `/etc/xo-server/config.toml` instead.
|
||||
|
||||
In this config file, you can change default ports (80 and 443) for xo-server. If you are running the server as a non-root user, you will need to set the port to 1024 or higher.
|
||||
|
||||
You can try to start xo-server to see if it works. You should have something like this:
|
||||
|
||||
```console
|
||||
$ yarn start
|
||||
WebServer listening on localhost:80
|
||||
[INFO] Default user: "[email protected]" with password "admin"
|
||||
```
|
||||
|
||||
### Running XO
|
||||
|
||||
The only part you need to launch is xo-server, which is quite easy to do. From the `xen-orchestra/packages/xo-server` directory, run the following:
|
||||
|
||||
```sh
|
||||
yarn start
|
||||
```
|
||||
|
||||
That's it! Use your browser to visit the xo-server IP address, and it works! :)
|
||||
|
||||
### Updating
|
||||
|
||||
If you would like to update your current version, enter your `xen-orchestra` directory and run the following:
|
||||
|
||||
```sh
|
||||
# This will clear any changes you made in the repository!!
|
||||
git checkout .
|
||||
|
||||
git pull --ff-only
|
||||
yarn
|
||||
yarn build
|
||||
```
|
||||
|
||||
Then restart Xen Orchestra if it was running.
|
||||
|
||||
### Always Running
|
||||
|
||||
#### Using forever
|
||||
|
||||
- You can use [forever](https://github.com/nodejitsu/forever) to have the process always running:
|
||||
|
||||
```sh
|
||||
yarn global add forever
|
||||
|
||||
# Run the below as the user owning XO
|
||||
forever start dist/cli.mjs
|
||||
```
|
||||
|
||||
- Or you can use [forever-service](https://github.com/zapty/forever-service) to install XO as a system service, so it starts automatically at boot. Run the following as root:
|
||||
|
||||
```sh
|
||||
yarn global add forever
|
||||
yarn global add forever-service
|
||||
|
||||
# Be sure to edit the path below to where your install is located!
|
||||
cd /home/username/xen-orchestra/packages/xo-server/
|
||||
|
||||
# Change the username below to the user owning XO
|
||||
forever-service install orchestra -r username -s dist/cli.mjs
|
||||
```
|
||||
|
||||
The forever-service command above must be run in the xo-server bin directory. Now you can manage the service, and it will start on boot with the machine:
|
||||
|
||||
```sh
|
||||
service orchestra start
|
||||
service orchestra status
|
||||
```
|
||||
|
||||
If you need to delete the service:
|
||||
|
||||
```sh
|
||||
forever-service delete orchestra
|
||||
```
|
||||
|
||||
#### Systemd service
|
||||
|
||||
You can also use systemd to enable the service instead.
|
||||
|
||||
_The following example is based on a Ubuntu 24.04 installation_
|
||||
|
||||
Create the following file `/etc/systemd/system/xo-server.service` containing the following inside:
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=XO Server
|
||||
After=network-online.target
|
||||
|
||||
[Service]
|
||||
Environment="DEBUG=xo:main"
|
||||
Restart=always
|
||||
SyslogIdentifier=xo-server
|
||||
|
||||
# Be sure to edit the path below to where your Node and your xo-server install is located!
|
||||
ExecStart=/usr/bin/node /home/username/xen-orchestra/packages/xo-server/dist/cli.mjs
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
Reload the daemon and enable the service:
|
||||
|
||||
```sh
|
||||
systemctl daemon-reload
|
||||
systemctl enable --now xo-server
|
||||
```
|
||||
|
||||
You can then use standard systemd commands to start/stop/check status e.g.
|
||||
|
||||
```sh
|
||||
systemctl status xo-server
|
||||
```
|
||||
|
||||
> **Security:** `xo-server` will be run as `root`, make sure your files are not editable by other users or it may be used as an attack vector.
|
||||
|
||||
### Banner and warnings
|
||||
|
||||
You probably noticed a banner and some warnings when using XO "from the sources": no pro support, no QA performed, etc. But why? We don't sell any licenses, just the turnkey appliance with QA/support and extra services. And we don't sell that to individuals, only companies.
|
||||
|
||||
However, there's no way to discriminate if this "from the sources" version is used by a company or an individual. Remember that we have no control where or when XO from the sources is running on premise, nor how many people use it.
|
||||
|
||||
That's why we have to notify these companies about XOA: it's better to run XO with XOA in production. So as a home user, just ignore it. Also, removing this with your own scripts that you distribute might hurt XO and the [XCP-ng project](https://xcp-ng.org). Indeed, since XOA is our main revenue stream for both projects, this banner is important to get the attention of companies potentially interested by that, driving revenue helping us to develop our fully Open Source products further/faster. We are not Facebook or Google with their giant ad revenue, and each dollar/euro earned by selling support is **directly and 100% invested into XO or XCP-ng**.
|
||||
|
||||
As a home user, you can support the XO project in a lot of ways: spreading the word, giving your feedback, finding bugs and ultimately contribute to the code. Keeping this banner is also a way to support us!
|
||||
|
||||
:::tip
|
||||
Exceptional individual contributors are awarded with a free XOA Premium subscription. If you think you deserve it, feel free to contact us!
|
||||
:::
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
If you have problems during the building phase, follow these steps in your `xen-orchestra` directory:
|
||||
|
||||
1. `rm -rf node_modules`
|
||||
1. `yarn`
|
||||
1. `yarn build`
|
||||
|
||||
### FreeBSD
|
||||
|
||||
> This process has been contributed by the community, it is **not officially supported**.
|
||||
|
||||
If you are using FreeBSD, you need to install these packages:
|
||||
|
||||
```sh
|
||||
pkg install gmake redis python git npm node autoconf
|
||||
```
|
||||
|
||||
You can update `npm` itself right now with a `npm update -g`
|
||||
|
||||
A few of the npm packages look for system binaries as part of their installation, and if missing will try to build it themselves. Installing these will save some time and allow for easier upgrades later:
|
||||
|
||||
```sh
|
||||
pkg install jpeg-turbo optipng gifsicle
|
||||
```
|
||||
|
||||
Because FreeBSD is shipped with CLANG and not GCC, you need to do this:
|
||||
|
||||
```sh
|
||||
ln -s /usr/bin/clang++ /usr/local/bin/g++
|
||||
```
|
||||
|
||||
To enable redis on boot, add this in your `/etc/rc.conf`:
|
||||
|
||||
```sh
|
||||
redis_enable="YES"
|
||||
```
|
||||
|
||||
Don't forget to start redis if you don't reboot now:
|
||||
|
||||
```sh
|
||||
service redis start
|
||||
```
|
||||
|
||||
### OpenBSD
|
||||
|
||||
> This process has been contributed by the community, it is **not officially supported**.
|
||||
|
||||
If you are using OpenBSD, you need to install these packages:
|
||||
|
||||
```sh
|
||||
pkg_add gmake redis python--%2.7 git node autoconf yarn
|
||||
```
|
||||
|
||||
A few of the npm packages look for system binaries as part of their installation, and if missing will try to build it themselves. Installing these will save some time and allow for easier upgrades later:
|
||||
|
||||
```sh
|
||||
pkg_add jpeg optipng gifsicle
|
||||
```
|
||||
|
||||
Because OpenBSD is shipped with CLANG and not GCC, you need to do this:
|
||||
|
||||
```sh
|
||||
export CC=/usr/bin/clang
|
||||
export CXX=/usr/bin/clang++
|
||||
```
|
||||
|
||||
You will need to update the number of allowed open files and make `node` available to `npm` :
|
||||
|
||||
```sh
|
||||
ulimit -n 10240
|
||||
ln -s /usr/local/bin/node /tmp/node
|
||||
```
|
||||
|
||||
If `yarn` cannot find Python, give it a hand :
|
||||
|
||||
```sh
|
||||
PYTHON=/usr/local/bin/python2 yarn
|
||||
```
|
||||
|
||||
Enable redis on boot with:
|
||||
|
||||
```sh
|
||||
rcctl enable redis
|
||||
```
|
||||
|
||||
Don't forget to start redis if you don't reboot now:
|
||||
|
||||
```sh
|
||||
rcctl start redis
|
||||
```
|
||||
|
||||
### sudo
|
||||
|
||||
If you are running `xo-server` as a non-root user, you need to use `sudo` to be able to mount NFS remotes. You can do this by editing the `xo-server` configuration file and setting `useSudo = true`. It's near the end of the file:
|
||||
|
||||
```toml
|
||||
useSudo = true
|
||||
```
|
||||
|
||||
You need to configure `sudo` to allow the user of your choice to run mount/umount commands without asking for a password.
|
||||
|
||||
:::tip
|
||||
Depending on your operating system or `sudo` version, the location of this configuration may change.
|
||||
|
||||
Regardless, you can use:
|
||||
|
||||
```
|
||||
username ALL=(root)NOPASSWD: /bin/mount, /bin/umount, /bin/findmnt
|
||||
```
|
||||
:::
|
||||
@@ -1,28 +0,0 @@
|
||||
---
|
||||
slug: backup
|
||||
---
|
||||
|
||||
# Introduction to backups
|
||||
|
||||
Xen Orchestra is currently the most capable and advanced solution to backup your VMs/infrastructure. There's many ways and solutions to achieve what you need, take time to read them all. Take a look on the [concept section](backups.md) to learn more about how it works.
|
||||
|
||||
Alternatively, here is a video recap on different backup capabilities:
|
||||
|
||||
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/FfUqIwT8KzI?si=kTvxIFhPjv-8Iwri" title="Administer and backup your VM infrastructure the easiest way" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
|
||||
|
||||
- [Rolling Snapshots](rolling_snapshots.md)
|
||||
- [Full Backups](full_backups.md)
|
||||
- [Incremental Backups](incremental_backups.md)
|
||||
- [Full Replication](full_replication.md)
|
||||
- [Metadata Backups](metadata_backup.md)
|
||||
- [Incremental Replication](incremental_replication.md)
|
||||
- [File Level Restore](backups.md#file-level-restore)
|
||||
- [Mirror backup](mirror_backup.md)
|
||||
|
||||
:::tip
|
||||
Don't forget to take a look at the [backup troubleshooting](backup_troubleshooting.md) section. You can also take a look at the [backup reports](backup_reports.md) section for configuring notifications.
|
||||
:::
|
||||
|
||||
:::tip
|
||||
There is also a way to automatically select the VMs to backup: **[smart backup](backups.md#smart-backup)**.
|
||||
:::
|
||||
@@ -1,31 +0,0 @@
|
||||
# License management
|
||||
|
||||
This section will cover the license management system for commercial editions of our products.
|
||||
|
||||
## Activate a Xen Orchestra license
|
||||
|
||||
1. After the [purchase](../xo6/purchase.md), all your available licenses will be visible in the license section of your appliance.
|
||||
|
||||
2. All the licenses available and not bind already will be displayed here with a green `activate license` button
|
||||
|
||||

|
||||
|
||||
3. By clicking on the activate license option, you will be required to confirm your choice.
|
||||
|
||||

|
||||
|
||||
## Rebind XO license
|
||||
|
||||
:::warning
|
||||
A license can only be bind to a single appliance at the same time, rebind your license will unbind the license from any other appliance.
|
||||
:::
|
||||
|
||||
To rebind your Xen Orchestra appliance, you simply need to connect on the **appliance on which you want to bind the license** and click on the rebind option (Move license to this XOA button) in the license section
|
||||
|
||||

|
||||
|
||||
You will then have a confirmation screen
|
||||
|
||||

|
||||
|
||||
Once it's done, you simply need to proceed to an upgrade on your freshly binded appliance to download the correct edition packages.
|
||||
+229
-42
@@ -1,18 +1,20 @@
|
||||
# Load balancing
|
||||
|
||||
<InterfaceNote />
|
||||
|
||||
## Basic notions
|
||||
|
||||
A generic definition (from Wikipedia), is:
|
||||
A generic definition, from Wikipedia:
|
||||
|
||||
> In computing, load balancing distributes workloads across multiple computing resources, such as computers, a computer cluster, network links, central processing units or disk drives.
|
||||
|
||||
In the case of virtualization, you have multiple physical hosts, which run your virtual machines (VMs). The goal here is to **distribute the VM load** in the best way possible across your servers.
|
||||
|
||||
:::tip
|
||||
You may have heard about VMWare DRS (Distributed Resource Scheduler). That's the same principle here, but for XCP-ng.
|
||||
You may have heard about VMware DRS (Distributed Resource Scheduler). That's the same principle here, but for XCP-ng.
|
||||
:::
|
||||
|
||||
The first goal is to adapt your VM placement in real time —without service interruption— depending of the load. Since Xen Orchestra is connected to [multiple pools](./architecture#xo-server-server) and XCP-ng supports live storage motion, we can perform load balancing on a **whole XCP-ng infrastructure**, even between remote datacenters.
|
||||
The first goal is to adapt your VM placement in real time, without service interruption, depending on the load. Since Xen Orchestra is connected to [multiple pools](../architecture.md#xo-server) and XCP-ng supports live storage motion, we can perform load balancing on a **whole XCP-ng infrastructure**, even between remote datacenters.
|
||||
|
||||
:::tip
|
||||
A load balancing policy is called a **plan**.
|
||||
@@ -20,19 +22,176 @@ A load balancing policy is called a **plan**.
|
||||
|
||||
Here's a simple example, with 2 hosts running 6 VMs:
|
||||
|
||||

|
||||
<Schema label="A quiet cluster: two hosts, six VMs" legend={[["#56c288", "VM"]]} maxWidth="640px">
|
||||
<svg viewBox="0 0 640 220" role="img" aria-label="Two hosts each running three healthy VMs, both using 5 percent of their CPUs">
|
||||
<g fill="none" stroke="rgba(255,255,255,0.22)" strokeDasharray="6 5">
|
||||
<rect x="25" y="40" width="280" height="150" rx="10"/>
|
||||
<rect x="335" y="40" width="280" height="150" rx="10"/>
|
||||
</g>
|
||||
<g fontSize="12.5" fill="#7a8699">
|
||||
<text x="41" y="64">Host 1</text>
|
||||
<text x="351" y="64">Host 2</text>
|
||||
</g>
|
||||
<g fontSize="11" textAnchor="end" fill="#56c288">
|
||||
<text x="289" y="64">CPU 5%</text>
|
||||
<text x="599" y="64">CPU 5%</text>
|
||||
</g>
|
||||
<g fill="rgba(86,194,136,0.14)" stroke="#56c288">
|
||||
<rect x="45" y="94" width="64" height="44" rx="5"/>
|
||||
<rect x="129" y="94" width="64" height="44" rx="5"/>
|
||||
<rect x="213" y="94" width="64" height="44" rx="5"/>
|
||||
<rect x="355" y="94" width="64" height="44" rx="5"/>
|
||||
<rect x="439" y="94" width="64" height="44" rx="5"/>
|
||||
<rect x="523" y="94" width="64" height="44" rx="5"/>
|
||||
</g>
|
||||
<g fontSize="11" fill="#c6d2e1" textAnchor="middle">
|
||||
<text x="77" y="120">VM 1</text>
|
||||
<text x="161" y="120">VM 2</text>
|
||||
<text x="245" y="120">VM 3</text>
|
||||
<text x="387" y="120">VM 4</text>
|
||||
<text x="471" y="120">VM 5</text>
|
||||
<text x="555" y="120">VM 6</text>
|
||||
</g>
|
||||
</svg>
|
||||
</Schema>
|
||||
|
||||
Let's say both hosts are using only 5% of all their CPUs. Suddenly, one of your VM starts to have a very high CPU load (in yellow): performance of other VMs on this same host could be impacted negatively (in pink):
|
||||
Let's say both hosts are using only 5% of all their CPUs. Suddenly, one of your VMs starts to have a very high CPU load (in red): the other VMs on this same host end up starved for CPU (in amber):
|
||||
|
||||

|
||||
<Schema label="VM 5 heats up, its neighbors starve" legend={[["#ef6a5f", "CPU-hungry"], ["#e0a94a", "starved"]]} maxWidth="640px">
|
||||
<svg viewBox="0 0 640 220" role="img" aria-label="VM 5 on Host 2 spikes to a very high CPU load, starving VM 4 and VM 6 on the same host, while Host 1 stays at 5 percent">
|
||||
<g fill="none" stroke="rgba(255,255,255,0.22)" strokeDasharray="6 5">
|
||||
<rect x="25" y="40" width="280" height="150" rx="10"/>
|
||||
<rect x="335" y="40" width="280" height="150" rx="10"/>
|
||||
</g>
|
||||
<g fontSize="12.5" fill="#7a8699">
|
||||
<text x="41" y="64">Host 1</text>
|
||||
<text x="351" y="64">Host 2</text>
|
||||
</g>
|
||||
<text x="289" y="64" fontSize="11" textAnchor="end" fill="#56c288">CPU 5%</text>
|
||||
<text x="599" y="64" fontSize="11" textAnchor="end" fill="#ef6a5f">CPU 95%</text>
|
||||
<g fill="rgba(86,194,136,0.14)" stroke="#56c288">
|
||||
<rect x="45" y="94" width="64" height="44" rx="5"/>
|
||||
<rect x="129" y="94" width="64" height="44" rx="5"/>
|
||||
<rect x="213" y="94" width="64" height="44" rx="5"/>
|
||||
</g>
|
||||
<g fill="rgba(224,169,74,0.12)" stroke="#e0a94a" strokeOpacity="0.85">
|
||||
<rect x="355" y="94" width="64" height="44" rx="5"/>
|
||||
<rect x="523" y="94" width="64" height="44" rx="5"/>
|
||||
</g>
|
||||
<g className="schema-glow">
|
||||
<rect x="439" y="94" width="64" height="44" rx="5" fill="rgba(239,106,95,0.2)" stroke="#ef6a5f" strokeWidth="1.6"/>
|
||||
</g>
|
||||
<g fontSize="11" fill="#c6d2e1" textAnchor="middle">
|
||||
<text x="77" y="120">VM 1</text>
|
||||
<text x="161" y="120">VM 2</text>
|
||||
<text x="245" y="120">VM 3</text>
|
||||
<text x="387" y="116">VM 4</text>
|
||||
<text x="471" y="116">VM 5</text>
|
||||
<text x="555" y="116">VM 6</text>
|
||||
</g>
|
||||
<text x="471" y="131" fontSize="9" fill="#ef6a5f" textAnchor="middle">100% CPU</text>
|
||||
<g fontSize="9" fill="#e0a94a" textAnchor="middle">
|
||||
<text x="387" y="131">waiting…</text>
|
||||
<text x="555" y="131">waiting…</text>
|
||||
</g>
|
||||
</svg>
|
||||
</Schema>
|
||||
|
||||
`Host 1` still using 5% of its CPUs, but `Host 2` is now at 95%.
|
||||
`Host 1` is still using 5% of its CPUs, but `Host 2` is now at 95%.
|
||||
|
||||
We can detect that and now move others VM to the other host, like this:
|
||||
The load balancer detects it, and moves the starved VMs to the other host:
|
||||
|
||||

|
||||
<Schema label="The plan reacts: starved VMs move out and turn healthy, the busy VM gets the host" legend={[["#56c288", "healthy"], ["#e0a94a", "starved"], ["#ef6a5f", "CPU-hungry"]]} maxWidth="640px">
|
||||
<svg viewBox="0 0 640 250" role="img" aria-label="VM 4 and VM 6 are live migrated from Host 2 to Host 1, becoming healthy again, leaving the CPU-hungry VM 5 alone on Host 2">
|
||||
<g fill="none" stroke="rgba(255,255,255,0.22)" strokeDasharray="6 5">
|
||||
<rect x="25" y="40" width="280" height="180" rx="10"/>
|
||||
<rect x="335" y="40" width="280" height="180" rx="10"/>
|
||||
</g>
|
||||
<g fontSize="12.5" fill="#7a8699">
|
||||
<text x="41" y="64">Host 1</text>
|
||||
<text x="351" y="64">Host 2</text>
|
||||
</g>
|
||||
{/* Host CPU gauges: start as in FIG 2 (5% / 95%), update once both
|
||||
VMs have landed. Static (reduced-motion) readers see the final state. */}
|
||||
<g className="schema-transient" fontSize="11" textAnchor="end" opacity="1">
|
||||
<text x="289" y="64" fill="#56c288">CPU 5%</text>
|
||||
<text x="599" y="64" fill="#ef6a5f">CPU 95%</text>
|
||||
<animate attributeName="opacity" dur="12s" repeatCount="indefinite"
|
||||
values="1;1;0;0;1;1" keyTimes="0;0.27;0.3;0.96;0.99;1"/>
|
||||
</g>
|
||||
<g className="schema-live" fontSize="11" textAnchor="end" opacity="0">
|
||||
<text x="289" y="64" fill="#56c288">CPU 15%</text>
|
||||
<text x="599" y="64" fill="#e0a94a">CPU 80%</text>
|
||||
<animate attributeName="opacity" dur="12s" repeatCount="indefinite"
|
||||
values="0;0;1;1;0;0" keyTimes="0;0.27;0.3;0.94;0.96;1"/>
|
||||
</g>
|
||||
<g fill="rgba(86,194,136,0.14)" stroke="#56c288">
|
||||
<rect x="45" y="84" width="64" height="44" rx="5"/>
|
||||
<rect x="129" y="84" width="64" height="44" rx="5"/>
|
||||
<rect x="213" y="84" width="64" height="44" rx="5"/>
|
||||
</g>
|
||||
<g className="schema-glow">
|
||||
<rect x="439" y="94" width="64" height="44" rx="5" fill="rgba(239,106,95,0.2)" stroke="#ef6a5f" strokeWidth="1.6"/>
|
||||
</g>
|
||||
<g fontSize="11" fill="#c6d2e1" textAnchor="middle">
|
||||
<text x="77" y="110">VM 1</text>
|
||||
<text x="161" y="110">VM 2</text>
|
||||
<text x="245" y="110">VM 3</text>
|
||||
<text x="471" y="116">VM 5</text>
|
||||
</g>
|
||||
<text x="471" y="131" fontSize="9" fill="#ef6a5f" textAnchor="middle">100% CPU</text>
|
||||
<text className="schema-transient" x="330" y="236" fontSize="9.5" fill="#7a8699" textAnchor="middle">live migration</text>
|
||||
{/* VM 4: origin (starved, on Host 2) fades out, a mover rides the
|
||||
wire, the healthy copy appears on Host 1. */}
|
||||
<g className="schema-live" opacity="1">
|
||||
<rect x="355" y="94" width="64" height="44" rx="5" fill="rgba(224,169,74,0.12)" stroke="#e0a94a" strokeOpacity="0.85"/>
|
||||
<text x="387" y="116" fontSize="11" fill="#c6d2e1" textAnchor="middle">VM 4</text>
|
||||
<text x="387" y="131" fontSize="9" fill="#e0a94a" textAnchor="middle">waiting…</text>
|
||||
<animate attributeName="opacity" dur="12s" repeatCount="indefinite"
|
||||
values="1;1;0;0;1;1" keyTimes="0;0.15;0.17;0.96;0.99;1"/>
|
||||
</g>
|
||||
<g className="schema-packet" opacity="0">
|
||||
<rect x="-32" y="-22" width="64" height="44" rx="5" fill="rgba(224,169,74,0.16)" stroke="#e0a94a"/>
|
||||
<text x="0" y="4" fontSize="11" fill="#e0a94a" textAnchor="middle">VM 4</text>
|
||||
<animateMotion dur="12s" repeatCount="indefinite" calcMode="linear"
|
||||
path="M387,116 C 330,158 220,128 119,174"
|
||||
keyPoints="0;0;1;1" keyTimes="0;0.15;0.27;1"/>
|
||||
<animate attributeName="opacity" dur="12s" repeatCount="indefinite"
|
||||
values="0;0;1;1;0;0" keyTimes="0;0.15;0.16;0.26;0.28;1"/>
|
||||
</g>
|
||||
<g className="schema-live" opacity="0">
|
||||
<rect x="87" y="152" width="64" height="44" rx="5" fill="rgba(86,194,136,0.14)" stroke="#56c288"/>
|
||||
<text x="119" y="178" fontSize="11" fill="#c6d2e1" textAnchor="middle">VM 4</text>
|
||||
<animate attributeName="opacity" dur="12s" repeatCount="indefinite"
|
||||
values="0;0;1;1;0;0" keyTimes="0;0.26;0.28;0.94;0.96;1"/>
|
||||
</g>
|
||||
{/* VM 6: same journey, at the same time. */}
|
||||
<g className="schema-live" opacity="1">
|
||||
<rect x="523" y="94" width="64" height="44" rx="5" fill="rgba(224,169,74,0.12)" stroke="#e0a94a" strokeOpacity="0.85"/>
|
||||
<text x="555" y="116" fontSize="11" fill="#c6d2e1" textAnchor="middle">VM 6</text>
|
||||
<text x="555" y="131" fontSize="9" fill="#e0a94a" textAnchor="middle">waiting…</text>
|
||||
<animate attributeName="opacity" dur="12s" repeatCount="indefinite"
|
||||
values="1;1;0;0;1;1" keyTimes="0;0.15;0.17;0.96;0.99;1"/>
|
||||
</g>
|
||||
<g className="schema-packet" opacity="0">
|
||||
<rect x="-32" y="-22" width="64" height="44" rx="5" fill="rgba(224,169,74,0.16)" stroke="#e0a94a"/>
|
||||
<text x="0" y="4" fontSize="11" fill="#e0a94a" textAnchor="middle">VM 6</text>
|
||||
<animateMotion dur="12s" repeatCount="indefinite" calcMode="linear"
|
||||
path="M555,116 C 500,180 340,190 219,174"
|
||||
keyPoints="0;0;1;1" keyTimes="0;0.15;0.27;1"/>
|
||||
<animate attributeName="opacity" dur="12s" repeatCount="indefinite"
|
||||
values="0;0;1;1;0;0" keyTimes="0;0.15;0.16;0.26;0.28;1"/>
|
||||
</g>
|
||||
<g className="schema-live" opacity="0">
|
||||
<rect x="187" y="152" width="64" height="44" rx="5" fill="rgba(86,194,136,0.14)" stroke="#56c288"/>
|
||||
<text x="219" y="178" fontSize="11" fill="#c6d2e1" textAnchor="middle">VM 6</text>
|
||||
<animate attributeName="opacity" dur="12s" repeatCount="indefinite"
|
||||
values="0;0;1;1;0;0" keyTimes="0;0.26;0.28;0.94;0.96;1"/>
|
||||
</g>
|
||||
</svg>
|
||||
</Schema>
|
||||
|
||||
`Host 1` has a slightly higher load, but `Host 2` can fully handle the “problematic” VM without disrupting the other VMs.
|
||||
`Host 1` has a slightly higher load, but `Host 2` can fully handle the "problematic" VM without disrupting the other VMs.
|
||||
|
||||
This way, the heavy load on a single VM doesn’t end up penalizing everything else.
|
||||
|
||||
@@ -51,34 +210,42 @@ Load balancing plans have:
|
||||
- Pool(s) where to apply the policy
|
||||
- A mode (see [Plan modes](#plan-modes))
|
||||
|
||||
:::warning
|
||||
A pool can only belong to **one** plan: the plugin will refuse a configuration where two plans share a pool.
|
||||
:::
|
||||
|
||||
### Plan modes
|
||||
|
||||
Plans can work in one of these 3 modes:
|
||||
|
||||
- **Performance:** VMs are placed to use all possible resources. This means balance the load to give the best overall performance possible. This tends to use all hosts available to spread the load.\
|
||||
To specify how the performance plan should act, go to the [Performance plan behavior](#performance-plan-behavior) section.
|
||||
- **Performance:** VMs are placed to make the most of all available resources: the load is spread across every available host, to give the best overall performance.\
|
||||
To specify how the performance plan should act, see the [Performance plan behavior](#performance-plan-behavior) section.
|
||||
|
||||
- **Density:** This time, the objective is to use the least hosts possible, and to concentrate your VMs. In this mode, unused (and compatible) hosts are shut down.
|
||||
- **Simple:** This mode allows you to use VM anti-affinity without using any load balancing mechanism (see [VM Anti-affinity](#vm-anti-affinity)).
|
||||
- **Density:** This time, the objective is to use the least hosts possible, and to concentrate your VMs. In this mode, emptied hosts are shut down. A few safety rules apply: the pool master is never evacuated, and only hosts with a **power-on mode** configured (so XO can power them back on later) are candidates for shutdown. A host is also skipped if any of its running VMs cannot be migrated (missing guest tools, or carrying an affinity/anti-affinity tag).
|
||||
- **Simple:** This mode allows you to use [VM affinity](#vm-affinity) and [anti-affinity](#vm-anti-affinity) without any load balancing mechanism.
|
||||
|
||||
:::tip
|
||||
The performance plan also powers halted hosts back on: any halted host of the plan's pools with a power-on mode configured is started, so its resources are available to spread the load. This is the counterpart of the density plan shutting hosts down.
|
||||
:::
|
||||
|
||||
### Create a new plan
|
||||
|
||||
To create a new plan:
|
||||
|
||||
1. From the navigation bar, go to the **Settings → Plugin** section.
|
||||
1. From the navigation bar, go to the **Settings → Plugins** section.
|
||||
2. Open the **load-balancer** plugin and click the **+** button to show the **Configuration** menu:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/load_balancing_configuration.png" alt="The load-balancer plugin, in Settings › Plugins" width={700} />
|
||||
|
||||
Here, you can create a new load balancing plan or edit an existing one.
|
||||
|
||||
3. In **Configuration → Plans**, check the box called **Fill information (optional)**:
|
||||
\
|
||||
<UiDetail src="/img/xo5/load_balancing_fill_information.png" alt="Check “Fill information (optional)” to reveal the Add button" width={480} />\
|
||||
The **Add** button will appear.
|
||||
4. Click **Add**:
|
||||

|
||||
<UiDetail src="/img/xo5/load_balancing_add.png" alt="Click Add to create a new plan" width={700} />
|
||||
A new form will open, where you can set up your plan:
|
||||

|
||||
<UiDetail src="/img/xo5/load_balancing_new_plan.png" alt="The new plan form: name, mode, pools" width={620} />
|
||||
|
||||
5. Enter a **Name** for your plan.
|
||||
6. Select a **Mode**.
|
||||
@@ -88,10 +255,10 @@ To create a new plan:
|
||||
|
||||
### Critical thresholds
|
||||
|
||||
In a load balancing plan, you can define different performance thresholds, such as:
|
||||
In a load balancing plan, you can define two critical thresholds:
|
||||
|
||||
- CPU threshold
|
||||
- Free memory
|
||||
- CPU usage (%)
|
||||
- Free memory (MB)
|
||||
|
||||
To configure thresholds for your plan:
|
||||
|
||||
@@ -101,34 +268,42 @@ To configure thresholds for your plan:
|
||||
4. Check the **Fill information (optional)** box.\
|
||||
New fields will appear where you can set your thresholds:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/load_balancing_thresholds.png" alt="Set the critical thresholds of the plan" width={620} />
|
||||
|
||||
The defaults are **90%** for CPU and **1000 MB** of free memory.
|
||||
|
||||
:::warning
|
||||
If the CPU threshold is set to 90%, the load balancer will only trigger if the **average CPU usage on a host** exceeds 90%.
|
||||
The threshold you configure is the **critical** value, and the plugin deliberately acts *before* reaching it: a host is considered overloaded when its average CPU usage exceeds **85% of the critical value** (76.5% with the default 90%), and migrations continue until it falls back under **65% of it** (58.5% by default). For memory it's symmetrical: migrations start when free RAM drops below **1.2×** the configured value (1200 MB by default) and stop once it's back above **1.5×** (1500 MB by default).
|
||||
:::
|
||||
|
||||
For memory, load balancing will trigger when **free RAM** drops below the **Free memory** threshold.
|
||||
To avoid reacting to a momentary spike, the decision is based on a weighted average: 75% of the last minute, 25% of the last 30 minutes. A host has to be busy *for a while* before its VMs start moving.
|
||||
|
||||
### Exclusion
|
||||
|
||||
If you want to prevent load balancing from triggering migrations on a particular host or VM, you can exclude it from the process. This can be done with:
|
||||
|
||||
- The **Excluded hosts** setting in each plan
|
||||
- The **Ignored VM tags** parameter, which is common to every plan
|
||||
- The **Excluded hosts** setting in each plan: an excluded host is never used as a source *or* a destination, and is never powered on or shut down by the plugin
|
||||
- The **Ignored VM tags** parameter, which is common to every plan: VMs carrying one of these tags are never migrated
|
||||
|
||||
:::note
|
||||
Only **running** VMs are considered, and a VM needs the **guest tools** installed to be live migrated: VMs without them simply stay where they are.
|
||||
:::
|
||||
|
||||
### Timing
|
||||
|
||||
The global situation (resource usage) is examined **every minute**.
|
||||
The global situation (resource usage) is examined **every minute**, and each run works on smoothed metrics rather than instant values (see [Critical thresholds](#critical-thresholds)).
|
||||
|
||||
Every migration decided by the plugin is visible in the XO **Tasks** view, as a task named "Load balancer migrates VM …" whose description tells you the source, the destination and the *reason*: CPU over threshold for too long, CPU significantly higher than the pool average, vCPU balancing, affinity or anti-affinity satisfaction, or a density-plan host shutdown. Nothing moves silently.
|
||||
|
||||
:::tip
|
||||
TODO: more details to come here
|
||||
During a [Rolling Pool Update](./manage_infrastructure#rolling-pool-updates-rpu), the load balancer is automatically suspended, and re-enabled 30 minutes after the update completes, so the two features never fight over VM placement.
|
||||
:::
|
||||
|
||||
### Advanced settings
|
||||
|
||||
You can fine-tune your load balancing plan using the advanced settings.
|
||||
The advanced settings fine-tune how migrations are performed. They are global: they apply to every plan.
|
||||
|
||||
To do this:
|
||||
To change them:
|
||||
|
||||
1. Go to **Configuration → Advanced**.
|
||||
2. Check the **Fill information (optional)** box.\
|
||||
@@ -139,20 +314,23 @@ To do this:
|
||||
|
||||
#### Maximum concurrent migrations
|
||||
|
||||
This option lets you define the maximum number of migrations that can run at the same time. Limiting concurrent migrations can help maintain the overall performance of your environment.
|
||||
This option lets you define the maximum number of migrations that can run at the same time (default: **2**, shared by all plans). Limiting concurrent migrations can help maintain the overall performance of your environment.
|
||||
|
||||
#### Migration cooldown
|
||||
|
||||
This option prevents the load balancer from migrating the same VM twice in quick succession, by forcing a given delay between load-balancer-related migrations. Default to 30 minutes, set to 0 to disable it.
|
||||
This option prevents the load balancer from migrating the same VM twice in quick succession, by forcing a given delay between load-balancer-related migrations. Defaults to **30 minutes**, set to 0 to disable it.
|
||||
|
||||

|
||||
:::note
|
||||
The density plan does not apply the cooldown: when it evacuates a host to shut it down, it moves everything.
|
||||
:::
|
||||
|
||||
<UiDetail src="/img/xo5/load_balancing_advanced_settings.png" alt="The advanced settings of the plugin" width={700} />
|
||||
|
||||
### Performance plan behavior
|
||||
|
||||
With a performance plan, you can enable a performance sub-mode that adds extra features on top of the plan’s default behavior.
|
||||
These features are complementary and do not replace the default behavior.
|
||||
With a performance plan, you can pick a behavior that adds extra logic on top of the plan's threshold-based balancing. The default behavior always stays active: these options complement it, they don't replace it.
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/load_balancing_performance_plan_behavior.png" alt="The three behaviors of a performance plan" width={700} />
|
||||
|
||||
#### Conservative (default)
|
||||
|
||||
@@ -160,28 +338,37 @@ This is the standard behavior of the performance plan.
|
||||
|
||||
#### Preventive
|
||||
|
||||
By default, the performance plan only migrates VMs once CPU or memory usage reaches critical levels. The Preventive option goes further by trying to reduce CPU usage imbalances between hosts in the pool. For example, it aims to avoid a situation where one host runs at 60% CPU while others sit at 10% — something the default behavior would normally allow.
|
||||
By default, the performance plan only migrates VMs once CPU or memory usage reaches critical levels. The Preventive option goes further by trying to reduce CPU usage imbalances between hosts in the pool. For example, it aims to avoid a situation where one host runs at 60% CPU while others sit at 10%, something the default behavior would normally allow. Concretely, it kicks in when a host uses at least 1.5× the pool's average CPU (and at least 25% CPU), and only when no host is over the critical thresholds.
|
||||
|
||||
#### vCPU balancing
|
||||
|
||||
When the pool load is low (under 40% CPU usage), this option proactively distributes VMs across hosts to reduce large disparities in the number of vCPUs per CPU, rather than waiting until a host is overloaded.
|
||||
This way, VMs are pre-positioned to minimize the number of migrations needed later as the load increases.
|
||||
|
||||
## VM affinity
|
||||
|
||||
VM affinity keeps VMs together: all the VMs sharing one of the plan's **Affinity tags** are placed on the **same host**. This is useful when a group of VMs talk to each other a lot and benefit from staying on the same machine (chatty application tiers, a VM and its cache, etc.).
|
||||
|
||||
Affinity runs in every plan mode, including Simple. The plugin gathers all VMs carrying a given tag onto the host that already holds most of them, and if that host lacks memory, it will even move *other*, untagged VMs out of the way to make room.
|
||||
|
||||
:::warning
|
||||
Avoid giving a VM several affinity tags: the plugin then has to merge all these groups into one (if VM 1 has tags A and B, and VM 2 has tags B and C, then A, B and C must all land on the same host), and it logs a warning about it.
|
||||
:::
|
||||
|
||||
## VM anti-affinity
|
||||
|
||||
VM anti-affinity is a feature that prevents VMs with the same user tags from running on the same host. This functionality is built into the load-balancer plugin.
|
||||
It helps you avoid situations where redundant or similar VMs end up on the same host.
|
||||
VM anti-affinity is the opposite: it prevents VMs sharing the same tag from running on the same host. Use it to keep redundant VMs (replicas, cluster members) apart, so losing one host never takes down both copies.
|
||||
|
||||
For example, imagine you have several VMs running MySQL and PostgreSQL with high availability or replication.
|
||||
Naturally, you don’t want both replicated databases to be placed on the same physical host.
|
||||
To prevent that, set up your plan like this:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/antiaffinity.png" alt="A simple plan with two anti-affinity tags" width={560} />
|
||||
|
||||
- **Simple plan:** no active load balancing mechanism is used.
|
||||
- **Anti-affinity**: we added two tags, meaning any VMs with one of these tags will not run on the same host as another VM that has the same tag (whenever possible).
|
||||
|
||||
You can also use the Performance plan with Anti-affinity enabled to continue migrating VMs that don’t have tags.
|
||||
You can also use the Performance plan with Anti-affinity enabled to continue migrating VMs that don’t have tags: tagged VMs are left to the affinity logic, and are never moved by the performance or density algorithms themselves.
|
||||
|
||||
:::tip
|
||||
This feature is not limited by the number of VMs sharing the same tag. For example, if you have six VMs with the same anti-affinity tag and two hosts, the plugin will try to place three VMs on each host. It distributes VMs as evenly as possible and, in most cases, takes priority over the performance algorithm.
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
# Management overview
|
||||
|
||||
Xen Orchestra is based on the concept of **one interface to rule all your pools, hosts and VMs, from any device**. It's made to do any object creation, modification, displays metrics and statistics. In other words, all the tools you need to administer your XCP-ng/Citrix Hypervisor (formerly XenServer) infrastructure efficiently.
|
||||
|
||||
See the [Infrastructure management section](manage_infrastructure.md) for more details and examples.
|
||||
|
||||

|
||||
|
||||
But there's even more! You can:
|
||||
|
||||
- [create XO users](users.md) to delegate resources
|
||||
- use [advanced features](advanced.md) like Cloud Init or web hooks
|
||||
- [load balance](load_balancing.md) your VMs
|
||||
- extend your network with [our SDN controller](sdn_controller.md)
|
||||
- create hyperconverged storage with [XOSTOR](https://docs.xcp-ng.org/xostor/)
|
||||
@@ -1,6 +1,8 @@
|
||||
# Infrastructure management
|
||||
|
||||
This section is related on how to manage your XCP-ng/Citrix Hypervisor infrastructure.
|
||||
<InterfaceNote>This page describes infrastructure management in the XO 5 interface. XO 6 already covers inspection of pools, hosts, networks and storage, host power actions, network and VIF creation.</InterfaceNote>
|
||||
|
||||
Xen Orchestra is built on one idea: **a single interface for all your pools, hosts and VMs, from any device**: creation, modification, metrics and statistics for every object of your XCP-ng infrastructure. This page covers those day-to-day operations in XO 5.
|
||||
|
||||
## Home view
|
||||
|
||||
@@ -8,17 +10,17 @@ The home view is what you see when you access your Xen Orchestra URL. It display
|
||||
|
||||
If you don't have any servers connected, you'll see a panel telling you to add a server:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/xo5noserver.png" alt="No host connected yet: add your first server to get started" width={420} />
|
||||
|
||||
### Add a host
|
||||
|
||||
Just click on "Add server", enter the IP of a XCP-ng/XenServer host (ideally the pool master if in a pool):
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/xo5addserver.png" alt="Enter the IP or FQDN of your host, with its root credentials" width={620} />
|
||||
|
||||
After clicking on connect, the server is displayed as connected:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/xo5connectedserver.png" alt="The pool appears as soon as the server is connected" width={620} />
|
||||
|
||||
Now go back to the Home view (or click on the "Xen Orchestra" title on the top left of the screen), you'll see the default home view of VM objects.
|
||||
|
||||
@@ -26,7 +28,7 @@ Now go back to the Home view (or click on the "Xen Orchestra" title on the top l
|
||||
|
||||
By default, this view groups all **running VMs** on your connected server and everyday administration tasks:
|
||||
|
||||

|
||||
<UiShot light="/img/xo5/xo5homevms.png" alt="The Home view lists every VM across all your connected pools" url="https://your-xo/v5/#/home" />
|
||||
|
||||
Let's take a quick tour:
|
||||
|
||||
@@ -44,7 +46,7 @@ You can select multiple objects (eg VMs) at once to perform a bulk action. The m
|
||||
|
||||
After selecting one or more object, an action bar is displayed:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/xo5bulk.png" alt="Select multiple objects to reveal the bulk action bar" width={700} />
|
||||
|
||||
This will execute the action for all selected objects!
|
||||
|
||||
@@ -52,7 +54,7 @@ This will execute the action for all selected objects!
|
||||
|
||||
All host objects are displayed:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/xo5host.png" alt="The Home view filtered on hosts" width={700} />
|
||||
|
||||
You have power status, name, description, number of CPU cores, total memory, management IP and pool name displayed. You can also edit these by long clicking.
|
||||
|
||||
@@ -64,7 +66,7 @@ If hosts have missing patches, you'll see a red dot with the total patches missi
|
||||
|
||||
All your pools are displayed here:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/xo5pool.png" alt="The Home view filtered on pools" width={700} />
|
||||
|
||||
You can also see missing patches in red.
|
||||
|
||||
@@ -89,11 +91,11 @@ Pro Tip: the URL of Xen Orchestra contains the search string, eg `home?s=power_s
|
||||
|
||||
We include some predefined filters in the dropdown "Filters":
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/xo5presetfilter.png" alt="Preset filters for VMs" width={320} />
|
||||
|
||||
You can use custom filters here:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/xo5presetfilter2.png" alt="Preset filters for hosts" width={360} />
|
||||
|
||||
### Save your search
|
||||
|
||||
@@ -213,7 +215,7 @@ Example: to search by the Xen Tools status:
|
||||
|
||||
A new VM can be created via the "New" button in the main menu (bottom):
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/xo5vmcreatemenu.png" alt="The New menu in the main navigation" width={320} />
|
||||
|
||||
Or in the home view:
|
||||
|
||||
@@ -225,7 +227,7 @@ Or in the home view:
|
||||
|
||||
Because Xen Orchestra can be connected to multiple pools, you must select which one you want to create your VMs on:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/xo5createonpool.png" alt="Select the pool where the VM will be created" width={620} />
|
||||
|
||||
On which **host** the VM will actually run on will depend of various settings (local SR or not, RAM available etc.)
|
||||
|
||||
@@ -235,7 +237,7 @@ On which **host** the VM will actually run on will depend of various settings (l
|
||||
|
||||
The next step is to select a template:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/xo5createwithtemplate.png" alt="Pick a template for your new VM" width={440} />
|
||||
|
||||
:::tip
|
||||
What is a XCP-ng/XenServer template? It can be 2 things: first an "empty" template, meaning it contains only the configuration for your future VM, such as example settings (minimum disk size, RAM and CPU, BIOS settings if HVM etc.) Or it could be a previous VM you converted into a template: in this case, creating a VM will clone the existing disks.
|
||||
@@ -251,7 +253,7 @@ You can create multiple VMs at once by toggling the _Multiple VMs_ option. The `
|
||||
|
||||
Click on the refresh icon to see the change:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/xo5multiplevms.png" alt="Create several identical VMs in one go" width={620} />
|
||||
|
||||
#### Performance
|
||||
|
||||
@@ -275,7 +277,7 @@ Depending of your template type (with existing disks or not, PV vs HVM) this pan
|
||||
|
||||
You can choose to boot from an ISO or using PXE:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/xo5installsettings.png" alt="Install settings for an HVM template: ISO/DVD or PXE" width={620} />
|
||||
|
||||
##### PV templates
|
||||
|
||||
@@ -305,11 +307,11 @@ Pro tip: avoid using large disks for your VMs. Want to store a lot of files? Use
|
||||
|
||||
Any object with a dotted underline can be edited with a mouse click: VM title, description, CPU and memory.
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/xo5editvm.png" alt="Long click any field to edit it in place" width={480} />
|
||||
|
||||
In the advanced tab, you have extra options:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/xo5vmadvanced.png" alt="The Advanced tab of a VM" width={620} />
|
||||
|
||||
### XCP-ng/Citrix Hypervisor limitations
|
||||
|
||||
@@ -327,7 +329,7 @@ Thanks to Xen Storage Motion, it's easy to move a VM disk from one storage locat
|
||||
|
||||
To do so: Access the Xen Orchestra page for your running VM, then enter the Disk tab. Long click on the current SR of the disk, and a drop down menu will be displayed with all compatible destinations. Just select one, that's all: the migration will start live!
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/xo5diskmigrate.png" alt="Migrate a disk to another SR, live, from the VM Disks tab" width={700} />
|
||||
|
||||
#### Offline VDI migration
|
||||
|
||||
@@ -337,7 +339,7 @@ Even though it's not currently supported in XCP-ng/XenServer, we can do it in Xe
|
||||
|
||||
In the advanced tab, use the "Recovery Start" button:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/xo5recovery.png" alt="Start the VM in recovery mode from its Advanced tab" width={700} />
|
||||
|
||||
This button will allow you to boot directly from the CD drive, ignoring your current disks. Note that it works for all virtualization modes: HVM or PV.
|
||||
|
||||
@@ -351,13 +353,13 @@ Activating "Auto Power on" for a VM will also configure the pool accordingly. If
|
||||
|
||||
In the Vates stack, each VM connects to the network through a **Virtual Interface**, or **VIF**.
|
||||
|
||||
Think of it as the VM’s virtual network card —it handles all incoming and outgoing traffic on a specific virtual network, which is linked to a physical NIC on the host via a bridge. Every VIF comes with a fixed MAC address and can be tied to a particular VLAN (or virtual network), depending on how your environment is set up.
|
||||
Think of it as the VM’s virtual network card: it handles all incoming and outgoing traffic on a specific virtual network, which is linked to a physical NIC on the host via a bridge. Every VIF comes with a fixed MAC address and can be tied to a particular VLAN (or virtual network), depending on how your environment is set up.
|
||||
|
||||
#### What does VIF locking mode do?
|
||||
|
||||
**VIF locking mode** is a security feature that helps prevent unauthorized or spoofed traffic from getting in or out of a VM.
|
||||
|
||||
In practical terms, enabling locking mode means **the VM can’t send traffic using a fake MAC address** — and if an IP address is set, it won’t be able to use anything else either. This is **especially helpful in multi-tenant setups** or anytime you need tight control over which VM is allowed to do what on the network.
|
||||
In practical terms, enabling locking mode means **the VM can’t send traffic using a fake MAC address**, and if an IP address is set, it won’t be able to use anything else either. This is **especially helpful in multi-tenant setups** or anytime you need tight control over which VM is allowed to do what on the network.
|
||||
|
||||
#### Default behavior
|
||||
|
||||
@@ -369,25 +371,25 @@ However, if you add restricted IPs, the VIF becomes locked, meaning only the spe
|
||||
To add a restricted IP address:
|
||||
|
||||
1. Go to the **VM view** and open the **Network** tab. You will see a column called **Allowed IPs**:
|
||||

|
||||
<UiDetail src="/img/xo5/allowed-ip-column.png" alt="The allowed IPs column in the VM Network tab" width={700} />
|
||||
1. Click the **+** icon to add authorized IP addresses:
|
||||

|
||||
<UiDetail src="/img/xo5/add-allowed-ip.png" alt="Add an allowed IP address to a VIF" width={300} />
|
||||
|
||||
#### How do I enable VIF locking mode?
|
||||
|
||||
1. Select the VM.
|
||||
1. Head over to the **Network** tab to see each VIF along with its current locking mode status:
|
||||

|
||||
<UiDetail src="/img/xo5/vif-locking-status.png" alt="The VIF locking status in the VM Network tab" width={700} />
|
||||
1. To change the locking mode status:
|
||||
1. Click the pencil icon (with the **Edit locking mode** label). A dropdown menu appears.
|
||||
1. Choose your desired mode from that menu:
|
||||

|
||||
<UiDetail src="/img/xo5/choose-vif-locking-mode.png" alt="Choose the locking mode of a VIF" width={320} />
|
||||
|
||||
If Xen Orchestra knows the VM’s IP address — either through the guest agent or DHCP — it will automatically apply IP-level locking when the mode is enabled.
|
||||
If Xen Orchestra knows the VM’s IP address (either through the guest agent or DHCP), it will automatically apply IP-level locking when the mode is enabled.
|
||||
|
||||
#### How do I automate VIF locking mode?
|
||||
|
||||
If you’re automating things or working with scripts, you can also control VIF locking mode through the XO [command-line interface](architecture#xo-cli-cli).
|
||||
If you’re automating things or working with scripts, you can also control VIF locking mode through the XO [command-line interface](../architecture.md#xo-cli).
|
||||
|
||||
### VM high availability (HA)
|
||||
|
||||
@@ -455,7 +457,7 @@ We support OVA import from VirtualBox. Feel free to report issues with OVA from
|
||||
|
||||
To import an XVA file, just go to the New/Import menu:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/xoa5import.png" alt="Import an XVA file from the New › Import menu" width={340} />
|
||||
|
||||
Select the target pool and SR where the VM will be imported. Then, drag and drop your file and click on the import button.
|
||||
|
||||
@@ -463,7 +465,7 @@ Select the target pool and SR where the VM will be imported. Then, drag and drop
|
||||
|
||||
OVA files contains extra info that you need to check before importing, like name, etc.
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/ova-import.png" alt="OVA import: review the VM parameters before importing" width={620} />
|
||||
|
||||
When you are OK with these settings, just click on the "Import" button.
|
||||
|
||||
@@ -544,7 +546,7 @@ Maintenance mode will trigger two actions internally:
|
||||
|
||||
It's perfect if you want to shutdown the host for hardware replacement, or if you want to do some other operations without disrupting your production.
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/maintenancemode.png" alt="Enable maintenance mode from the host view" width={480} />
|
||||
|
||||
Note that maintenance mode will be **automatically exited after a host reboot**.
|
||||
|
||||
@@ -552,7 +554,7 @@ Note that maintenance mode will be **automatically exited after a host reboot**.
|
||||
|
||||
You can easily adjust the control domain memory under the Advanced tab of a host. Enable the maintenance mode on the host and click on the pen icon to edit the value:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/dom0memory.png" alt="Edit the Dom0 memory from the host Advanced tab" width={460} />
|
||||
|
||||
There is more information about Dom0 memory management in the [XCP-ng Documentation](https://docs.xcp-ng.org/guides/dom0-memory/)
|
||||
|
||||
@@ -568,13 +570,13 @@ Updates can be called both "patches" or "updates", it doesn't matter. Updates ar
|
||||
|
||||
You'll be notified by Xen Orchestra directly in the main XO menu (on the left), with a yellow triangle:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/availableupdates.png" alt="The number of missing patches, right on the pool" width={300} />
|
||||
|
||||
If you hover on it, it will explain that updates/patches are available.
|
||||
|
||||
You can also see how many updates to do in the Home/Pool view for your pools, and Home/Host view for your hosts, with a red pill. In this following screenshot, "Test Pool1" got 88 updates available:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/updatesvisible.png" alt="Missing patches listed for the host" width={320} />
|
||||
|
||||
You can also see the available updates in the Dashboard view.
|
||||
|
||||
@@ -591,7 +593,7 @@ So unlike with Citrix Hypervisor, Xen Orchestra will not fetch or download updat
|
||||
|
||||
Also known as RPU, **this is the advised way to update your pool**. By just clicking on one button, Xen Orchestra will automatically move VMs around, apply updates and reboot the hosts, without any service interruption. The following button is available in the **Pool** view of the **Patches** tab:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/rpubutton.png" alt="The Rolling Pool Update button on the pool Patches tab" width={340} />
|
||||
|
||||
:::tip
|
||||
This powerful and fully automated mechanism requires some prerequisites: all your VMs disks must be on a one (or more) shared storage. Also, high-availability will be automatically disabled, as the XO load balancer plugin and backup jobs. Everything will be enabled back when it's done!
|
||||
@@ -607,7 +609,7 @@ restartHostTimeout = '40 minutes'
|
||||
|
||||
:::
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/rpu1.png" alt="XO orchestrates everything: evacuate, patch, reboot, repeat on each host" width={620} />
|
||||
|
||||
##### Scheduling a RPU
|
||||
|
||||
@@ -618,9 +620,9 @@ Of course, schedule the updates outside production hours. Although RPUs are desi
|
||||
:::
|
||||
|
||||
1. **Create a job**: Navigate to the **Jobs** screen and create a new job, using the `pool.rollingUpdate` method. Determine which pools you want to include in the update:
|
||||

|
||||
<UiDetail src="/img/xo5/create-rpu.png" alt="Create a scheduled Rolling Pool Update job" width={700} />
|
||||
1. **Set the schedule**: Assign a schedule to the job (e.g., every Sunday at 3 AM) and apply it to your new job:
|
||||

|
||||
<UiDetail src="/img/xo5/schedule-rpu.png" alt="Pick the schedule for your Rolling Pool Update" width={620} />
|
||||
1. **Monitor the process**: Once scheduled, the RPU will run automatically at the set time, applying updates and rebooting hosts as necessary.
|
||||
|
||||
##### Troubleshooting a RPU
|
||||
@@ -654,7 +656,7 @@ tracesRetention = '31 days'
|
||||
|
||||
If you can't use RPU (Rolling Pool Updates), you can still use "Install pool patches" button. This will simply install updates on all hosts on your pool and restart the toolstack, **without doing any host reboot**:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/installpoolpatches.png" alt="Install all pool patches in one click" width={340} />
|
||||
|
||||
:::tip
|
||||
Restarting the toolstack won't have any impact on your running VMs. However, **most updates will require a reboot** to be applied, that you should execute during a scheduled maintenance.
|
||||
@@ -662,7 +664,7 @@ Restarting the toolstack won't have any impact on your running VMs. However, **m
|
||||
|
||||
You can see hosts that will require a reboot via a small blue triangle:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/xo5patching.png" alt="Patch installation progress" width={620} />
|
||||
|
||||
#### Host updates
|
||||
|
||||
@@ -691,7 +693,7 @@ When you click on "Install all patches", XOA will do all of the following automa
|
||||
You can see [more screenshots here](https://xen-orchestra.com/blog/hotfix-xs70e004-for-xenserver-7-0).
|
||||
|
||||
:::tip
|
||||
If you are behind a proxy, please update your `xo-server` configuration to add a proxy server, as [explained in the appropriate section](configuration.md#proxy-for-updates-and-patches).
|
||||
If you are behind a proxy, please update your `xo-server` configuration to add a proxy server, as [explained in the appropriate section](../configuration.md#proxy-for-updates-and-patches).
|
||||
:::
|
||||
|
||||
#### Host updates
|
||||
@@ -735,7 +737,7 @@ Don't add pool slaves to your XOA server list! XOA will automatically find them
|
||||
|
||||
To remove one host from a pool, you can go to the "Advanced" tab of the host page for the host you wish to remove, and click on "Detach"
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/detach-host.png" alt="Detach the host from its pool, from the host Advanced tab" width={700} />
|
||||
|
||||
:::warning
|
||||
|
||||
@@ -749,7 +751,7 @@ To remove one host from a pool, you can go to the "Advanced" tab of the host pag
|
||||
|
||||
Network bonding, also known as link aggregation, involves combining two or more physical network interfaces into a single logical interface.
|
||||
|
||||
The primary goals are to improve redundancy —so that a single cable or interface failure does not interrupt connectivity— and, depending on the bonding mode, to increase throughput by distributing traffic across multiple links.
|
||||
The primary goals are to improve redundancy, so that a single cable or interface failure does not interrupt connectivity— and, depending on the bonding mode, to increase throughput by distributing traffic across multiple links.
|
||||
|
||||
#### Supported bond types
|
||||
|
||||
@@ -778,14 +780,14 @@ Xen Orchestra supports the following bond types:
|
||||
1. Navigate to **New → Network** to open the **Create Network** page.
|
||||
2. Choose the pool where you want the bond to be created.
|
||||
3. Enable the **Bonded network** toggle:
|
||||

|
||||
<UiDetail src="/img/xo5/bond0.png" alt="Create a bonded network from the pool Network tab" width={620} />
|
||||
4. In the **Interface** dropdown, select two or more physical interfaces (PIFs) to include in the bond.
|
||||
5. Provide a **name** and a **description** for the bond.
|
||||
6. Set the **Bond mode** to **LACP**.
|
||||
7. Leave the **MTU** field blank. This will work as-is in most cases.
|
||||
8. Click **Create network**.
|
||||
XO will then create the bond on the host(s):
|
||||

|
||||
<UiDetail src="/img/xo5/bond1.png" alt="The bond and its member interfaces" width={620} />
|
||||
|
||||
:::tip
|
||||
|
||||
@@ -800,7 +802,7 @@ Once a bond (e.g., `bond0`) is created, you can build VLANs over it:
|
||||
1. Go again to **New → Network** screen.
|
||||
2. Select the new bond interface (e.g., `bond0`) in the **Interface** dropdown.
|
||||
3. Provide a **name**, **description**, and specify the **VLAN** ID (for instance, `20`):
|
||||

|
||||
<UiDetail src="/img/xo5/bond2.png" alt="Create a VLAN network on top of the bond" width={440} />
|
||||
4. Validate the VLAN network creation.\
|
||||
This creates a virtual network on top of the bond, using the name and ID you've specified, available for VM attachment.
|
||||
|
||||
@@ -810,7 +812,7 @@ This process is the same whether you're adding a VLAN on top of a LACP network b
|
||||
|
||||
## Storage Management
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/xo5storageadvanced.png" alt="The SR Advanced tab" width={700} />
|
||||
|
||||
### Maintenance mode
|
||||
|
||||
@@ -820,7 +822,7 @@ Maintenance mode will trigger two actions internally:
|
||||
- shutdown related VMs
|
||||
- disconnect the storage from your hosts
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/SR-maintenance-mode.png" alt="Enable maintenance mode on a storage repository" width={480} />
|
||||
|
||||
This way, you can do whatever is needed on the storage, and when done, re-enable it: all the hosts will be reconnected to it. No manual process to find all VMs related to this SR, shut them down, then disconnect all the PBDs.
|
||||
|
||||
@@ -828,21 +830,21 @@ This way, you can do whatever is needed on the storage, and when done, re-enable
|
||||
|
||||
If your SAN supports it, Xen Orchestra can instruct your XCP-ng host to send a trim command to perform some cleaning.
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/xo5reclaimfree.png" alt="Reclaim free space from the SR Advanced tab" width={620} />
|
||||
|
||||
## Visualizations
|
||||
|
||||
Visualizations can help you to understand your XCP-ng/XenServer infrastructure, as well as correlate events and detect bottlenecks.
|
||||
|
||||
:::tip
|
||||
👷 This section needs to be completed: screenshots and how-to 👷
|
||||
:::
|
||||
|
||||
### Dashboard
|
||||
|
||||
The dashboard view gathers information on all your connected pools/hosts.
|
||||
|
||||

|
||||
:::note
|
||||
Since XO 6 became the default interface, `https://your-xo/#/dashboard` opens the [new XO 6 dashboard](../xo6/management.md). The XO 5 dashboard described here now lives under `/v5/`.
|
||||
:::
|
||||
|
||||
<UiShot light="/img/xo5/dashboard-overview.png" alt="The Overview aggregates pools, hosts, VMs, resource usage and alarms at a glance" url="https://your-xo/v5/#/dashboard/overview" />
|
||||
|
||||
:::tip
|
||||
You can also update all your hosts (install missing patches) from this page.
|
||||
@@ -852,7 +854,7 @@ You can also update all your hosts (install missing patches) from this page.
|
||||
|
||||
A Parallel Coordinates visualization helps to detect proportions in a hierarchical environment. In a XCP-ng/XenServer environment, it's especially useful if you want to see useful information from a large amount of data.
|
||||
|
||||

|
||||
<UiShot light="/img/xo5/dashboard-visualizations.png" alt="Follow a resource path across vCPUs, RAM, network and storage" url="https://your-xo/v5/#/dashboard/visualizations" />
|
||||
|
||||
## Health
|
||||
|
||||
@@ -910,13 +912,13 @@ This sections details the alerts coming from XCP-ng/XenServer hosts. More inform
|
||||
|
||||
A heatmap allows its reader to understand when your VMs or hosts are stressed. Values are relative, thus it's easy to detect trends or spikes.
|
||||
|
||||
[](https://xen-orchestra.com/blog/xen-orchestra-4-4/#heatmapforinfrastructurehealth).
|
||||
<UiDetail src="/img/xo5/heatmap.png" alt="The heatmap reveals activity patterns at a glance" width={700} />
|
||||
|
||||
### Event correlation
|
||||
|
||||
This is the place to compare metrics on comparable objects (VMs to VMs, hosts to hosts).
|
||||
|
||||
[](https://xen-orchestra.com/blog/xen-orchestra-4-6#eventcorrelation).
|
||||
<UiDetail src="/img/xo5/event-correlation.jpg" alt="Correlating VM metrics with infrastructure events" width={380} />
|
||||
|
||||
### Usage reports
|
||||
|
||||
@@ -928,7 +930,7 @@ To receive reports, you first need to enable the **usage-report** plugin:
|
||||
2. From the list, look for the **usage-report** plugin (you can scroll through the list or search for it by name).
|
||||
3. Enable the plugin by switching on the toggle next to the plugin name.
|
||||
4. Click the **+** icon to open the plugin settings:
|
||||

|
||||
<UiDetail src="/img/xo5/usage-report-plugin.png" alt="A usage report generated by the plugin" width={700} />
|
||||
5. In the **emails** section, click **Add**. A new text field will appear.
|
||||
6. Enter the email address where you want to receive the reports. Repeat steps 5–6 to add more addresses.
|
||||
7. Turn on the **all** toggle to include stats for all resources in your report, including:
|
||||
@@ -980,10 +982,10 @@ Xen Orchestra allows you to monitor the health of your software RAID arrays dire
|
||||
|
||||
To check the status reported by `mdadm`, go to the **Host → Advanced** section. You'll get a clear, real-time view of your RAID array’s condition:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/mdadm-status.png" alt="Software RAID status of the XOA, in its Dashboard" width={700} />
|
||||
|
||||
#### RAID status alerts
|
||||
|
||||
If a host has a degraded software RAID array, a red warning triangle will appear in the host view. Clicking on it will display detailed information about the issue, so you can quickly identify and address critical problems:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/raid-status-alert.png" alt="XO raises an alert when the RAID array is degraded" width={620} />
|
||||
|
||||
@@ -1,408 +0,0 @@
|
||||
# Model Context Protocol (MCP)
|
||||
|
||||
## What is MCP?
|
||||
|
||||
[MCP](https://modelcontextprotocol.io/) (Model Context Protocol) is an open standard that allows AI assistants to interact with external tools and data sources. Think of it as a universal adapter between AI assistants (like Claude) and your infrastructure.
|
||||
|
||||
With the `@xen-orchestra/mcp` package, your AI assistant can directly query your Xen Orchestra instance to answer questions about your virtualization infrastructure in natural language.
|
||||
|
||||
## Why MCP with Xen Orchestra?
|
||||
|
||||
MCP enables new ways to interact with your infrastructure:
|
||||
|
||||
- **Natural language queries** — Ask "How many VMs are running?" instead of navigating dashboards
|
||||
- **AI-assisted monitoring** — Get instant summaries of your infrastructure state
|
||||
- **Quick diagnostics** — Ask about specific VMs, hosts, or pools without leaving your conversation
|
||||
- **Documentation at your fingertips** — Search XO documentation directly from the assistant
|
||||
|
||||
All operations are **read-only by default**, ensuring safe interaction with your production environment. Write operations can be enabled explicitly — see [Write operations](#write-operations).
|
||||
|
||||
## Installation
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- **Node.js** 20 or later
|
||||
- A **Xen Orchestra** instance, version **6.5 or later**, with [REST API](restapi.md) enabled
|
||||
- An **AI assistant** that supports MCP (Claude Desktop, Claude Code, etc.)
|
||||
|
||||
:::warning
|
||||
The MCP server requires **Xen Orchestra 6.5 or later**. On an older XO it stops at startup with an error such as `Unable to verify MCP status (HTTP 404)`. Upgrade your Xen Orchestra to use it.
|
||||
:::
|
||||
|
||||
### Install the MCP server
|
||||
|
||||
```bash
|
||||
npm install -g @xen-orchestra/mcp
|
||||
```
|
||||
|
||||
Or run directly without installing:
|
||||
|
||||
```bash
|
||||
npx @xen-orchestra/mcp
|
||||
```
|
||||
|
||||
### Configure authentication
|
||||
|
||||
The MCP server connects to Xen Orchestra via the REST API. Two authentication modes are supported: **token** (recommended) or **username/password**.
|
||||
|
||||
| Variable | Required | Description |
|
||||
| ----------------------- | ----------------------- | --------------------------------------------------------------------------------------------- |
|
||||
| `XO_URL` | Yes | Xen Orchestra server URL (e.g., `https://xo.example.com`) |
|
||||
| `XO_TOKEN` | If no username/password | Authentication token |
|
||||
| `XO_USERNAME` | If no token | XO user with admin privileges |
|
||||
| `XO_PASSWORD` | If no token | XO password |
|
||||
| `XO_MCP_ENABLE_ACTIONS` | No | Set to `1` to expose write/destructive operations (see [Write operations](#write-operations)) |
|
||||
|
||||
To generate a token, go to the XO user page (`/user`) or run `xo-cli create-token`. If both `XO_TOKEN` and `XO_USERNAME`/`XO_PASSWORD` are set, token authentication takes priority.
|
||||
|
||||
:::tip
|
||||
Only admin users can currently use the REST API. See [REST API authentication](restapi.md#authentication) for details.
|
||||
:::
|
||||
|
||||
### Configure your AI assistant
|
||||
|
||||
#### Claude Desktop
|
||||
|
||||
Add the following to your Claude Desktop configuration file (`~/.config/claude-desktop/config.json` on Linux, `~/Library/Application Support/Claude/claude_desktop_config.json` on macOS):
|
||||
|
||||
Using a token (recommended):
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"xo": {
|
||||
"command": "npx",
|
||||
"args": ["@xen-orchestra/mcp"],
|
||||
"env": {
|
||||
"XO_URL": "https://your-xo-server",
|
||||
"XO_TOKEN": "your-token"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Using username/password:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"xo": {
|
||||
"command": "npx",
|
||||
"args": ["@xen-orchestra/mcp"],
|
||||
"env": {
|
||||
"XO_URL": "https://your-xo-server",
|
||||
"XO_USERNAME": "[email protected]",
|
||||
"XO_PASSWORD": "your-password"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Claude Code
|
||||
|
||||
```bash
|
||||
# Using a token (recommended)
|
||||
claude mcp add xo \
|
||||
-e XO_URL=https://your-xo-server \
|
||||
-e XO_TOKEN=your-token \
|
||||
-- npx @xen-orchestra/mcp
|
||||
|
||||
# Using username/password
|
||||
claude mcp add xo \
|
||||
-e XO_URL=https://your-xo-server \
|
||||
-e XO_USERNAME=[email protected] \
|
||||
-e XO_PASSWORD=your-password \
|
||||
-- npx @xen-orchestra/mcp
|
||||
```
|
||||
|
||||
#### Other MCP-compatible clients
|
||||
|
||||
Run the MCP server with environment variables set:
|
||||
|
||||
```bash
|
||||
# Using a token (recommended)
|
||||
XO_URL=https://your-xo-server \
|
||||
XO_TOKEN=your-token \
|
||||
npx @xen-orchestra/mcp
|
||||
|
||||
# Using username/password
|
||||
XO_URL=https://your-xo-server \
|
||||
XO_USERNAME=[email protected] \
|
||||
XO_PASSWORD=your-password \
|
||||
npx @xen-orchestra/mcp
|
||||
```
|
||||
|
||||
The server communicates via stdio using the MCP protocol (JSON-RPC), compatible with any MCP client.
|
||||
|
||||
#### Multiple XO instances
|
||||
|
||||
To manage several XO servers from the same assistant, add one entry per instance with a different name:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"xo-production": {
|
||||
"command": "npx",
|
||||
"args": ["@xen-orchestra/mcp"],
|
||||
"env": {
|
||||
"XO_URL": "https://xo-production.example.com",
|
||||
"XO_TOKEN": "prod-token"
|
||||
}
|
||||
},
|
||||
"xo-staging": {
|
||||
"command": "npx",
|
||||
"args": ["@xen-orchestra/mcp"],
|
||||
"env": {
|
||||
"XO_URL": "https://xo-staging.example.com",
|
||||
"XO_TOKEN": "staging-token"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
With Claude Code:
|
||||
|
||||
```bash
|
||||
claude mcp add xo-production \
|
||||
-e XO_URL=https://xo-production.example.com \
|
||||
-e XO_TOKEN=prod-token \
|
||||
-- npx @xen-orchestra/mcp
|
||||
|
||||
claude mcp add xo-staging \
|
||||
-e XO_URL=https://xo-staging.example.com \
|
||||
-e XO_TOKEN=staging-token \
|
||||
-- npx @xen-orchestra/mcp
|
||||
```
|
||||
|
||||
Each entry starts its own process with its own credentials. The assistant gets a separate set of tools per instance, so you can ask about a specific environment by name ("list running VMs on xo-production").
|
||||
|
||||
:::tip
|
||||
Pick descriptive names (`xo-production`, `xo-dr-site`, ...) so the assistant knows which instance you're referring to.
|
||||
:::
|
||||
|
||||
### Behind a corporate proxy
|
||||
|
||||
The MCP server respects `HTTP_PROXY`, `HTTPS_PROXY`, and `NO_PROXY`. This matters in enterprise networks: your AI assistant may need an outbound proxy to reach the public internet, but your XOA is internal and must be reached directly. Without `NO_PROXY`, internal traffic gets sent through the proxy and rejected.
|
||||
|
||||
| Variable | Effect |
|
||||
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `HTTP_PROXY` | Proxy URL for plain HTTP requests, e.g. `http://proxy.corp.example:3128`. Credentials are supported: `http://user:pass@proxy:3128` (Basic auth only — NTLM/Kerberos proxies need a sidecar like cntlm). |
|
||||
| `HTTPS_PROXY` | Proxy URL for HTTPS requests. Same format as `HTTP_PROXY`. The proxy itself is contacted over HTTP; `https://` schemes are unusual. |
|
||||
| `NO_PROXY` | Comma-separated list of hostnames that bypass the proxy. Three forms: exact host (`xoa.internal.example.com`), suffix wildcard (`.example.com` or `*.example.com` — matches subdomains, **not** the bare domain — list both if needed), or `*` alone to bypass everything. CIDR ranges are not supported by the underlying library. Lowercase `no_proxy` works too. |
|
||||
|
||||
Example for Claude Desktop, with a corporate proxy and a XOA on the internal network:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"xo": {
|
||||
"command": "npx",
|
||||
"args": ["@xen-orchestra/mcp"],
|
||||
"env": {
|
||||
"XO_URL": "https://xoa.internal.example.com",
|
||||
"XO_TOKEN": "your-token",
|
||||
"HTTPS_PROXY": "http://proxy.corp.example:3128",
|
||||
"NO_PROXY": "xoa.internal.example.com"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
:::note
|
||||
`NO_PROXY` on its own does nothing. If you set it without `HTTP_PROXY` or `HTTPS_PROXY`, the MCP logs a warning at startup. A malformed proxy URL is reported on stderr but does not crash the server; it falls back to direct connections.
|
||||
:::
|
||||
|
||||
### Disabling MCP globally
|
||||
|
||||
Sometimes you need to shut MCP off across the board — during an incident, while reviewing an internal policy, or simply to keep AI access turned off until you've decided who should have it. The xo-server config has a flag for that:
|
||||
|
||||
```toml
|
||||
[mcp]
|
||||
enabled = false
|
||||
```
|
||||
|
||||
Restart xo-server and the change takes effect immediately:
|
||||
|
||||
- The `@xen-orchestra/mcp` binary refuses to start. It prints `MCP disabled by admin` on stderr and exits with code 1.
|
||||
- Any MCP client already running gets a `503` with `{ "error": "mcp_disabled" }` on its next request, so sessions shut down without leaving stale connections on the server.
|
||||
|
||||
The default is `enabled = true`; legacy configs without an `[mcp]` section behave the same way. Flip the value, reload, done — no other state to clean up.
|
||||
|
||||
:::note Detection caveat
|
||||
The kill-switch keys off the `X-XO-Client: mcp` header the official binary sends. A third-party MCP client, or an older `@xen-orchestra/mcp` version that predates this header, will bypass the gate. Pin to a recent release if you rely on the kill-switch as a hard control.
|
||||
:::
|
||||
|
||||
## How it works
|
||||
|
||||

|
||||
|
||||
1. On startup, the MCP server fetches the OpenAPI spec from your XO instance (`/rest/v0/docs/swagger.json`) and generates one tool per resource domain.
|
||||
2. You ask a question in natural language to your AI assistant.
|
||||
3. The assistant picks a tool (e.g. `pools_query`) and chooses an `operation` (e.g. `list`, `dashboard`).
|
||||
4. The MCP server calls the corresponding XO REST endpoint and returns a markdown-formatted response.
|
||||
|
||||
Because the tool surface is generated from the live OpenAPI spec, it always reflects the XO version you're connecting to — new endpoints become available automatically as XO evolves.
|
||||
|
||||
## Available Tools
|
||||
|
||||
### Utility tools
|
||||
|
||||
These three tools are always present regardless of the XO spec.
|
||||
|
||||
#### `check_connection`
|
||||
|
||||
Test the connection to the Xen Orchestra server. Use this to validate your setup before querying infrastructure.
|
||||
|
||||
**Parameters:** None
|
||||
|
||||
**Example question:** "Can you connect to my XO server?"
|
||||
|
||||
---
|
||||
|
||||
#### `get_infrastructure_summary`
|
||||
|
||||
Aggregate pools, hosts, and VMs across the entire infrastructure into a single markdown summary.
|
||||
|
||||
**Parameters:** None
|
||||
|
||||
**Example question:** "Give me an overview of my infrastructure"
|
||||
|
||||
---
|
||||
|
||||
#### `search_documentation`
|
||||
|
||||
Search and retrieve Xen Orchestra documentation. Useful for learning about XO features, configuration, and best practices.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `topic` | enum | Yes | One of: `installation`, `configuration`, `backups`, `restapi`, `manage`, `users`, `architecture`, `troubleshooting`, `releases` |
|
||||
|
||||
**Example question:** "How do I configure backups in XO?"
|
||||
|
||||
### Domain query tools
|
||||
|
||||
Each resource family exposes a single `{domain}_query` tool. Domains come from the spec's primary tag (`tags[0]`) verbatim — no client-side remapping. The MCP layer asks the REST API for a pre-rendered markdown table (`?markdown=true`) and relays the bytes verbatim; there is no client-side formatting.
|
||||
|
||||
All query tools share the same argument shape:
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| ----------- | ------ | ----------- | ------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `operation` | enum | Yes | The OpenAPI `operationId` to invoke. Valid values are listed in the tool description. |
|
||||
| `id` | string | If required | Resource ID (required for single-resource and sub-resource operations) |
|
||||
| `filter` | string | No | [Filter expression](https://docs.xen-orchestra.com/xo5/manage_infrastructure#live-filter-search) for list operations |
|
||||
| `fields` | string | No | Comma-separated fields to return (e.g. `id,name_label`). Passed straight to the REST API; leave empty to get all fields. |
|
||||
| `limit` | number | No | Maximum number of results for list operations |
|
||||
|
||||
Operation names are the `operationId`s emitted by the server (tsoa, PascalCase). Examples:
|
||||
|
||||
| operationId | Endpoint |
|
||||
| ----------------------- | --------------------------------------------- |
|
||||
| `GetPools` | `GET /pools` |
|
||||
| `GetPool` | `GET /pools/{id}` |
|
||||
| `GetPoolDashboard` | `GET /pools/{id}/dashboard` |
|
||||
| `EmergencyShutdownPool` | `POST /pools/{id}/actions/emergency_shutdown` |
|
||||
| `StartVm` | `POST /vms/{id}/actions/start` |
|
||||
| `DeleteVm` | `DELETE /vms/{id}` |
|
||||
| `GetVmAlarms` | `GET /vms/{id}/alarms` |
|
||||
|
||||
Generated domains (on a current xo-server):
|
||||
|
||||
- Compute: `pools_query`, `hosts_query`, `vms_query` (covers VMs, templates, snapshots, controllers — tsoa groups them under `vms` server-side)
|
||||
- Storage: `vdis_query` (includes VDI snapshots), `srs_query`, `vbds_query`, `pbds_query`
|
||||
- Network: `networks_query`, `vifs_query`, `pifs_query`
|
||||
- Backup: `backup_jobs_query`, `backup_logs_query`, `restore_logs_query`, `backup_repositories_query`, `backup_archives_query`, `schedules_query`
|
||||
- Access: `users_query`, `groups_query`, `servers_query`
|
||||
- Observability: `alarms_query`, `messages_query`, `events_query`, `tasks_query`
|
||||
- System: `proxies_query`, `pgpus_query`, `pcis_query`, `sms_query`, `xoa_query`
|
||||
- Misc: `docs_query`
|
||||
|
||||
**Example questions:**
|
||||
|
||||
- "List all my pools" → `pools_query` with `operation: GetPools`
|
||||
- "Show the dashboard for pool X" → `pools_query` with `operation: GetPoolDashboard, id: X`
|
||||
- "How many VMs are currently running?" → `vms_query` with `operation: GetVms, filter: power_state:Running`
|
||||
- "List user VDIs larger than 100GB" → `vdis_query` with `operation: GetVdis, filter: VDI_type:User`
|
||||
- "Show all XCP-ng hosts" → `hosts_query` with `operation: GetHosts, filter: productBrand:XCP-ng`
|
||||
|
||||
**Configuration env vars:**
|
||||
|
||||
| Env var | Effect |
|
||||
| ----------------------- | ------------------------------------------------------------------------------------ |
|
||||
| `XO_MCP_ENABLE_ACTIONS` | Set to `1` to expose write operations (`{domain}_action` tools). Default: read-only. |
|
||||
| `XO_MCP_DENY_LIST` | Comma-separated `operationId`s to drop entirely, e.g. `DeleteVm,HardShutdownVm`. |
|
||||
|
||||
:::note Excluded endpoints
|
||||
Stats endpoints (`/…/stats`) and binary downloads (`.xva`, `.ova`, `.raw`, `.vhd`, `.{format}`, …) are deliberately not exposed as MCP tools: their payloads are unsuitable for LLM context. Hit the REST API directly when you need them.
|
||||
:::
|
||||
|
||||
### Write operations
|
||||
|
||||
By default, the MCP server only exposes read-only tools. Set `XO_MCP_ENABLE_ACTIONS=1` in the server environment to also expose `{domain}_action` tools covering POST/PUT/PATCH/DELETE operations.
|
||||
|
||||
Action tools share this argument shape:
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------------- | ------ | ---------------- | ------------------------------------------------------------------------------------------ |
|
||||
| `operation` | enum | Yes | The `operationId` of the action to perform (e.g. `StartVm`, `DeleteVm`, `HardShutdownVm`). |
|
||||
| `id` | string | For most actions | Target resource ID |
|
||||
| `body` | object | No | Request body for create/update operations |
|
||||
| `confirm_token` | string | Yes, for actions | One-shot token from a prior preview call; required to run an action |
|
||||
|
||||
**Confirmation flow.** Every action runs as a two-step handshake. The first call returns a preview (method, path, body) and a one-shot `confirm_token`; the assistant must call back with that token within 5 minutes to execute. A blunt "yes, delete everything" can't go through in one shot, so an accidental or hallucinated call stops at the preview. Use `XO_MCP_DENY_LIST` to drop specific operations from the surface entirely when you don't want them offered at all.
|
||||
|
||||
:::warning Only enable actions if you trust the caller
|
||||
Enabling `XO_MCP_ENABLE_ACTIONS` lets the assistant mutate your infrastructure. The confirm-token handshake means no action runs without a second, explicit call, but it's still write access. Keep the default read-only mode unless you have a specific need.
|
||||
:::
|
||||
|
||||
## Prompts
|
||||
|
||||
The MCP server also provides a built-in prompt:
|
||||
|
||||
### `infrastructure-overview`
|
||||
|
||||
Generates a natural language overview of the XO infrastructure. When invoked, the assistant calls `get_infrastructure_summary` and formats the results as a readable summary.
|
||||
|
||||
## Example Conversations
|
||||
|
||||
**Infrastructure overview:**
|
||||
|
||||

|
||||
|
||||
**Searching documentation:**
|
||||
|
||||

|
||||
|
||||
## Troubleshooting
|
||||
|
||||
:::note Connection refused
|
||||
Verify that `XO_URL` is correct and includes the protocol (`https://` or `http://`). Make sure the XO server is reachable from the machine running the MCP server.
|
||||
:::
|
||||
|
||||
:::note Authentication failed (401)
|
||||
If using token authentication, check that `XO_TOKEN` is valid — the token may have expired or been revoked. If using username/password, check `XO_USERNAME` and `XO_PASSWORD`. Only admin users can currently access the REST API.
|
||||
:::
|
||||
|
||||
:::note Timeout errors
|
||||
The MCP server has a 30-second timeout for API requests. If you experience timeouts, check network connectivity between the MCP server and your XO instance.
|
||||
:::
|
||||
|
||||
:::note Internal XOA blocked when behind a corporate proxy
|
||||
If your AI assistant injects `HTTPS_PROXY` into the MCP process and your XOA lives on the internal network, the proxy may silently drop or reject the requests. Add the XOA hostname (and any internal CIDR ranges) to `NO_PROXY` so the traffic stays direct. See [Behind a corporate proxy](#behind-a-corporate-proxy).
|
||||
:::
|
||||
|
||||
:::note Missing required environment variables
|
||||
`XO_URL` is always required. You must also set either `XO_TOKEN` or both `XO_USERNAME` and `XO_PASSWORD`. When using Claude Desktop, make sure they are in the `env` section of the MCP server configuration.
|
||||
:::
|
||||
|
||||
:::note MCP disabled by admin
|
||||
The xo-server administrator has set `[mcp] enabled = false` in the server config. The binary won't start until that flag is removed or set back to `true`. See [Disabling MCP globally](#disabling-mcp-globally) for the server-side details.
|
||||
:::
|
||||
|
||||
:::note
|
||||
**Unable to verify MCP status (HTTP 404)**
|
||||
Your Xen Orchestra is older than **6.5**. Upgrade XO to 6.5 or later to use the MCP server, see [Prerequisites](#prerequisites).
|
||||
:::
|
||||
@@ -1,28 +1,62 @@
|
||||
# Metadata backup
|
||||
|
||||
XCP-ng and Citrix Hypervisor (Xenserver) hosts use a database to store metadata about VMs and their associated resources such as storage and networking. Metadata forms this complete view of all VMs available on your pool. Backing up the metadata of your pool allows you to recover from a physical hardware failure scenario in which you lose your hosts without losing your storage (SAN, NAS...).
|
||||
Every XCP-ng or XenServer pool keeps a database, the XAPI database, describing everything that isn't the data itself: VMs and their settings, storage repositories, networks, and how they all fit together. Xen Orchestra has an equivalent of its own: its configuration, holding users, authorizations and resource sets, backup jobs, and plugin settings.
|
||||
|
||||
In Xen Orchestra, Metadata backup is divided into two different options:
|
||||
Metadata backup protects both layers, with two backup kinds you can enable independently or together in a single job:
|
||||
|
||||
- **Pool metadata backup** - Backup metadata of your physical XCP-ng host: VMs, storage repositories, networks, etc.
|
||||
- **XO configuration backup:** - Backup metadata of your Xen Orchestra instance: Users, authorizations and ressource sets, backup job settings, hosts and plugin settings, etc.
|
||||
- **Pool metadata backup**: a dump of the pool's XAPI database (VMs, SRs, networks, etc.).
|
||||
- **XO config backup**: the configuration of your Xen Orchestra instance itself.
|
||||
|
||||
This is the backup that saves you when the hardware dies but the storage survives: reinstall a host, restore the pool metadata, and the pool knows about its VMs and SRs again. Likewise, if you lose your XOA, restoring the XO config brings back your users, jobs, and settings without rebuilding them by hand.
|
||||
|
||||
<Schema label="Metadata backup: XO dumps the pool's XAPI database and exports its own config to the BR" legend={[["#8e83fe", "Pool"], ["#6aabf0", "XO"], ["#e0a94a", "Backup repository"]]} maxWidth="640px">
|
||||
<svg viewBox="0 0 640 220" role="img" aria-label="A pool's XAPI database and Xen Orchestra's own configuration both flow into the backup repository, with Xen Orchestra driving the backup">
|
||||
<text x="32" y="46" fill="#8e83fe" fontSize="12">Pool</text>
|
||||
<rect x="24" y="54" width="180" height="120" rx="10" fill="none" stroke="rgba(255,255,255,0.22)" strokeDasharray="6 5" />
|
||||
<rect x="44" y="86" width="140" height="52" rx="6" fill="rgba(255,255,255,0.04)" stroke="#8e83fe" />
|
||||
<text x="114" y="109" fill="#c6d2e1" fontSize="12" textAnchor="middle">XAPI database</text>
|
||||
<text x="114" y="125" fill="#7a8699" fontSize="10" textAnchor="middle">VMs, SRs, networks</text>
|
||||
<rect x="260" y="60" width="130" height="108" rx="8" fill="rgba(255,255,255,0.04)" stroke="#6aabf0" />
|
||||
<text x="325" y="92" fill="#c6d2e1" fontSize="12" textAnchor="middle">Xen Orchestra</text>
|
||||
<text x="325" y="126" fill="#7a8699" fontSize="10" textAnchor="middle">XO config:</text>
|
||||
<text x="325" y="140" fill="#7a8699" fontSize="10" textAnchor="middle">users, jobs,</text>
|
||||
<text x="325" y="154" fill="#7a8699" fontSize="10" textAnchor="middle">settings, plugins</text>
|
||||
<line x1="184" y1="112" x2="250" y2="112" stroke="#8e83fe" strokeWidth="1.5" className="schema-flow" strokeDasharray="5 4" />
|
||||
<polygon points="258,112 249,107 249,117" fill="#8e83fe" />
|
||||
<text x="222" y="100" fill="#8e83fe" fontSize="10" textAnchor="middle">dump</text>
|
||||
<line x1="390" y1="114" x2="466" y2="114" stroke="#e0a94a" strokeWidth="1.5" className="schema-flow" strokeDasharray="5 4" />
|
||||
<polygon points="474,114 465,109 465,119" fill="#e0a94a" />
|
||||
<text x="428" y="102" fill="#e0a94a" fontSize="10" textAnchor="middle">export</text>
|
||||
<text x="482" y="46" fill="#c6d2e1" fontSize="12">Backup repository (BR)</text>
|
||||
<rect x="474" y="54" width="146" height="120" rx="10" fill="none" stroke="rgba(255,255,255,0.22)" strokeDasharray="6 5" />
|
||||
<rect x="490" y="72" width="114" height="38" rx="6" fill="rgba(255,255,255,0.04)" stroke="#e0a94a" />
|
||||
<text x="547" y="95" fill="#c6d2e1" fontSize="11" textAnchor="middle">pool metadata</text>
|
||||
<rect x="490" y="122" width="114" height="38" rx="6" fill="rgba(255,255,255,0.04)" stroke="#e0a94a" />
|
||||
<text x="547" y="145" fill="#c6d2e1" fontSize="11" textAnchor="middle">XO config</text>
|
||||
</svg>
|
||||
</Schema>
|
||||
|
||||
:::note
|
||||
In the XO 5 interface, backup repositories are still labeled **Remotes**.
|
||||
:::
|
||||
|
||||
## Performing a backup
|
||||
|
||||
In the backup job section, when creating a new backup job, you will now have a choice between backing up VMs and backing up Metadata:
|
||||

|
||||
In **Backup → New**, choose what kind of job you want to create: backing up VMs, or backing up metadata.
|
||||
|
||||
When you select Metadata backup, you will have a new backup job screen, letting you choose between a pool metadata backup and an XO configuration backup (or both at the same time):
|
||||
<UiDetail src="/img/xo5/metadata-backup-type.png" alt="Backup type choice between Backup VMs and Backup metadata" width={620} />
|
||||
|
||||

|
||||
Selecting **Backup metadata** opens a dedicated job form. Toggle **Pool metadata**, **XO config**, or both at the same time, then pick the pools to cover and the target BR.
|
||||
|
||||
Define the name and retention for the job.
|
||||
<UiDetail src="/img/xo5/metadata-job-form.png" alt="Metadata backup job form with Pool metadata and XO config toggles, target remotes, pools and schedules" width={700} />
|
||||
|
||||

|
||||
Each schedule has its own name and retention, one for pool metadata backups and one for XO config backups. At least one retention must be higher than 0.
|
||||
|
||||
Once created, the job is displayed with the other classic jobs.
|
||||
<UiDetail src="/img/xo5/metadata-schedule-retention.png" alt="Schedule modal with name, pool retention and XO retention fields" width={620} />
|
||||
|
||||

|
||||
Once saved, the job shows up alongside your other backup jobs, with its modes listed (Pool metadata, XO config).
|
||||
|
||||
<UiDetail src="/img/xo5/metadata-job-list.png" alt="Schedules list showing a metadata job with Pool metadata and XO config modes next to a regular backup job" width={700} />
|
||||
|
||||
## Performing a restore
|
||||
|
||||
@@ -30,16 +64,16 @@ Once created, the job is displayed with the other classic jobs.
|
||||
Restoring pool metadata completely overwrites the XAPI database of a host. Only perform a metadata restore if it is a new server with nothing running on it (eg replacing a host with new hardware).
|
||||
:::
|
||||
|
||||
If you browse to the Backup NG Restore panel, you will now notice a Metadata filter button:
|
||||
Go to **Backup → Restore** and click the **Metadata** filter button: the list switches to the metadata backups available for restore, both XO config backups and pool metadata backups.
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/metadata-restore-list.png" alt="Restore view filtered on metadata, listing a Xen Orchestra config backup and a pool metadata backup" width={620} />
|
||||
|
||||
If you click this button, it will show you Metadata backups available for restore:
|
||||
To restore one, click the blue restore arrow on its row, choose the backup date to restore, and click **OK**.
|
||||
|
||||

|
||||
|
||||
You can see both our Xen Orchestra config backup, and our pool metadata backup. To restore one, simply click the blue restore arrow, choose a backup date to restore, and click OK:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/metadata-restore-modal.png" alt="Restore XO metadata modal with a backup date selector" width={480} />
|
||||
|
||||
That's it!
|
||||
|
||||
:::tip
|
||||
Metadata backup is one half of protecting your orchestration layer: the other half is keeping the XOA itself recoverable. See [How to ensure XOA is always available](../backup_howto.md#how-to-ensure-xoa-is-always-available).
|
||||
:::
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
# Migrate to new XOA
|
||||
|
||||
### Deploy new appliance
|
||||
|
||||
First step, you have to deploy a new appliance. All necessary information can be found in [installation](installation.md).
|
||||
|
||||
### Export configuration
|
||||
|
||||
To export your current configuration, navigate to **Settings** -> **Config**.
|
||||
Here you will see a button labeled **_Download current config_**. Click on it, then an export modal will appear.
|
||||
|
||||

|
||||
|
||||
You can set a passphrase to encrypt the exported configuration.
|
||||
|
||||
### Import configuration
|
||||
|
||||
Now it's time to import your configuration to the new appliance.
|
||||
Go to the **Settings** → **Config** page of your new appliance. Here, you have an **_import_** section where you can drag and drop your exported configuration file.
|
||||
|
||||

|
||||
|
||||
When your configuration is loaded, click to import. A new modal will appear to ask you the passphrase to decrypt your configuration. If you didn't set a passphrase when you exported your configuration, leave it empty.
|
||||
|
||||
### Advanced users
|
||||
|
||||
If you made custom adjustments to the `/etc/xo-server/config.toml` config file on your previous appliance, unfortunately you will have to recreate these modifications on the new appliance.
|
||||
@@ -1,105 +0,0 @@
|
||||
# Mirror Backups
|
||||
|
||||
The goal is to replicate a backup from one remote to another. For instance, you make your backup to in-house NFS storage, and then replicate to bigger, slower and cheaper storage with a longer retention.
|
||||
|
||||
The source and destination can have different settings for encryption, VHD storage mode, retention, or compression.
|
||||
|
||||
## Creation
|
||||
|
||||
Just go into your "Backup" view, and select Vm Mirror Backup.
|
||||
Then, select if you want to mirror incremental backups or full backups.
|
||||
You must have exactly one source remote, you must have one or more destinations. The mirroring speed will be limited by the slower remote.
|
||||
|
||||
Most options of the full/incremental backups applies here, like concurrency (number of VM transferred in parallel), report, proxy and speed limit. You can also add a health check on schedules. Please note that only the last transferred backup (if any) will be checked.
|
||||
|
||||
:::tip
|
||||
If you have full and incremental backups on a remote, you must configure 2 mirror backup jobs, one full and one incremental.
|
||||
:::
|
||||
|
||||
## synchronizing algorithm for full backups
|
||||
|
||||
Any new backup on the source is transferred to the remote
|
||||
|
||||
_key backup(full) are in upper case, delta backup are in lowercase_ . _Source has a retention of 3, destination has 4_
|
||||
|
||||
### First transfer
|
||||
|
||||
```
|
||||
- source : ABC
|
||||
- destination: empty
|
||||
```
|
||||
|
||||
will transfer in order A , then B, and C. Destination will contains ABC
|
||||
|
||||
> **Limitation:** if the mirror retention is lower than the backup retention on the source remote, more data than necessary may be transferred during the first run, since all the backups of the source will be transferred to the destinations. Then the older backups will be purged on the destinations.
|
||||
|
||||
### Second transfer
|
||||
|
||||
```
|
||||
- source : BCD
|
||||
- destination: ABC
|
||||
```
|
||||
|
||||
will transfer D. Destination will contains ABCD
|
||||
|
||||
### Third transfer
|
||||
|
||||
```
|
||||
- source : CDE
|
||||
- destination: ABCD
|
||||
```
|
||||
|
||||
will transfer E and delete A from remote. Destination will contains BCDE
|
||||
|
||||
### if there is too much change on source
|
||||
|
||||
```
|
||||
- source : IJK
|
||||
- destination: BCDE
|
||||
```
|
||||
|
||||
will transfer in order IJK and delete BCD from remote. Destination will contains EIJK
|
||||
|
||||
## Synchronizing algorithm for incremental backups
|
||||
|
||||
this will only transfer new backups, and then run the same merge algorithm than in [Incremental Backups](incremental_backups.md).
|
||||
|
||||
_key backup(full) are in upper case, delta backup are in lowercase_ . _Source has a retention of 3, destination has 4_
|
||||
|
||||
### First transfer
|
||||
|
||||
```
|
||||
- source : Abc # one key, two delta
|
||||
- destination: empty
|
||||
```
|
||||
|
||||
will transfer in order A , then b, and c. Destination will contains Abc
|
||||
|
||||
> **Limitation:** if the mirror retention is lower than the backup retention on the source remote, more data than necessary may be transferred during the first run, since all the backups of the source will be transferred to the destinations. Then the older backups will be purged on the destinations.
|
||||
|
||||
### Second transfer
|
||||
|
||||
```
|
||||
- source : Bcd # A and b have been merged
|
||||
- destination: Abc
|
||||
```
|
||||
|
||||
transfer only the delta d , destination will contains Abcd (no merge)
|
||||
|
||||
### Third transfer
|
||||
|
||||
```
|
||||
- source : Cde # B and c have been merged
|
||||
- destination: Abcd
|
||||
```
|
||||
|
||||
transfer only the delta e , destination will contains Bcde (merge A into b)
|
||||
|
||||
### if there is too much change on source
|
||||
|
||||
```
|
||||
- source : Ijk
|
||||
- destination: Bcde
|
||||
```
|
||||
|
||||
transfer all the chain in order, destination will contains EIjk (merge B,c and d into e)
|
||||
+90
-40
@@ -1,101 +1,151 @@
|
||||
---
|
||||
sidebar_label: Backup proxies
|
||||
---
|
||||
|
||||
# Backup Proxy
|
||||
|
||||
A Xen Orchestra proxy is an architecture component you can deploy in your infrastructure in order to locally handle the data streams of your backup jobs.
|
||||
The most current situation in which you might wish to use a XO proxy are:
|
||||
A Xen Orchestra proxy is a small appliance you deploy in your infrastructure to handle the data streams of your backup jobs locally, while your main Xen Orchestra appliance (XOA) keeps orchestrating everything. The two most common reasons to use a proxy are:
|
||||
|
||||
- To handle backup data streams in large infrastructure to avoid saturation of the main appliance and split the workload
|
||||
- To handle backup data streams in remote infrastructure to avoid useless back and forth from the main XOA to the remote location
|
||||
- **Large infrastructure**: spread the backup workload across several appliances and avoid saturating the main XOA
|
||||
- **Remote sites**: keep backup data inside the remote site and avoid a useless round trip across the WAN to the main XOA
|
||||
|
||||
## Architecture
|
||||
|
||||

|
||||
Without a proxy, the main XOA handles every data stream itself. For a remote site, that means the VM export travels all the way to the main XOA, only to be sent right back to a backup repository (BR) sitting next to the pool it came from. With a proxy deployed on the remote site, the data never leaves the site: the proxy exports the VMs and writes to the local BR, and only lightweight control traffic crosses the WAN.
|
||||
|
||||

|
||||
<Schema label="Without a proxy, backup data from a remote pool crosses the WAN twice to reach a BR located on the same remote site; with a proxy deployed there, the data stays local and only control traffic crosses the WAN" legend={[["#6aabf0", "XOA / XO Proxy"], ["#8e83fe", "XCP-ng pool"], ["#5ac8c8", "backup data"], ["#e0a94a", "backup repository (BR)"]]} maxWidth="640px">
|
||||
<svg viewBox="0 0 640 476" role="img" aria-label="Two panels compare backup traffic. Without a proxy, the VM export from the remote XCP-ng pool crosses the WAN to the main XOA, which sends the backup data back across the WAN to the backup repository on the remote site: the same data crosses the WAN twice. With a proxy deployed on the remote site, backup data flows locally from the pool through the XO Proxy to the backup repository, and only control traffic crosses the WAN between XOA and the proxy">
|
||||
<text x="16" y="28" fill="#c6d2e1" fontSize="12.5">Without a proxy</text>
|
||||
<rect x="16" y="44" width="170" height="168" rx="8" fill="none" stroke="rgba(255,255,255,0.22)" strokeDasharray="6 5" />
|
||||
<text x="28" y="64" fill="#c6d2e1" fontSize="12">Main site</text>
|
||||
<rect x="44" y="96" width="112" height="64" rx="6" fill="rgba(255,255,255,0.04)" stroke="#6aabf0" />
|
||||
<text x="100" y="124" fill="#c6d2e1" fontSize="12" textAnchor="middle">XOA</text>
|
||||
<text x="100" y="140" fill="#7a8699" fontSize="10" textAnchor="middle">main appliance</text>
|
||||
<text x="243" y="64" fill="#7a8699" fontSize="11" textAnchor="middle">WAN</text>
|
||||
<rect x="300" y="44" width="324" height="168" rx="8" fill="none" stroke="rgba(255,255,255,0.22)" strokeDasharray="6 5" />
|
||||
<text x="312" y="64" fill="#c6d2e1" fontSize="12">Remote site</text>
|
||||
<rect x="316" y="84" width="108" height="40" rx="6" fill="rgba(255,255,255,0.04)" stroke="#8e83fe" />
|
||||
<text x="370" y="108" fill="#c6d2e1" fontSize="11" textAnchor="middle">XCP-ng pool</text>
|
||||
<rect x="492" y="124" width="116" height="40" rx="6" fill="rgba(255,255,255,0.04)" stroke="#e0a94a" />
|
||||
<text x="550" y="143" fill="#c6d2e1" fontSize="12" textAnchor="middle">BR</text>
|
||||
<text x="550" y="157" fill="#7a8699" fontSize="9" textAnchor="middle">backup repository</text>
|
||||
<line x1="316" y1="104" x2="166" y2="104" stroke="#5ac8c8" className="schema-flow" strokeDasharray="5 4" />
|
||||
<polygon points="156,104 166,99 166,109" fill="#5ac8c8" />
|
||||
<text x="243" y="96" fill="#5ac8c8" fontSize="10" textAnchor="middle">1. VM export</text>
|
||||
<line x1="156" y1="144" x2="482" y2="144" stroke="#5ac8c8" className="schema-flow" strokeDasharray="5 4" />
|
||||
<polygon points="492,144 482,139 482,149" fill="#5ac8c8" />
|
||||
<text x="243" y="160" fill="#5ac8c8" fontSize="10" textAnchor="middle">2. backup data</text>
|
||||
<text x="320" y="232" fill="#ef6a5f" fontSize="10.5" textAnchor="middle">the same backup data crosses the WAN twice</text>
|
||||
<line x1="16" y1="250" x2="624" y2="250" stroke="rgba(255,255,255,0.12)" />
|
||||
<text x="16" y="278" fill="#c6d2e1" fontSize="12.5">With a proxy</text>
|
||||
<rect x="16" y="294" width="170" height="168" rx="8" fill="none" stroke="rgba(255,255,255,0.22)" strokeDasharray="6 5" />
|
||||
<text x="28" y="314" fill="#c6d2e1" fontSize="12">Main site</text>
|
||||
<rect x="44" y="330" width="112" height="56" rx="6" fill="rgba(255,255,255,0.04)" stroke="#6aabf0" />
|
||||
<text x="100" y="354" fill="#c6d2e1" fontSize="12" textAnchor="middle">XOA</text>
|
||||
<text x="100" y="370" fill="#7a8699" fontSize="10" textAnchor="middle">main appliance</text>
|
||||
<text x="243" y="314" fill="#7a8699" fontSize="11" textAnchor="middle">WAN</text>
|
||||
<line x1="156" y1="351" x2="482" y2="404" stroke="#7a8699" strokeDasharray="3 4" />
|
||||
<text x="243" y="352" fill="#7a8699" fontSize="9.5" textAnchor="middle">control traffic only</text>
|
||||
<rect x="300" y="294" width="324" height="168" rx="8" fill="none" stroke="rgba(255,255,255,0.22)" strokeDasharray="6 5" />
|
||||
<text x="312" y="314" fill="#c6d2e1" fontSize="12">Remote site</text>
|
||||
<rect x="316" y="400" width="104" height="40" rx="6" fill="rgba(255,255,255,0.04)" stroke="#8e83fe" />
|
||||
<text x="368" y="424" fill="#c6d2e1" fontSize="10.5" textAnchor="middle">XCP-ng pool</text>
|
||||
<rect x="444" y="404" width="76" height="32" rx="6" fill="rgba(106,171,240,0.10)" stroke="#6aabf0" />
|
||||
<text x="482" y="424" fill="#c6d2e1" fontSize="10.5" textAnchor="middle">XO Proxy</text>
|
||||
<rect x="544" y="400" width="64" height="40" rx="6" fill="rgba(255,255,255,0.04)" stroke="#e0a94a" />
|
||||
<text x="576" y="424" fill="#c6d2e1" fontSize="12" textAnchor="middle">BR</text>
|
||||
<line x1="420" y1="420" x2="434" y2="420" stroke="#5ac8c8" className="schema-flow" strokeDasharray="5 4" />
|
||||
<polygon points="444,420 435,415.5 435,424.5" fill="#5ac8c8" />
|
||||
<line x1="520" y1="420" x2="534" y2="420" stroke="#5ac8c8" className="schema-flow" strokeDasharray="5 4" />
|
||||
<polygon points="544,420 535,415.5 535,424.5" fill="#5ac8c8" />
|
||||
<text x="462" y="456" fill="#5ac8c8" fontSize="10" textAnchor="middle">backup data stays on the remote site</text>
|
||||
</svg>
|
||||
</Schema>
|
||||
|
||||
## Deployment
|
||||
|
||||
### Prerequisites
|
||||
|
||||
To deploy a Xen Orchestra proxy, you need to have an available proxy license. To purchase a license, you simply need to visit [our store](https://xen-orchestra.com/#!/member/purchaser) and follow the purchasing process.
|
||||
Each deployed proxy needs its own proxy license: see [Pricing and available add-ons](https://docs.vates.tech/pricing-licencing/pricing-addons/) in the Vates docs. If you have an unused license on your account, it will be bound automatically to the proxy at deployment time.
|
||||
|
||||
### Minimum Requirements
|
||||
|
||||
XO proxies require the following resources:
|
||||
|
||||
- 2 vCPUs
|
||||
- 2GiB RAM
|
||||
- 20GiB disk (2GiB on thin pro SR)
|
||||
- 2 GiB RAM
|
||||
- 20 GiB disk (2 GiB on a thin provisioned SR)
|
||||
|
||||
### Installation
|
||||
|
||||
1. Go to the proxies section of your appliance
|
||||
1. Go to the **Proxies** section of your appliance:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/proxy-section.png" alt="The Proxies entry in the XOA main menu" width={175} />
|
||||
|
||||
2. Deploy a proxy in your infrastructure
|
||||
2. Click **Deploy a proxy**:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/proxy-deploy-form.png" alt="The Deploy a proxy button in the Proxies view, with no proxies deployed yet" width={291} />
|
||||
|
||||
3. Perform all the required configuration for your proxy (SR, network...)
|
||||
3. Choose where the proxy VM will live: destination SR, destination network and network configuration (DHCP or static):
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/proxy-first-config.png" alt="The Deploy a proxy modal asking for a destination SR, a destination network and the network configuration" width={602} />
|
||||
|
||||
4. If you have an available license, it will be automatically bound to your newly deployed proxy.
|
||||
|
||||
## Proxy Remote creation
|
||||
## Backup repository through a proxy {#proxy-remote-creation}
|
||||
|
||||
Once a proxy is deployed in your infrastructure, you can create a proxy remote using the remote form.
|
||||
Once a proxy is deployed in your infrastructure, you can create a backup repository (BR) handled by that proxy, using the usual form (still labeled _Remotes_ in XO 5). Simply pick the proxy in the **Proxy** selector: the proxy will mount the BR itself and handle all data streams to it.
|
||||
|
||||

|
||||

|
||||
<UiDetail src="/img/xo5/proxy-remote-form.png" alt="The New file system remote form with an NFS type and Proxy 1 selected in the proxy field" width={700} />
|
||||
|
||||
The proxy handling each BR is then visible in the _Remotes_ list:
|
||||
|
||||
<UiDetail src="/img/xo5/proxy-remote-select.png" alt="The Remotes list showing an enabled BR with Proxy 1 displayed in its Proxy column" width={700} />
|
||||
|
||||
## Backup job with Proxies
|
||||
|
||||
While creating a standard backup job from your main Xen Orchestra appliance, you will have the ability to select a proxy on which you want to execute the job.
|
||||
While creating a standard backup job from your main Xen Orchestra appliance, you can select a proxy in the job settings: the proxy will then execute the job and handle its data streams instead of the main appliance.
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/proxy-job-select.png" alt="The backup job Settings panel with Proxy 1 selected in the Proxy field" width={700} />
|
||||
|
||||
:::tip
|
||||
If you see this error: `The backup will not be run on this remote because it's not compatible with the selected proxy`, it means the selected remote is not accessible from the proxy or mounted on the proxy that you have selected for the job.
|
||||
If you see this error: `The backup will not be run on this remote because it's not compatible with the selected proxy`, it means the selected BR is not handled by the proxy chosen for the job. A proxy can only write to BRs that are bound to it, so either bind that BR to the same proxy, or pick a BR that already is.
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/remote_not_compatible_with_proxy.png" alt="A backup job form showing the error tooltip: the backup will not be run on this remote because it's not compatible with the selected proxy" width={700} />
|
||||
:::
|
||||
|
||||
## Enabling login to a proxy appliance
|
||||
|
||||
Login is disabled by default on proxy appliances.
|
||||
If you need to login for some reason, you need to set a password for the xoa user via the XenStore of the VM. The following is to be ran on your XCP-ng host:
|
||||
If you need to login for some reason, you need to set a password for the `xoa` user via the XenStore of the VM. Run the following on your XCP-ng host, where `UUID` is the UUID of your proxy VM:
|
||||
|
||||
```sh
|
||||
<Terminal shell title="XCP-ng host: set a password for the xoa user">{`
|
||||
xe vm-param-set uuid=<UUID> xenstore-data:vm-data/system-account-xoa-password=<password>
|
||||
```
|
||||
`}</Terminal>
|
||||
|
||||
Where UUID is the uuid of your proxy VM.
|
||||
|
||||
Then you need to restart the proxy VM.
|
||||
You can now login through SSH with the `xoa` username and password you defined in the previous command.
|
||||
Then restart the proxy VM.
|
||||
You can now login through SSH with the `xoa` username and the password you defined in the previous command.
|
||||
|
||||
## Adding a network card to a Proxy
|
||||
|
||||
First you will need to add a second VIF to your Proxy VM. This can be done in the Network tab of the VM in XOA.
|
||||
First you will need to add a second VIF to your proxy VM. This can be done in the Network tab of the VM in XOA.
|
||||
|
||||
After adding the VIF you will need to set an IP for the new NIC, for that you will first need to SSH to the VM [as describe before](#enabling-login-to-a-proxy-appliance).
|
||||
After adding the VIF, you will need to set an IP address for the new NIC. To do so, SSH to the VM [as described before](#enabling-login-to-a-proxy-appliance).
|
||||
|
||||
Then set the new IP:
|
||||
If you want a static address:
|
||||
|
||||
```console
|
||||
$ xoa network static eth1
|
||||
<Terminal title="proxy VM: set a static IP on eth1">{`
|
||||
xoa network static eth1
|
||||
? Static IP for this machine 192.168.100.120
|
||||
? Network mask (eg 255.255.255.0) 255.255.255.0
|
||||
```
|
||||
`}</Terminal>
|
||||
|
||||
If you want to set a static address.
|
||||
If you prefer using DHCP:
|
||||
|
||||
```sh
|
||||
<Terminal shell title="proxy VM: configure eth1 through DHCP">{`
|
||||
xoa network dhcp eth1
|
||||
```
|
||||
`}</Terminal>
|
||||
|
||||
If you prefer using DHCP.
|
||||
:::tip
|
||||
As XOA uses the first IP address reported by XAPI to contact the proxy appliance, you may have to switch the network card order if you want your proxy to be connected through a specific IP address.
|
||||
:::
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
# Releases
|
||||
|
||||
Xen Orchestra is distributed in 2 ways:
|
||||
|
||||
1. Through XOA
|
||||
2. "as is" from GitHub
|
||||
|
||||
XOA (**X**en **O**rchestra virtual **A**ppliance) is the pre-installed VM with:
|
||||
|
||||
- everything ready to work
|
||||
- complete QA (tested) to guarantee it will work
|
||||
- a web updater
|
||||
- bundled remote support capabilities
|
||||
- extra services (XO Hub, XO Recipes, Advanced metrics, XOSAN…)
|
||||
- secured system (sudo, firewall)
|
||||
|
||||
It's really trivial to deploy it, as you can see [in the XOA install section](installation.md#xoa).
|
||||
|
||||
:::tip
|
||||
In any case, we suggest that you try XOA first, regardless your future usage. It's the easiest way to test everything!
|
||||
:::
|
||||
|
||||
## XOA updates
|
||||
|
||||
See the [updates dedicated section](updater.md) to learn how to keep your XOA up to date.
|
||||
|
||||
## GitHub updates
|
||||
|
||||
If you decide to install it [from the sources](installation.md#from-the-sources), please **always** try to stick to `master` as possible. Before opening any bug report or topic on the forum, update to the latest commit.
|
||||
|
||||
Because you cloned the repository on `master`, just `git pull`!
|
||||
|
||||
:::warning
|
||||
There's no community support on XO installations that aren't up to date to `master`.
|
||||
:::
|
||||
@@ -1,537 +0,0 @@
|
||||
# REST API
|
||||
|
||||
We originally developed [our existing API](architecture.md#api) to be used between the Web UI `xo-web` and the server backend, `xo-server`. That's why it's a JSON-RPC API connected via websockets, allowing us to update objects live in the browser. This is perfect for our usage, but a bit complicated for others.
|
||||
|
||||
Also, this API wasn't meant to be public, but over the years some users have expressed a desire to be able to use it for their own purposes. This led us to add more tooling around it, like `xo-cli` and to answer specific requests.
|
||||
|
||||
For these reasons we decided to build a new API. Not an evolution of the current one, but 100% new. It is meant to be public and [REST-like](https://en.wikipedia.org/wiki/Representational_state_transfer). So a simple curl command can request it.
|
||||
|
||||
While it's not yet at feature parity with the JSON-RPC API, you can explore all available endpoints through the [autogenerated Swagger documentation](./restapi.md#openapiswagger) included in your Xen Orchestra instance. Our goal is to make the REST API the main interface in the future, so it's the most future-proof choice going forward.
|
||||
|
||||
## Versioning
|
||||
|
||||
Our REST API is versioned, and the current version is `/v0` (see URL format below). Since this is the first version, we’ve made efforts to avoid breaking changes, but they may still happen. If a major change is required, we’ll release a new version (e.g., `/v1`) while keeping `/v0` available to minimize the impact.
|
||||
|
||||
## Authentication
|
||||
|
||||
Most endpoints require authentication. For this, you can either attach a valid authentication token as a cookie, or use the [Authorization header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Authorization)
|
||||
|
||||
:::tip
|
||||
Admin users have access to all REST API endpoints. Non-admin users can use the REST API according to the [ACL v2 / RBAC](../xo6/acl-v2.md) permissions defined on their account.
|
||||
:::
|
||||
|
||||
### Usage
|
||||
|
||||
```http
|
||||
GET /rest/v0/vms HTTP/1.1
|
||||
Cookie: authenticationToken=TN2YBOMYtXB_hHtf4wTzm9p5tTuqq2i15yeuhcz2xXM
|
||||
```
|
||||
|
||||
```http
|
||||
GET /rest/v0/vms HTTP/1.1
|
||||
Authorization: Basic YWRtaW5AYWRtaW4ubmV0OmFkbWlu
|
||||
```
|
||||
|
||||
The server will respond to an invalid token or invalid Basic token with a `401 Unauthorized` status.
|
||||
|
||||
Usage with cURL:
|
||||
|
||||
```bash
|
||||
curl -b \
|
||||
authenticationToken=KQxQdm2vMiv7jBIK0hgkmgxKzemd8wSJ7ugFGKFkTbs \
|
||||
https://xo.company.lan/rest/v0/vms
|
||||
```
|
||||
|
||||
### Creation
|
||||
|
||||
To create an authentication token, you can use:
|
||||
|
||||
- `POST /rest/v0/users/:id/authentication_tokens`
|
||||
|
||||
:::tip
|
||||
If you don't know your user ID, you can use the `me` alias. (`/rest/v0/users/me/authentication_tokens`)
|
||||
:::
|
||||
|
||||
```bash
|
||||
$ curl -X POST \
|
||||
https://xoa.company.lan/rest/v0/users/e531b8c9-3876-4ed9-8fd2-0476d5f825c9/authentication_tokens \
|
||||
-u [email protected]:admin
|
||||
```
|
||||
|
||||
```bash
|
||||
$ curl -X POST \
|
||||
https://xoa.company.lan/rest/v0/users/e531b8c9-3876-4ed9-8fd2-0476d5f825c9/authentication_tokens \
|
||||
-b authenticationToken=KQxQdm2vMiv7jBIK0hgkmgxKzemd8wSJ7ugFGKFkTbs
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"token": {
|
||||
"created_at": 1765187444219,
|
||||
"id": "UlTBEnFeL12XocK-7Qx-DKvOYbPn0eG7Z2oMvOniNjg",
|
||||
"user_id": "e531b8c9-3876-4ed9-8fd2-0476d5f825c9",
|
||||
"expiration": 1767779444219
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- `xo-cli`
|
||||
|
||||
```bash
|
||||
$ xo-cli create-token xoa.company.lan [email protected]
|
||||
Password: ********
|
||||
Successfully logged with [email protected]
|
||||
Authentication token created
|
||||
|
||||
DiYBFavJwf9GODZqQJs23eAx9eh3KlsRhBi8RcoX0KM
|
||||
```
|
||||
|
||||
### Refresh
|
||||
|
||||
**[Not implemented at this time]** The server can request that the client updates its token with a `Set-Cookie` header:
|
||||
|
||||
```http
|
||||
HTTP/1.1 200 OK
|
||||
Set-Cookie: authenticationToken=KQxQdm2vMiv7jBIK0hgkmgxKzemd8wSJ7ugFGKFkTbs
|
||||
```
|
||||
|
||||
Since automatic refresh is not implemented yet, you must manually refresh your token. To do so, create a new token using your existing valid authentication token:
|
||||
|
||||
```http
|
||||
POST /rest/v0/users/e531b8c9-3876-4ed9-8fd2-0476d5f825c9/authentication_tokens HTTP/1.1
|
||||
Cookie: authenticationToken=r3ZRJTejFmD8_8Yj7PnG008T58xnw01VzR3YmuIVNPw
|
||||
|
||||
{
|
||||
"token": {
|
||||
"created_at": 1765189117608,
|
||||
"id": "s2BPrps41PRqRSn1i69udcGsbx_Yx46HBa2zhY2Jj-A",
|
||||
"user_id": "e531b8c9-3876-4ed9-8fd2-0476d5f825c9",
|
||||
"expiration": 1767781117608
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Collections request
|
||||
|
||||
Collections of objects are available at `/<name>` (e.g. `/vms`)
|
||||
|
||||
The following query parameters are supported:
|
||||
|
||||
- `limit`: max number of objects returned
|
||||
- `fields`: if specified, instead of plain URLs, the results will be objects containing the requested fields
|
||||
- `filter`: a string that will be used to select only matching objects, see [the syntax documentation](manage_infrastructure.md#live-filter-search)
|
||||
- `ndjson`: if specified, the result will be in [NDJSON format](https://github.com/ndjson/ndjson-spec)
|
||||
|
||||
Simple request:
|
||||
|
||||
```http
|
||||
GET /rest/v0/vms HTTP/1.1
|
||||
Cookie: authenticationToken=TN2YBOMYtXB_hHtf4wTzm9p5tTuqq2i15yeuhcz2xXM
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/json
|
||||
|
||||
[
|
||||
"/rest/v0/vms/770aa52a-fd42-8faf-f167-8c5c4a237cac",
|
||||
"/rest/v0/vms/5019156b-f40d-bc57-835b-4a259b177be1"
|
||||
]
|
||||
```
|
||||
|
||||
With custom fields:
|
||||
|
||||
```http
|
||||
GET /rest/v0/vms?fields=name_label,power_state HTTP/1.1
|
||||
Cookie: authenticationToken=TN2YBOMYtXB_hHtf4wTzm9p5tTuqq2i15yeuhcz2xXM
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/json
|
||||
|
||||
[
|
||||
{
|
||||
"name_label": "Debian 10 Cloudinit",
|
||||
"power_state": "Running",
|
||||
"url": "/rest/v0/vms/770aa52a-fd42-8faf-f167-8c5c4a237cac"
|
||||
},
|
||||
{
|
||||
"name_label": "Debian 10 Cloudinit self-service",
|
||||
"power_state": "Halted",
|
||||
"url": "/rest/v0/vms/5019156b-f40d-bc57-835b-4a259b177be1"
|
||||
}
|
||||
]
|
||||
|
||||
```
|
||||
|
||||
Here is an example with `curl`:
|
||||
|
||||
```bash
|
||||
$ curl \
|
||||
-b authenticationToken=0OQIKwb1WjeHtch25Ls \
|
||||
http://xoa.example.com/rest/v0/vms?fields=name_label,power_state
|
||||
[
|
||||
{
|
||||
"name_label": "FreeNAS",
|
||||
"power_state": "Running",
|
||||
"href": "/rest/v0/vms/0fc14abc-ae7a-4209-79c4-d20ca1f0e567"
|
||||
},
|
||||
{
|
||||
"name_label": "Ubuntu 20.04 test",
|
||||
"power_state": "Halted",
|
||||
"href": "/rest/v0/vms/d505eb99-164e-5516-27e1-43837a01be45"
|
||||
},
|
||||
{
|
||||
"name_label": "Rocky Linux 8",
|
||||
"power_state": "Halted",
|
||||
"href": "/rest/v0/vms/38f423b7-1498-ee8c-ca8d-d3bb8fcffcf2"
|
||||
},
|
||||
{
|
||||
"name_label": "XOA 🎷",
|
||||
"power_state": "Running",
|
||||
"href": "/rest/v0/vms/857e34e5-c61a-f3f1-65e6-a7a9306b347b"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
As NDJSON:
|
||||
|
||||
```http
|
||||
GET /rest/v0/vms?fields=name_label,power_state&ndjson=true HTTP/1.1
|
||||
Cookie: authenticationToken=TN2YBOMYtXB_hHtf4wTzm9p5tTuqq2i15yeuhcz2xXM
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/x-ndjson
|
||||
|
||||
{"name_label":"Debian 10 Cloudinit","power_state":"Running","url":"/rest/v0/vms/770aa52a-fd42-8faf-f167-8c5c4a237cac"}
|
||||
{"name_label":"Debian 10 Cloudinit self-service","power_state":"Halted","url":"/rest/v0/vms/5019156b-f40d-bc57-835b-4a259b177be1"}
|
||||
```
|
||||
|
||||
## Task monitoring
|
||||
|
||||
### Specific task
|
||||
|
||||
When fetching a task record, the special `wait` query string can be used.
|
||||
|
||||
```sh
|
||||
curl \
|
||||
-b authenticationToken=KQxQdm2vMiv7jBIK0hgkmgxKzemd8wSJ7ugFGKFkTbs \
|
||||
'https://xo.example.org/rest/v0/tasks/0lr4zljbe?wait=true'
|
||||
```
|
||||
|
||||
### All tasks
|
||||
|
||||
A watch mode is available when fetching the collection as NDJSON by using both `ndjson` and `watch` query strings. Instead of sending the objects directly, each entry will be an array `[event, object]`. `event` can be either `remove` to mean that an object has been removed from the collection or `update` to mean that an object has been added to the collection or updated.
|
||||
|
||||
In case of the `remove` event, only the `id` properties of the deleted object is available.
|
||||
|
||||
The `fields` and `filter` parameters are supported.
|
||||
|
||||
Example:
|
||||
|
||||
```http
|
||||
GET /rest/v0/vms?fields=start,status&ndjson=true&watch=true HTTP/1.1
|
||||
Cookie: authenticationToken=TN2YBOMYtXB_hHtf4wTzm9p5tTuqq2i15yeuhcz2xXM
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/x-ndjson
|
||||
|
||||
["remove",{"href":"/rest/v0/tasks/0lv13orww"}]
|
||||
["update",{"start":1713194362080,"status":"pending","href":"/rest/v0/tasks/0lv13otzz"}]
|
||||
```
|
||||
|
||||
> This request does not send existing tasks, only events. If you want to get the whole collection and keep it up-to-date, the correct way to do that is:
|
||||
>
|
||||
> 1. start a watch request
|
||||
> 2. fetch the whole collection via a normal request
|
||||
> 3. process events sent by the watch request to update the local cache
|
||||
|
||||
## Properties update
|
||||
|
||||
### Collections
|
||||
|
||||
For collection properties, like `tags`, it can be more practical to touch a single item without impacting the others.
|
||||
|
||||
An item can be created with `PUT <collection>/<item id>` and can be destroyed with `DELETE <collection>/<item id>`.
|
||||
|
||||
Adding a tag:
|
||||
|
||||
```sh
|
||||
curl \
|
||||
-X PUT \
|
||||
-b authenticationToken=KQxQdm2vMiv7jBIK0hgkmgxKzemd8wSJ7ugFGKFkTbs \
|
||||
'https://xo.example.org/rest/v0/vms/770aa52a-fd42-8faf-f167-8c5c4a237cac/tags/My%20tag'
|
||||
```
|
||||
|
||||
Removing a tag:
|
||||
|
||||
```sh
|
||||
curl \
|
||||
-X DELETE \
|
||||
-b authenticationToken=KQxQdm2vMiv7jBIK0hgkmgxKzemd8wSJ7ugFGKFkTbs \
|
||||
'https://xo.example.org/rest/v0/vms/770aa52a-fd42-8faf-f167-8c5c4a237cac/tags/My%20tag'
|
||||
```
|
||||
|
||||
## VM and VDI destruction
|
||||
|
||||
For a VM:
|
||||
|
||||
```sh
|
||||
curl \
|
||||
-X DELETE \
|
||||
-b authenticationToken=KQxQdm2vMiv7jBIK0hgkmgxKzemd8wSJ7ugFGKFkTbs \
|
||||
'https://xo.example.org/rest/v0/vms/770aa52a-fd42-8faf-f167-8c5c4a237cac'
|
||||
```
|
||||
|
||||
For a VDI:
|
||||
|
||||
```sh
|
||||
curl \
|
||||
-X DELETE \
|
||||
-b authenticationToken=KQxQdm2vMiv7jBIK0hgkmgxKzemd8wSJ7ugFGKFkTbs \
|
||||
'https://xo.example.org/rest/v0/vdis/1a269782-ea93-4c4c-897a-475365f7b674'
|
||||
```
|
||||
|
||||
## VM and VDI export
|
||||
|
||||
VDI export and VM export are supported by the API. Below is a simple example to export a VM with `zstd` compression into a `myVM.xva` file:
|
||||
|
||||
```sh
|
||||
curl \
|
||||
-b authenticationToken=KQxQdm2vMiv7jFEAZXOAGKFkTbs \
|
||||
'https://xoa.example.org/rest/v0/vms/770aa52a-fd42-8faf-f167-8c5c4a237a12.xva?compress=zstd' \
|
||||
> myVM.xva
|
||||
```
|
||||
|
||||
A VDI can be exported in VHD format at `/rest/v0/vdis/<uuid>.vhd` or the raw content at `/rest/v0/vdis/<uuid>.raw`.
|
||||
|
||||
```sh
|
||||
curl \
|
||||
-b authenticationToken=KQxQdm2vMiv7FkTbs \
|
||||
'https://xoa.example.org/rest/v0/vdis/1a269782-ea93-4c4c-897a-475365f7b674.vhd' \
|
||||
> myDisk.vhd
|
||||
```
|
||||
|
||||
The following optional query parameters are supported for VDI export:
|
||||
|
||||
- `preferNbd=<boolean>`: will use NBD for export if available
|
||||
- `nbdConcurrency=<integer>`: set the number of concurrent stream per disk if NBD is enabled, default 1
|
||||
|
||||
## VM Import
|
||||
|
||||
> OVA import is not supported.
|
||||
|
||||
A VM can be imported by posting an XVA to `/rest/v0/pools/:id/vms`.
|
||||
|
||||
```sh
|
||||
curl \
|
||||
-X POST \
|
||||
-b authenticationToken=KQxQdm2vMiv7jBIK0hgkmgxKzemd8wSJ7ugFGKFkTbs \
|
||||
-T myDisk.raw \
|
||||
'https://xo.example.org/rest/v0/pools/355ee47d-ff4c-4924-3db2-fd86ae629676/vms?sr=357bd56c-71f9-4b2a-83b8-3451dec04b8f' \
|
||||
| cat
|
||||
```
|
||||
|
||||
The `sr` query parameter can be used to specify on which SR the VM should be imported, if not specified, the default SR will be used.
|
||||
|
||||
> Note: the final `| cat` ensures cURL's standard output is not a TTY, which is necessary for upload stats to be displayed.
|
||||
|
||||
## VDI Import
|
||||
|
||||
### Existing VDI
|
||||
|
||||
A VHD or a raw export can be imported in an existing VDI respectively at `/rest/v0/vdis/<uuid>.vhd` and `/rest/v0/vdis/<uuid>.raw`.
|
||||
|
||||
> Note: the size of the VDI must match exactly the size of VDI that was previously exported.
|
||||
|
||||
```sh
|
||||
curl \
|
||||
-X PUT \
|
||||
-b authenticationToken=KQxQdm2vMiv7jBIK0hgkmgxKzemd8wSJ7ugFGKFkTbs \
|
||||
-T myDisk.vhd \
|
||||
'https://xo.example.org/rest/v0/vdis/1a269782-ea93-4c4c-897a-475365f7b674.vhd' \
|
||||
| cat
|
||||
```
|
||||
|
||||
> Note: the final `| cat` ensures cURL's standard output is not a TTY, which is necessary for upload stats to be displayed.
|
||||
|
||||
### New VDI
|
||||
|
||||
An export can also be imported on an SR to create a new VDI at `/rest/v0/srs/<sr uuid>/vdis`.
|
||||
|
||||
```sh
|
||||
curl \
|
||||
-X POST \
|
||||
-b authenticationToken=KQxQdm2vMiv7jBIK0hgkmgxKzemd8wSJ7ugFGKFkTbs \
|
||||
-T myDisk.raw \
|
||||
'https://xo.example.org/rest/v0/srs/357bd56c-71f9-4b2a-83b8-3451dec04b8f/vdis?raw&name_label=my_imported_VDI' \
|
||||
| cat
|
||||
```
|
||||
|
||||
> Note: the final `| cat` ensures cURL's standard output is not a TTY, which is necessary for upload stats to be displayed.
|
||||
|
||||
This request returns the UUID of the created VDI.
|
||||
|
||||
The following query parameters are supported to customize the created VDI:
|
||||
|
||||
- `name_label`
|
||||
- `name_description`
|
||||
- `raw`: this parameter must be used if importing a raw export instead of a VHD
|
||||
|
||||
## Attaching an existing VDI to a VM
|
||||
|
||||
To attach an existing VDI to a VM, create a VBD through the `POST /vbds`
|
||||
endpoint. The VBD's `mode` (`RW` or `RO`) and `bootable` flag are set at creation.
|
||||
|
||||
:::note
|
||||
Mounting or ejecting an ISO (CD-ROM) is not currently available through the
|
||||
REST API. Use the JSON-RPC API instead, for example via `xo-cli`:
|
||||
:::
|
||||
> ```sh
|
||||
> xo-cli vm.insertCd id=<vm-id> cd_id=<vdi-id> [force=<boolean>]
|
||||
> ```
|
||||
|
||||
## Actions
|
||||
|
||||
The field `params` contains the [JSON schema](https://json-schema.org/) for the parameters.
|
||||
|
||||
### Start an action
|
||||
|
||||
Post at the action endpoint which is `/rest/v0/<type>/<uuid>/actions/<action>`.
|
||||
|
||||
For instance, to reboot a VM:
|
||||
|
||||
```sh
|
||||
curl \
|
||||
-X POST \
|
||||
-b authenticationToken=KQxQdm2vMiv7jBIK0hgkmgxKzemd8wSJ7ugFGKFkTbs \
|
||||
'https://xo.example.org/rest/v0/vms/770aa52a-fd42-8faf-f167-8c5c4a237cac/actions/clean_reboot'
|
||||
```
|
||||
|
||||
Some actions accept parameters, they should be provided in a JSON-encoded object as the request body:
|
||||
|
||||
```sh
|
||||
curl \
|
||||
-X POST \
|
||||
-b authenticationToken=KQxQdm2vMiv7jBIK0hgkmgxKzemd8wSJ7ugFGKFkTbs \
|
||||
-H 'Content-Type: application/json' \
|
||||
-H 'Accept: application/json' \
|
||||
-d '{ "name_label": "My snapshot" }' \
|
||||
'https://xo.example.org/rest/v0/vms/770aa52a-fd42-8faf-f167-8c5c4a237cac/actions/snapshot'
|
||||
```
|
||||
|
||||
By default, actions are asynchronous and return the reference of the task associated with the request (see [_Task monitoring_](#task-monitoring)).
|
||||
|
||||
The `?sync=true` flag can be used to run the action synchronously without requiring task monitoring. The result of the action will be returned encoded as JSON:
|
||||
|
||||
```console
|
||||
$ curl \
|
||||
-X POST \
|
||||
-b authenticationToken=KQxQdm2vMiv7jBIK0hgkmgxKzemd8wSJ7ugFGKFkTbs \
|
||||
'https://xo.example.org/rest/v0/vms/770aa52a-fd42-8faf-f167-8c5c4a237cac/actions/clean_reboot?sync=true'
|
||||
"2b0266aa-c753-6fbc-e4dd-c79be7782052"
|
||||
```
|
||||
|
||||
## Events
|
||||
|
||||
The REST API exposes a [Server-Sent Events (SSE)](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events) endpoint to receive real-time notifications when objects change in the infrastructure (VMs, hosts, SRs, etc.).
|
||||
|
||||
### Opening a connection
|
||||
|
||||
```http
|
||||
GET /rest/v0/events HTTP/1.1
|
||||
Cookie: authenticationToken=TN2YBOMYtXB_hHtf4wTzm9p5tTuqq2i15yeuhcz2xXM
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: text/event-stream
|
||||
```
|
||||
|
||||
The first event sent is `init`, which contains the connection ID needed to manage subscriptions:
|
||||
|
||||
```
|
||||
event: init
|
||||
data: {"id":"0d8b28c6-e9bf-4c9d-a382-3c9e0d7cfbff"}
|
||||
```
|
||||
|
||||
A `ping` event is sent every 30 seconds to keep the connection alive:
|
||||
|
||||
```
|
||||
event: ping
|
||||
data: {"ping":1713194362080}
|
||||
```
|
||||
|
||||
### Managing subscriptions
|
||||
|
||||
By default an open connection has no active subscriptions. Use the connection ID returned by `init` to subscribe to a collection:
|
||||
|
||||
```http
|
||||
POST /rest/v0/events/0d8b28c6-e9bf-4c9d-a382-3c9e0d7cfbff/subscriptions HTTP/1.1
|
||||
Cookie: authenticationToken=TN2YBOMYtXB_hHtf4wTzm9p5tTuqq2i15yeuhcz2xXM
|
||||
Content-Type: application/json
|
||||
|
||||
{"collection": "VM", "fields": ["id", "name_label", "power_state"]}
|
||||
```
|
||||
|
||||
The `fields` property is optional. When omitted, all fields are returned. When provided, only the listed fields are included in events (and `update` events whose watched fields did not change are suppressed entirely).
|
||||
|
||||
To unsubscribe:
|
||||
|
||||
```http
|
||||
DELETE /rest/v0/events/0d8b28c6-e9bf-4c9d-a382-3c9e0d7cfbff/subscriptions/VM HTTP/1.1
|
||||
Cookie: authenticationToken=TN2YBOMYtXB_hHtf4wTzm9p5tTuqq2i15yeuhcz2xXM
|
||||
```
|
||||
|
||||
### Received events
|
||||
|
||||
Once subscribed, the stream emits the following events for the relevant collection:
|
||||
|
||||
| Event | Meaning |
|
||||
| -------- | ------------------------------------------ |
|
||||
| `add` | An object has been added to the collection |
|
||||
| `update` | An object has been updated |
|
||||
| `remove` | An object has been removed |
|
||||
|
||||
Each event's `data` is a JSON object containing the object's fields plus a `$subscription` property indicating which collection it belongs to:
|
||||
|
||||
```
|
||||
event: add
|
||||
data: {"$subscription":"VM","id":"770aa52a-fd42-8faf-f167-8c5c4a237cac","name_label":"Debian 12","power_state":"Halted"}
|
||||
|
||||
event: update
|
||||
data: {"$subscription":"VM","id":"770aa52a-fd42-8faf-f167-8c5c4a237cac","name_label":"Debian 12","power_state":"Running"}
|
||||
|
||||
event: remove
|
||||
data: {"$subscription":"VM","id":"770aa52a-fd42-8faf-f167-8c5c4a237cac","name_label":"Debian 12","power_state":"Running"}
|
||||
```
|
||||
|
||||
### Memory limit per connection
|
||||
|
||||
Each SSE connection buffers events internally until the client consumes them. To protect the server from memory exhaustion caused by slow or unresponsive clients, the buffer size per connection is configurable via `maxRamAllocatedPerSseClient` in `config.toml`:
|
||||
|
||||
```toml
|
||||
[rest-api]
|
||||
maxRamAllocatedPerSseClient = 20
|
||||
```
|
||||
|
||||
When a connection's buffer exceeds this limit, the server logs an error and immediately destroys that connection. The client will receive a closed stream and must reconnect.
|
||||
|
||||
## OpenAPI/Swagger
|
||||
|
||||
### What is Swagger?
|
||||
|
||||
[Swagger](https://swagger.io/specification/) allows you to describe the structure of an API so that machines can understand. By parsing the structure of the API, Swagger can automatically generate clear, user-friendly, and interactive API documentation. It also makes integration with tools and automatic client library generation possible.
|
||||
|
||||
As part of our continuous efforts to improve the developer experience, we’ve begun documenting the Xen Orchestra REST API using the OpenAPI (Swagger) standard:
|
||||
|
||||

|
||||
|
||||
:::tip
|
||||
|
||||
The Swagger API documentation is still a work in progress. Not all endpoints are currently covered, and some details may change as we continue to refine the specification. However, it already provides a solid foundation for understanding and interacting with key parts of the API.
|
||||
|
||||
:::
|
||||
|
||||
### Accessing the Xen Orchestra API documentation in Swagger
|
||||
|
||||
The Swagger UI is available at `/rest/v0/docs`. It doesn't just provide documentation of available endpoints, but also **lets you test them directly from the interface**. This way, you can experiment with the API without writing any code!
|
||||
|
||||
## Ongoing Improvements
|
||||
|
||||
We are actively working on enhancing and expanding the REST API with new features and capabilities. If you have specific use cases, ideas, or feedback that you would like to share, feel free to participate in the discussion on our [Xen Orchestra forum](https://xcp-ng.org/forum/category/12/xen-orchestra).
|
||||
@@ -1,23 +0,0 @@
|
||||
# Rolling snapshots
|
||||
|
||||
:::warning
|
||||
Snapshots aren't really a backup, but a convenient way to rollback in time. All snapshots are on the same storage as their original disk: if you lose the original disk or storage, you'll **lose all your snapshots**. Also, they are not mutually exclusive with backups.
|
||||
|
||||
We strongly advise that you do NOT rely only on snapshots!
|
||||
:::
|
||||
|
||||
This feature is similar to Backups, but it creates a snapshot when planned to do so. It also handles the retention (removing the oldest snapshot). This feature is very convenient to rollback to a previous state.
|
||||
|
||||
:::tip
|
||||
:construction_worker: This section needs to be completed: screenshots and how-to :construction_worker:
|
||||
:::
|
||||
|
||||
:::tip
|
||||
Due to space usage, rolling snapshots should be avoided for large VMs on non-thin provisioned storages.
|
||||
:::
|
||||
|
||||
## Examples
|
||||
|
||||
- Schedule a nightly snapshot for a group of VMs, let's say at 4:30 in the morning. With a max snapshot of 7, you'll have a week of revert possibility
|
||||
- Schedule a snapshot every week, but precisely Sunday at 11 PM, with 4 snapshots max. This will give you a month max of revert
|
||||
- And so forth!
|
||||
+104
-41
@@ -1,5 +1,7 @@
|
||||
# SDN Controller
|
||||
|
||||
<InterfaceNote>Private networks are currently created and managed from XO 5. Traffic rules moved ahead in [XO 6](../xo6/management.md#traffic-rules), with more capabilities than the XO 5 equivalent.</InterfaceNote>
|
||||
|
||||
:::tip
|
||||
Be sure to enable the plugin on only one XOA instance.
|
||||
:::
|
||||
@@ -10,7 +12,58 @@ The SDN Controller enables a user to **create pool-wide and cross-pool private n
|
||||
|
||||
Interconnect your VMs and hosts within a dedicated and secured private network, even across different pools all around the world. This is a great way to protect "private links" (eg between applications and databases, management networks etc.) without any complicated deployment.
|
||||
|
||||

|
||||
<Schema label="One private network spanning two sites" legend={[["#6aabf0", "XO"], ["#8e83fe", "XCP-ng"], ["#5ac8c8", "private network tunnels"]]} maxWidth="640px">
|
||||
<svg viewBox="0 0 640 260" role="img" aria-label="The SDN controller in Xen Orchestra builds encrypted GRE or VxLAN tunnels between the hosts of two pools in different locations, forming a single private network for the VMs">
|
||||
<rect x="280" y="10" width="80" height="34" rx="8" fill="rgba(106,171,240,0.12)" stroke="#6aabf0"/>
|
||||
<text x="320" y="27" fontSize="12.5" fill="#6aabf0" textAnchor="middle">XO</text>
|
||||
<text x="320" y="39" fontSize="8.5" fill="#7a8699" textAnchor="middle">SDN controller</text>
|
||||
<g className="schema-flow" stroke="#7a8699" strokeWidth="1.3" strokeDasharray="5 4">
|
||||
<line x1="292" y1="44" x2="160" y2="70"/>
|
||||
<line x1="348" y1="44" x2="480" y2="70"/>
|
||||
</g>
|
||||
<g fill="none" stroke="rgba(255,255,255,0.22)" strokeDasharray="6 5">
|
||||
<rect x="25" y="70" width="270" height="160" rx="10"/>
|
||||
<rect x="345" y="70" width="270" height="160" rx="10"/>
|
||||
</g>
|
||||
<g fontSize="12" fill="#7a8699">
|
||||
<text x="41" y="92">Pool 1 · Paris</text>
|
||||
<text x="361" y="92">Pool 2 · Amsterdam</text>
|
||||
</g>
|
||||
<g fill="rgba(142,131,254,0.1)" stroke="#8e83fe" strokeOpacity="0.8">
|
||||
<rect x="45" y="102" width="115" height="86" rx="6"/>
|
||||
<rect x="175" y="102" width="115" height="86" rx="6"/>
|
||||
<rect x="365" y="102" width="115" height="86" rx="6"/>
|
||||
<rect x="495" y="102" width="115" height="86" rx="6"/>
|
||||
</g>
|
||||
<g fontSize="10" fill="#8e83fe" textAnchor="middle">
|
||||
<text x="102" y="119">Host 1</text>
|
||||
<text x="232" y="119">Host 2</text>
|
||||
<text x="422" y="119">Host 3</text>
|
||||
<text x="552" y="119">Host 4</text>
|
||||
</g>
|
||||
<g fill="rgba(86,194,136,0.14)" stroke="#56c288">
|
||||
<rect x="60" y="132" width="85" height="34" rx="4"/>
|
||||
<rect x="190" y="132" width="85" height="34" rx="4"/>
|
||||
<rect x="380" y="132" width="85" height="34" rx="4"/>
|
||||
<rect x="510" y="132" width="85" height="34" rx="4"/>
|
||||
</g>
|
||||
<g fontSize="10.5" fill="#c6d2e1" textAnchor="middle">
|
||||
<text x="102" y="152">VM</text>
|
||||
<text x="232" y="152">VM</text>
|
||||
<text x="422" y="152">VM</text>
|
||||
<text x="552" y="152">VM</text>
|
||||
</g>
|
||||
<g className="schema-flow" stroke="#5ac8c8" strokeWidth="1.6" strokeDasharray="5 4">
|
||||
<line x1="102" y1="188" x2="102" y2="210"/>
|
||||
<line x1="232" y1="188" x2="232" y2="210"/>
|
||||
<line x1="422" y1="188" x2="422" y2="210"/>
|
||||
<line x1="552" y1="188" x2="552" y2="210"/>
|
||||
<line x1="102" y1="210" x2="552" y2="210"/>
|
||||
</g>
|
||||
<text x="320" y="203" fontSize="9" fill="#5ac8c8" textAnchor="middle">WAN</text>
|
||||
<text x="320" y="248" fontSize="9.5" fill="#7a8699" textAnchor="middle">encrypted GRE / VxLAN tunnels · one L2 network for all these VMs</text>
|
||||
</svg>
|
||||
</Schema>
|
||||
|
||||
### How does it work?
|
||||
|
||||
@@ -36,7 +89,7 @@ In the network creation view:
|
||||
- Create the network
|
||||
- Have fun! ☺
|
||||
|
||||

|
||||
<UiShot light="/img/xo5/sdn-controller.png" alt="Creating a private network: interface, encapsulation, encryption, and the pools to join" url="https://your-xo/v5/#/new/network" />
|
||||
|
||||
:::tip
|
||||
|
||||
@@ -47,7 +100,7 @@ In the network creation view:
|
||||
|
||||
### Configuration
|
||||
|
||||
Like all other xo-server plugins, it can be configured directly via the web interface, see [the plugin documentation](architecture#plugins).
|
||||
Like all other xo-server plugins, it can be configured directly via the web interface, see [the plugin documentation](../architecture.md#plugins).
|
||||
|
||||
The plugin's configuration contains:
|
||||
|
||||
@@ -61,22 +114,30 @@ The plugin's configuration contains:
|
||||
|
||||
### Encryption
|
||||
|
||||
- To be able to encrypt the networks, `openvswitch-ipsec` package must be installed on all the hosts:
|
||||
- `yum install openvswitch-ipsec --enablerepo=xcp-ng-testing`
|
||||
- `systemctl enable ipsec`
|
||||
- `systemctl enable openvswitch-ipsec`
|
||||
- `systemctl start ipsec`
|
||||
- `systemctl start openvswitch-ipsec`
|
||||
To be able to encrypt the networks, the `openvswitch-ipsec` package must be installed on all the hosts:
|
||||
|
||||
<Terminal shell title="on every host of the network">{`
|
||||
yum install openvswitch-ipsec --enablerepo=xcp-ng-testing
|
||||
systemctl enable ipsec
|
||||
systemctl enable openvswitch-ipsec
|
||||
systemctl start ipsec
|
||||
systemctl start openvswitch-ipsec
|
||||
`}</Terminal>
|
||||
|
||||
## OpenFlow rules
|
||||
|
||||
There are currently two implementations:
|
||||
Traffic rules let you allow or block traffic per VIF, or network-wide. There are currently two backends:
|
||||
|
||||
- One where the SDN Controller plugin talks directly to Open vSwitch through the OpenFlow protocol
|
||||
- A newer one using a XAPI plugin on XCP-ng side that directly configures Open vSwitch
|
||||
|
||||
At this time, the two options are covered until we can fully deprecate the older, direct OpenFlow implementation.
|
||||
|
||||
Where the UI lives:
|
||||
|
||||
- **XO 5**: per-VIF rules only, from the VM **Network** tab (described [below](#openflow-protocol))
|
||||
- **XO 6**: the full experience, network-wide **and** per-VIF rules, with a consolidated pool view: see [Traffic rules in XO 6](../xo6/management.md#traffic-rules). It requires the XAPI plugin backend.
|
||||
|
||||
### OpenFlow Protocol
|
||||
|
||||
:::warning
|
||||
@@ -103,8 +164,9 @@ In the VM network tab a new column has been added: _Network rules_.
|
||||
- The _Show rules_ button allow to display all rules for a VIF.
|
||||
- When the rules are display a button to delete a rule is available.
|
||||
|
||||

|
||||

|
||||
<UiDetail src="/img/xo5/add-rule.png" alt="The Add rule form: allow or deny, protocol, port, IP range, direction" width={480} />
|
||||
|
||||
<UiDetail src="/img/xo5/show-rules.png" alt="All the rules of a VIF, with a delete button for each" width={700} />
|
||||
|
||||
### XAPI Plugin
|
||||
|
||||
@@ -113,11 +175,11 @@ A few caveats:
|
||||
|
||||
- This is still in BETA and should not be used in production yet.
|
||||
- This will only work on XCP-ng, not on XenServer hosts.
|
||||
- This is not enabled by default, and requires a configuration change for `xo-server`. See [the configuration page](configuration#sdn-controller-mode) to know more.
|
||||
- This is not enabled by default, and requires a configuration change for `xo-server`. See [the configuration page](../configuration.md#sdn-controller-mode) to know more.
|
||||
:::
|
||||
|
||||
:::tip
|
||||
Since Xen Orchestra 6.5 UI, you can manage network-wide or VIF traffic rules. The rules can also be created through the [REST API](./restapi.md).
|
||||
This is the backend used by the [XO 6 traffic rules UI](../xo6/management.md#traffic-rules) (since XO 6.5): network-wide and per-VIF rules, with a consolidated view in the pool **Security** tab. The rules can also be managed through the [REST API](../automation/restapi.md), including in-place updates (since XO 6.7).
|
||||
:::
|
||||
|
||||
- Works on any network:
|
||||
@@ -129,12 +191,12 @@ Since Xen Orchestra 6.5 UI, you can manage network-wide or VIF traffic rules. Th
|
||||
|
||||
To setup a per-VIF rule using the UI, follow the [openflow instructions](#openflow-protocol) above, as the UI is the same and only the backend changes.
|
||||
|
||||
Here, we describe how to use `xo-cli` to configure rules. First, make sure to register xo-cli to your XOA instance as documented in [it's documentation](architecture#register-your-xo-instance).
|
||||
Here, we describe how to use `xo-cli` to configure rules. First, make sure to register xo-cli to your XOA instance as documented in [its documentation](../architecture.md#xo-cli).
|
||||
|
||||
- Add per-VIF rules: `xo-cli sdnController.addRule vifId=<VIF_UUID> <parameters>`
|
||||
- Delete per-VIF rules: `xo-cli sdnController.deleteRule vifId=<VIF_UUID> <parameters`
|
||||
- Add new network-wide rules: `xo-cli sdnController.addNetworkRule networkId=<NETWORK_UUID> <parameters`
|
||||
- Delete network-wide rules: `xo-cli sdnController.deleteNetworkRule networkId=<NETWORK_UUID> <parameters`
|
||||
- Delete per-VIF rules: `xo-cli sdnController.deleteRule vifId=<VIF_UUID> <parameters>`
|
||||
- Add new network-wide rules: `xo-cli sdnController.addNetworkRule networkId=<NETWORK_UUID> <parameters>`
|
||||
- Delete network-wide rules: `xo-cli sdnController.deleteNetworkRule networkId=<NETWORK_UUID> <parameters>`
|
||||
|
||||
Parameters:
|
||||
|
||||
@@ -149,18 +211,19 @@ Parameters:
|
||||
|
||||
Some examples:
|
||||
|
||||
```
|
||||
# Per-VIF rules:
|
||||
<Terminal shell title="per-VIF rules">{`
|
||||
xo-cli sdnController.addRule vifId=15f1a9ec-4348-0cca-d2b8-e536db043298 direction=from ipRange=1.1.1.3 protocol=tcp port=json:4242 allow=false
|
||||
xo-cli sdnController.deleteRule vifId=15f1a9ec-4348-0cca-d2b8-e536db043298 direction=from ipRange=1.1.1.3 protocol=tcp port=json:4242
|
||||
xo-cli sdnController.addRule vifId=e9a7914a-9518-82e2-7052-42cb16cc9724 direction=to ipRange=1.1.1.2 protocol=icmp allow=false
|
||||
xo-cli sdnController.deleteRule vifId=e9a7914a-9518-82e2-7052-42cb16cc9724 direction=to ipRange=1.1.1.2 protocol=icmp
|
||||
# Network-wide rules:
|
||||
`}</Terminal>
|
||||
|
||||
<Terminal shell title="network-wide rules">{`
|
||||
xo-cli sdnController.addNetworkRule networkId=9334aa83-6960-62e5-a463-5acc05295af4 direction=to ipRange=1.1.1.2 protocol=icmp allow=false
|
||||
xo-cli sdnController.deleteNetworkRule networkId=9334aa83-6960-62e5-a463-5acc05295af4 direction=to ipRange=1.1.1.2 protocol=icmp
|
||||
xo-cli sdnController.addNetworkRule networkId=9334aa83-6960-62e5-a463-5acc05295af4 direction=from ipRange=1.1.1.2 protocol=tcp allow=false port=json:4242
|
||||
xo-cli sdnController.deleteNetworkRule networkId=9334aa83-6960-62e5-a463-5acc05295af4 direction=from ipRange=1.1.1.2 protocol=tcp port=json:4242
|
||||
```
|
||||
`}</Terminal>
|
||||
|
||||
### Migration path
|
||||
|
||||
@@ -171,10 +234,10 @@ Because of this mismatch, the two modes are not directly interchangeable and you
|
||||
1. Re‑create the rules from scratch, or
|
||||
2. Use the provided migration script to translate an existing set of rules.
|
||||
|
||||
:::note
|
||||
The migration is forward only.
|
||||
You can go from OpenFlow Protocol to XAPI Plugin in a semi‑automatic manner, but to revert existing rules will be deleted first.
|
||||
:::
|
||||
:::note
|
||||
The migration is forward only.
|
||||
You can go from OpenFlow Protocol to XAPI Plugin in a semi‑automatic manner, but to revert existing rules will be deleted first.
|
||||
:::
|
||||
|
||||
#### What the migration script does
|
||||
|
||||
@@ -188,17 +251,17 @@ Existing rules will first be removed before restoring the saved ones.
|
||||
|
||||
The migration script is available as [sdn-migration.py (download script)](../../static/sh/sdn-migration.py).
|
||||
|
||||
```sh
|
||||
<Terminal shell title="migrate the rules (backup written to rules-channel.json)">{`
|
||||
# Export current rules to rules-channel.json and convert to XAPI format
|
||||
python3 sdn-migration.py migrate
|
||||
|
||||
# (Optional) Restore original rules (from rules-channel.json file)
|
||||
python3 sdn-migration.py restore
|
||||
```
|
||||
`}</Terminal>
|
||||
|
||||
## OpenSSL 3 + SDN upgrade path
|
||||
|
||||
With OpenSSL 3 arriving in XCP-ng 8.3, the certificates previously generated by the Xen Orchestra SDN Controller plugin will no longer work. **You must regenerate the certificates before updating your XCP-ng pools.** The steps below only cover certificate regeneration — updating your XCP-ng pools is a separate operation that you perform as you normally would, after the certificates are in place.
|
||||
With OpenSSL 3 arriving in XCP-ng 8.3, the certificates previously generated by the Xen Orchestra SDN Controller plugin will no longer work. **You must regenerate the certificates before updating your XCP-ng pools.** The steps below only cover certificate regeneration: updating your XCP-ng pools is a separate operation that you perform as you normally would, after the certificates are in place.
|
||||
|
||||
:::warning
|
||||
We remind you that the self-signed certificates generated by Xen Orchestra’s SDN Controller plugin are a workaround. **They are neither safe nor recommended**. You should provide your own certificates.
|
||||
@@ -233,9 +296,9 @@ We provide a script to run from a host that has access to your pool. To run the
|
||||
|
||||
Copy the file to where you want to run the script, then run this:
|
||||
|
||||
```
|
||||
$ bash check-sdn-features.sh <pool-master-ip1> [pool-master-ip2] [pool-master-ip3] ...
|
||||
```
|
||||
<Terminal shell title="check every pool master">{`
|
||||
bash check-sdn-features.sh <pool-master-ip1> [pool-master-ip2] [pool-master-ip3] ...
|
||||
`}</Terminal>
|
||||
|
||||
The script will connect to those masters and check:
|
||||
|
||||
@@ -273,11 +336,11 @@ This is the simplest case. We have updated the self-signed certificates to work
|
||||
:::tip
|
||||
We suggest doing a backup of the certificates in case anything goes wrong:
|
||||
|
||||
```
|
||||
xoa@xoa:~$ today=$(date +%Y%m%d)
|
||||
xoa@xoa:~$ sudo mkdir /var/lib/xo-server/data/sdn-controller/$today-backup
|
||||
xoa@xoa:~$ sudo mv /var/lib/xo-server/data/sdn-controller/*.pem /var/lib/xo-server/data/sdn-controller/$today-backup
|
||||
```
|
||||
<Terminal shell title="back up the current certificates, on your XOA">{`
|
||||
today=$(date +%Y%m%d)
|
||||
sudo mkdir /var/lib/xo-server/data/sdn-controller/$today-backup
|
||||
sudo mv /var/lib/xo-server/data/sdn-controller/*.pem /var/lib/xo-server/data/sdn-controller/$today-backup
|
||||
`}</Terminal>
|
||||
|
||||
:::
|
||||
|
||||
@@ -291,11 +354,11 @@ We provide a helper script to run on your XOA VM:
|
||||
|
||||
[regenerate-certs.sh (download script)](../../static/sh/regenerate-certs.sh)
|
||||
|
||||
```
|
||||
xoa@xoa:~$ sudo bash -e ./regenerate-certs.sh
|
||||
<Terminal shell title="regenerate the certificates, on your XOA">{`
|
||||
sudo bash -e ./regenerate-certs.sh
|
||||
# if you have available updates, just update XOA, otherwise:
|
||||
xoa@xoa:~$ sudo systemctl restart xo-server
|
||||
```
|
||||
sudo systemctl restart xo-server
|
||||
`}</Terminal>
|
||||
|
||||
Once `xo-server` is back up, the new certificates are pushed to your hosts. You can then update your XCP-ng pools as you normally would.
|
||||
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
# Host Compatibility List
|
||||
|
||||
This section lists all supported hosts where Xen Orchestra can connect to.
|
||||
|
||||
Xen Orchestra is designed to work exclusively on [XCP-ng](https://xcp-ng.org/) and [Citrix Hypervisor](https://www.citrix.com/products/citrix-hypervisor/) (formerly XenServer).
|
||||
|
||||
Xen Orchestra should be fully functional with any version of these two virtualization platforms. However, to benefit from the best support quality, our product is tested to work the best with the versions displayed with a ✅.
|
||||
|
||||
### Legend
|
||||
|
||||
- ✅ Full support
|
||||
- 🚀 All extra features (eg: RAM enabled backup)
|
||||
- ☠️ Virtualization platform without security updates anymore (upgrade your hosts!)
|
||||
- ❎ Not all XO features supported
|
||||
|
||||
## XCP-ng
|
||||
|
||||
:::tip
|
||||
Xen Orchestra and XCP-ng are mainly edited by the same company ([Vates](https://vates.tech)). That's why you are sure to have the best compatibility with both XCP-ng and XO! Also, we strongly suggest people to keep using the latest XCP-ng LTS version as far as possible (or N-1).
|
||||
:::
|
||||
|
||||
- XCP-ng 8.3 LTS ✅ 🚀
|
||||
- XCP-ng 8.2 ✅ ☠️
|
||||
- XCP-ng 8.1 ✅ ☠️
|
||||
- XCP-ng 8.0 ✅ ☠️
|
||||
- XCP-ng 7.6 ✅ ☠️
|
||||
- XCP-ng 7.5 ✅ ☠️
|
||||
- XCP-ng 7.4 ✅ ☠️
|
||||
|
||||
## XenServer (formerly Citrix Hypervisor)
|
||||
|
||||
- XenServer 8 ✅
|
||||
- Citrix Hypervisor 8.2 LTS ✅
|
||||
- Citrix Hypervisor 8.1 ✅ ☠️
|
||||
- Citrix Hypervisor 8.0 ✅ ☠️
|
||||
- XenServer 7.6 ✅ ☠️
|
||||
- XenServer 7.5 ✅ ☠️
|
||||
- [VDI I/O error](https://bugs.xenserver.org/browse/XSO-873), waiting for Citrix to release our fix
|
||||
- XenServer 7.4 ✅ ☠️
|
||||
- XenServer 7.3 ✅ ☠️
|
||||
- XenServer 7.2 ❎ ☠️
|
||||
- Issues with JSON-RPC which may leads to `INTERNAL_ERROR((Failure "Expected float, got 'I(1)'"))` during _Incremental Replication_ and _Incremental Backup_ restorations
|
||||
- XenServer 7.1 LTS ✅ ☠️
|
||||
- XenServer 7.0 ✅ ☠️
|
||||
- XenServer 6.5 ✅ ☠️
|
||||
- Random Delta backup issues
|
||||
- XenServer 6.1 and 6.2 ❎ ☠️
|
||||
- **No official support** due to missing JSON-RPC (only XML, too CPU intensive)
|
||||
- Not compatible with Delta backup and CR
|
||||
- XenServer 5.x ❎ ☠️
|
||||
- Basic administration features only, **no official support**
|
||||
|
||||
:::warning
|
||||
Backup restore for large VM disks (>1TiB usage) is [broken on old XenServer versions](https://bugs.xenserver.org/browse/XSO-868) (except 7.1 LTS up-to-date and superior to 7.6).
|
||||
:::
|
||||
|
||||
## Others
|
||||
|
||||
If you installed Xen hypervisor from your usual Linux distribution, it won't work. Xen Orchestra is **agent-less** and communicate to the host directly using XAPI toolstack. Without this toolstack, it's not possible to make Xen and XO communicate.
|
||||
|
||||
See more details in [architecture section](architecture.md).
|
||||
@@ -1,252 +0,0 @@
|
||||
# Troubleshooting
|
||||
|
||||
This page recaps the actions you can perform if you have any problems with your XOA.
|
||||
|
||||
:::warning
|
||||
If you have issues with XO installed from GitHub (not XOA), [please go to the dedicated section first!](../xo6/community.md).
|
||||
:::
|
||||
|
||||
## Recommendation
|
||||
|
||||
If you think you have a problem with your XOA, start by running the `xoa check` command in your terminal:
|
||||
|
||||
```console
|
||||
$ xoa check
|
||||
✔ Node version
|
||||
✔ Disk space for /var
|
||||
✔ Disk space for /
|
||||
✔ XOA version
|
||||
✔ xo-server config syntax
|
||||
✔ Appliance registration
|
||||
✔ Internet connectivity
|
||||
```
|
||||
|
||||
If the result you have is completely different from that, or if error messages are displayed, lost packets, etc., you have, indeed, a problem.
|
||||
|
||||
The next step should be to check the rest of this page for an existing solution.
|
||||
|
||||
:::tip
|
||||
You can also check the system logs, [as explained here](#cli).
|
||||
:::
|
||||
|
||||
## Backup issues
|
||||
|
||||
If you're having issues with your backups, check out the [Backup troubleshooting](backup_troubleshooting) page.
|
||||
|
||||
## Didn't find a solution?
|
||||
|
||||
Open a ticket for your issue in your [personal space](https://xen-orchestra.com/#!/member/support).
|
||||
|
||||
## Deploy error
|
||||
|
||||
> Auto deploy failed. - No SR specified and Pool default SR is null
|
||||
|
||||
It means you don't have a default SR set on the pool you are importing XOA on. To set a default SR, you must first find the SR UUID you want, with `xe sr-list`. When you have the UUID, you can set the default SR with: `xe pool-param-set uuid=<pool-uuid> default-SR=<sr-uuid>`. For the pool UUID, just press tab after `xe pool-param-set uuid=` and it will autofill your pool UUID. When this is done, re-enter the deploy script command and it will work!
|
||||
|
||||
## Unreachable after boot
|
||||
|
||||
XOA uses HVM mode. If your physical host doesn't support virtualization extensions, XOA won't work. To check if your XCP-ng/XenServer supports hardware assisted virtualization (HVM), you can enter this command in your host: `grep --color vmx /proc/cpuinfo`. If you don't have any result, it means XOA won't work on this hardware.
|
||||
|
||||
## Set or recover XOA VM password
|
||||
|
||||
As no password is set for the xoa system user by default, you will need to set your own. This can be done via the XenStore data of the VM. The following is to be ran on your XCP-ng host:
|
||||
|
||||
```sh
|
||||
xe vm-param-set uuid=<UUID> xenstore-data:vm-data/system-account-xoa-password=<password>
|
||||
```
|
||||
|
||||
Where UUID is the uuid of your XOA VM.
|
||||
|
||||
Then you need to restart the VM.
|
||||
You can now login through SSH with the `xoa` username and password you defined in the previous command.
|
||||
|
||||
## Recover web login password
|
||||
|
||||
If you have lost your password to log in to the XOA webpage, you can reset it. From the XOA CLI (for login/access info for the CLI, [see here](xoa.md#first-console-connection)), use the following command and insert the email/account you wish to recover:
|
||||
|
||||
```sh
|
||||
sudo xo-server-recover-account [email protected]
|
||||
```
|
||||
|
||||
It will prompt you to set a new password. If you provide an email here that does not exist in XOA yet, it will create a new account using it, with admin permissions - you can use that new account to log in as well.
|
||||
|
||||
## Empty page after login
|
||||
|
||||
This happens when your antivirus or firewall is blocking the websocket protocol. This is what we use to communicate between `xo-server` and `xo-web` (see the [architecture page](architecture.md)).
|
||||
|
||||
The solution is to use **HTTPS**. When doing so, websockets will be encapsulated in the secured protocol, avoiding interception from your firewall or antivirus system.
|
||||
|
||||
## Migration issues
|
||||
|
||||
By default, XOA has a static max memory set to 16GiB. Sometimes you can have trouble migrating with this error message:
|
||||
|
||||
```
|
||||
"Failed","Migrating VM 'XOA' from '<origin_hostname>' to '<destination_hostname>'
|
||||
Internal error: Xenops_interface.Internal_error("Domain.Xenguest_failure(\"Error while waiting for suspend notification: xenguest: xc_domain_save: [1] Save failed (0 = Success)\")")
|
||||
```
|
||||
|
||||
In this case, it means you need to reduce the static max memory field to a lower value, and try again.
|
||||
|
||||
## Boot issues
|
||||
|
||||
XOA is configured in HVM. It means you need hardware that supports HVM instructions (almost all hardware since 2011). If that's not the case, the symptom is this:
|
||||
|
||||
1. XOA VM starts for few seconds
|
||||
2. Then it shuts down
|
||||
|
||||
Please check that you have enabled virtualization settings in your BIOS or upgrade your hardware.
|
||||
|
||||
## User login
|
||||
|
||||
If you're having trouble logging in, look into `xo-server`'s logs.
|
||||
|
||||
For more information, refer to the [Logs](#logs) section on this page.
|
||||
|
||||
## Logs
|
||||
|
||||
This section will explain how to check the XOA logs, and use them to detect issues.
|
||||
|
||||
### From the web interface
|
||||
|
||||
Go into Settings/Logs view.
|
||||
|
||||
### CLI
|
||||
|
||||
To filter only what you need, you can use `journalctl`. Below is an example to filter only logs for `xo-server`:
|
||||
|
||||
```sh
|
||||
journalctl -u xo-server -f -n 50
|
||||
```
|
||||
|
||||
This will return the 50 last lines and tail the file. If you have an error message in your application, start this command and try to reproduce the issue. You'll see clearly what the problem is.
|
||||
|
||||
You can also filter for the updater program:
|
||||
|
||||
```sh
|
||||
journalctl -u xoa-updater -f -n 50
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
XOA is a virtual appliance running Debian with Xen Orchestra installed. If you have any problems, the first thing to do is to use our check service by running the `xoa check` command in a terminal:
|
||||
|
||||
```console
|
||||
$ xoa check
|
||||
✔ Node version
|
||||
✔ Disk space for /var
|
||||
✔ Disk space for /
|
||||
✔ XOA version
|
||||
✔ xo-server config syntax
|
||||
✔ Appliance registration
|
||||
✔ Internet connectivity
|
||||
```
|
||||
|
||||
If you have something completely different than that, or error messages, lost packets etc., it means you have a problem.
|
||||
|
||||
### Network issues
|
||||
|
||||
You can see your current network configuration by running `ifconfig` (default interface is called `enX0` or `eth0`). If you have an external firewall, please check that you allow the XOA's IP.
|
||||
|
||||
You can modify the IP configuration with `xoa network static` (for a static IP address) or `xoa network dhcp` to use DHCP.
|
||||
|
||||
### Stats not working
|
||||
|
||||
If statistics (all VMs and hosts) are not showing for a specific pool, check if there is a _Backup network_ configured on your pool (setting is in the _Advanced_ tab of the pool) and make sure XO can access all hosts of the pool via this network.
|
||||
|
||||
### Memory
|
||||
|
||||
Sometimes xo-server runs out of memory, this can be seen in the logs (`journalctl -u xo-server.service`):
|
||||
|
||||
```
|
||||
<--- Last few GCs --->
|
||||
48734864 ms: Mark-sweep 1359.7 (1422.6) -> 1359.7 (1438.6) MB, 1675.5 / 0.0 ms [allocation failure] [scavenge might not succeed].
|
||||
48736444 ms: Mark-sweep 1359.7 (1438.6) -> 1359.7 (1438.6) MB, 1579.5 / 0.0 ms [allocation failure] [scavenge might not succeed].
|
||||
48738329 ms: Mark-sweep 1359.7 (1438.6) -> 1368.7 (1422.6) MB, 1885.0 / 0.0 ms [last resort gc].
|
||||
48740025 ms: Mark-sweep 1368.7 (1422.6) -> 1377.7 (1422.6) MB, 1695.0 / 0.0 ms [last resort gc].
|
||||
<--- JS stacktrace --->
|
||||
==== JS stack trace =========================================
|
||||
Security context: 0x12ba820cfb51 <JS Object>
|
||||
1: stringify(aka stringify) [native json.js:178] [pc=0x12d240955b57] (this=0x12ba82004381 <undefined>,E=0x162cbe055041 <an Object with map 0x8ecabcc95a1>,F=0x12ba82004381 <undefined>,S=0x12ba82004381 <undefined>)
|
||||
2: arguments adaptor frame: 1->3
|
||||
3: response [/usr/local/lib/node_modules/xo-server/node_modules/json-rpc-protocol/dist/format.js:~54] [pc=0x12d240cc1301] (this=0x1de505db7...
|
||||
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
|
||||
1: node::Abort() [node]
|
||||
```
|
||||
|
||||
In that case, you need to increase the memory allocated to the XOA VM (from 2GB to 4GB or 8GB). Note that simply increasing the RAM for the VM is not enough. You must also edit the service file (`/etc/systemd/system/xo-server.service`) to increase the memory allocated to the xo-server process itself.
|
||||
|
||||
:::tip
|
||||
You should leave ~512MB for the debian OS itself. Meaning if your VM has 4096MB total RAM, you should use `3584` for the memory value below.
|
||||
|
||||
```diff
|
||||
- ExecStart=/usr/local/bin/xo-server
|
||||
+ ExecStart=/usr/local/bin/node --max-old-space-size=3584 /usr/local/bin/xo-server
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
The last step is to refresh and restart the service:
|
||||
|
||||
```sh
|
||||
systemctl daemon-reload
|
||||
systemctl restart xo-server
|
||||
```
|
||||
|
||||
### Behind a transparent proxy
|
||||
|
||||
If you're behind a transparent proxy, you'll probably have issues with the updater (SSL/TLS issues).
|
||||
|
||||
Run the following commands to allow the updater to work:
|
||||
|
||||
```sh
|
||||
sudo -s
|
||||
echo NODE_TLS_REJECT_UNAUTHORIZED=0 >> /etc/xo-appliance/env
|
||||
npm config -g set strict-ssl=false
|
||||
systemctl restart xoa-updater
|
||||
```
|
||||
|
||||
Now try running an update again.
|
||||
|
||||
### Updating SSL self-signed certificate
|
||||
|
||||
If the provided certificate is expired, you may want to create a new one.
|
||||
|
||||
Connect to your appliance via SSH, then as root execute these commands:
|
||||
|
||||
```sh
|
||||
cd /etc/ssl
|
||||
cp cert.pem cert.pem-old
|
||||
cp key.pem key.pem-old
|
||||
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -nodes -days 360
|
||||
systemctl restart xo-server.service
|
||||
```
|
||||
|
||||
### Ghost tasks
|
||||
|
||||
If you have ghost tasks accumulating in your Xen Orchestra you can try the following actions in order:
|
||||
|
||||
1. refresh the web page
|
||||
1. disconnect and reconnect the Xen pool/server owning the tasks
|
||||
1. restart the XenAPI Toolstack of the XCP-ng/XenServer master
|
||||
1. restart xo-server
|
||||
|
||||
### Redownload and rebuild
|
||||
|
||||
If a package disappears due to a build problem or human error, you can redownload them using the updater:
|
||||
|
||||
1. `rm /var/lib/xoa-updater/update.json`
|
||||
2. `xoa-updater --upgrade`
|
||||
|
||||
:::tip
|
||||
We'll have a `xoa-updater --force-reinstall` option soon, to do this automatically
|
||||
:::
|
||||
|
||||
### Reset configuration
|
||||
|
||||
If you have problems with your `xo-server` configuration, you can reset the database. **This operation will delete all your configured users and servers, plus any backup jobs**:
|
||||
|
||||
1. `redis-cli`
|
||||
2. `FLUSHALL`
|
||||
3. `systemctl restart xo-server.service`
|
||||
|
||||
You can now log in with `[email protected]` and `admin` password.
|
||||
+123
-75
@@ -1,8 +1,12 @@
|
||||
# Users
|
||||
|
||||
:::tip
|
||||
For system users (in XOA), please refer to [XOA section](xoa.md). Here, we are only talking about users in Xen Orchestra application
|
||||
:::
|
||||
<InterfaceNote>This page describes user management in the XO 5 interface. XO 6 currently lists users (with their groups and tokens); creating and editing them still happens here.</InterfaceNote>
|
||||
|
||||
Xen Orchestra involves three distinct notions of "user account". Make sure you are looking at the right one:
|
||||
|
||||
- **XOA system accounts**: the Linux accounts (`xoa`, `root`) of the appliance itself, used for SSH and console access. See [First login](../installation.md#first-login).
|
||||
- **XO application users**: the accounts inside the Xen Orchestra web application. This is what this page is about.
|
||||
- **XO 6 / REST API roles**: XO 6 introduces a new RBAC model with roles and fine-grained privileges. See the [RBAC page](../rbac.md).
|
||||
|
||||
There are 2 types of XO users:
|
||||
|
||||
@@ -29,7 +33,7 @@ This is the default method. Creating a user is very simple:
|
||||
1. Go into the Settings view, select "Users"
|
||||
2. You can create a _user_ or an _admin_, with their password (or generate one)
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/user-creation-form.png" alt="The Users settings view, with the creation form on top and the list of existing accounts below" width={700} />
|
||||
|
||||
By default, a _user_ won't have any permissions. At the opposite, an _admin_ will have all rights.
|
||||
|
||||
@@ -43,9 +47,13 @@ To activate two-factor authentication on your account:
|
||||
|
||||
1. Go to your profile settings.
|
||||
2. At the top of the screen, go to the **OTP authentication** field and toggle the switch to the **On** position.
|
||||

|
||||
|
||||
<UiDetail src="/img/xo5/totp-toggle.png" alt="The user profile page, with the OTP authentication toggle at the top" width={700} />
|
||||
|
||||
3. A window will appear displaying a **QR code**:
|
||||

|
||||
|
||||
<UiDetail src="/img/xo5/totp-qr-code.png" alt="The QR code modal shown when enabling TOTP on a user account" width={620} />
|
||||
|
||||
4. Open your preferred authentication app on your mobile device and **scan the QR code**.
|
||||
5. The app will generate a temporary 6-digit code.
|
||||
6. Enter this code into the **OTP code** field in the Xen Orchestra window.
|
||||
@@ -61,16 +69,19 @@ To disable this feature, return to your profile settings and toggle the **OTP au
|
||||
|
||||
### LDAP
|
||||
|
||||
XO currently supports connections to LDAP directories, like _Open LDAP_ or _Active Directory_.
|
||||
XO currently supports connections to LDAP directories, like _Open LDAP_ or _Active Directory_, through the `auth-ldap` plugin.
|
||||
|
||||
1. **Access the Plugin**:
|
||||
1. **Access the plugin**:
|
||||
1. Navigate to the **Settings → Plugins** screen.
|
||||
2. Locate the **auth-ldap plugin** by scrolling or using the search bar.
|
||||
2. **Configure LDAP Settings**:
|
||||
1. Click **+** button for the LDAP plugin.\
|
||||
A list of settings appears: 
|
||||
2. Fill in the required fields based on your LDAP server details.
|
||||
3. **Save and Activate**:
|
||||
2. **Configure LDAP settings**:
|
||||
1. Click the **+** button for the LDAP plugin.\
|
||||
A list of settings appears:
|
||||
|
||||
<UiDetail src="/img/xo5/ldap-plugin-config.png" alt="The auth-ldap plugin settings: URI, certificates, base, credentials, user filter and ID attribute" width={620} />
|
||||
|
||||
2. Fill in the required fields based on your LDAP server details: the **URI** of the server, the **Base** where users are looked for, the **User filter** and the **ID attribute** (which must be unique and stable, e.g. `dn`). Optional fields cover failover URIs, certificate authorities and certificate checking, StartTLS and the credentials used to search the directory.
|
||||
3. **Save and activate**:
|
||||
1. Click **Save configuration**.
|
||||
2. To check if the plugin is activated, activate the toggle switch next to the **auth-ldap** plugin name.\
|
||||
The switch should now appear green.
|
||||
@@ -99,7 +110,7 @@ The LDAP plugin allows for the synchronization of user groups.
|
||||
A list of text fields appear.
|
||||
3. Fill out the fields according to the picture below:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/ldap-group-sync-config.png" alt="The Synchronize groups section of the auth-ldap plugin, with base, filter, ID and display name attributes" width={620} />
|
||||
|
||||
2. **Basic group settings**:
|
||||
- **Base** and **Filter**: Similar to the user configuration. The plugin needs an entry point in the directory and a filter to find the groups.
|
||||
@@ -114,7 +125,7 @@ For example, here's an LDAP directory:
|
||||
|
||||
**User:**
|
||||
|
||||
```
|
||||
```text
|
||||
objectClass: Person
|
||||
cn: Bruce Wayne
|
||||
uid: 347
|
||||
@@ -123,7 +134,7 @@ uid: 347
|
||||
|
||||
**Group:**
|
||||
|
||||
```
|
||||
```text
|
||||
objectClass: Group
|
||||
cn: heroes
|
||||
displayName: Heroes
|
||||
@@ -200,9 +211,9 @@ In this section, you'll learn:
|
||||
|
||||
On the Xen Orchestra login page, click **Sign in with OpenID Connect**
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/oidc-signin-button.png" alt="The XO login page with the Sign in with OpenID Connect button" width={300} />
|
||||
|
||||
You’ll be redirected to the login page of your internal portal. Once authenticated on it, you will be redirected to the Xen Orchestra home page.
|
||||
You'll be redirected to the login page of your internal portal. Once authenticated on it, you will be redirected to the Xen Orchestra home page.
|
||||
|
||||
#### Administrator Guide
|
||||
|
||||
@@ -214,18 +225,24 @@ You can set up the `auth-oidc` plugin directly in Xen Orchestra:
|
||||
2. Find the `auth-oidc` plugin in the list.
|
||||
3. Click **+** next to the plugin name to expand the configuration options.
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/oidc-plugin-config.png" alt="The auth-oidc plugin configuration: auto-discovery URL, client identifier and client secret" width={620} />
|
||||
|
||||
##### Required Configuration
|
||||
|
||||
Fill in the mandatory fields. You can also specify the auto-discovery URL, if needed.
|
||||
Fill in the mandatory fields: the **Client identifier (key)** and **Client secret** from your identity provider. You also need to tell the plugin where to find your provider's endpoints, either way:
|
||||
|
||||
- **Auto-discovery URL**: the OIDC discovery URL provided by your identity provider (the simplest option), or
|
||||
- the **Advanced** section, by filling the **Authorization URL**, **Issuer**, **Token URL** and **User info URL** manually.
|
||||
|
||||
##### Advanced Configuration (Optional)
|
||||
|
||||
To access advanced options:
|
||||
|
||||
1. Check **Fill information (optional)** to reveal additional fields.
|
||||
2. Complete the fields as needed.
|
||||
2. Complete the fields as needed:
|
||||
- **Callback URL**: the redirect URI for OIDC responses (defaults to `/signin/oidc/callback`).
|
||||
- **Username field**: the field to use as the XO username, e.g. `displayName`, `username` or `email` (defaults to `username`).
|
||||
- **Scopes**: the scopes from which to request profile information, separated by whitespace (defaults to `profile`; the `openid` scope is implicitly included).
|
||||
|
||||
##### Save and Activate the Plugin
|
||||
|
||||
@@ -243,15 +260,15 @@ The TLS certificates used by Keycloak must satisfy the following conditions:
|
||||
|
||||
- **Common Name (CN)**: The CN of the certificate has to match the DNS name that clients will use to reach Keycloak.
|
||||
- **SubjectAltName (SAN)**: The certificate must contain a SAN entry with the same DNS name.
|
||||
- **Certificate chain**: The certificate must be issued by a trusted CA. The `auth‑oidc` plugin does not accept self‑signed certificates that lack a proper chain of trust.
|
||||
- **Certificate chain**: The certificate must be issued by a trusted CA. The `auth-oidc` plugin does not accept self-signed certificates that lack a proper chain of trust.
|
||||
|
||||
:::info
|
||||
The TLS certificate must match the domain that will be used as the _Relying Party ID_ (RP ID). The RP ID cannot be an IP address; it must be the DNS‑name that appears in the certificate’s CN or SAN.
|
||||
The TLS certificate must match the domain that will be used as the _Relying Party ID_ (RP ID). The RP ID cannot be an IP address; it must be the DNS name that appears in the certificate's CN or SAN.
|
||||
:::
|
||||
|
||||
Here is a certificate that meets these requirements:
|
||||
|
||||
```
|
||||
```text
|
||||
Version: 3 (0x02)
|
||||
Serial number: 7096756171258138755 (0x627cbe2335671083)
|
||||
Algorithm ID: SHA256withRSA
|
||||
@@ -271,11 +288,11 @@ With this configuration, Keycloak can participate in passkey authentication flow
|
||||
|
||||
###### Trust the Keycloak cert in XOA
|
||||
|
||||
1. Place the CA certificate used to sign Keycloak’s cert on the xo-server host (e.g., `/etc/ssl/poc.crt`).
|
||||
2. Edit the xo-server systemd service at `/etc/systemd/system/xo-server.service` to add the environment variable `NODE_EXTRA_CA_CERTS`.
|
||||
1. Place the CA certificate used to sign Keycloak's cert on the xo-server host (e.g., `/etc/ssl/poc.crt`).
|
||||
2. Edit the xo-server systemd service at `/etc/systemd/system/xo-server.service` to add the environment variable `NODE_EXTRA_CA_CERTS`:
|
||||
|
||||
```
|
||||
[07:21 10] xoa:~$ cat /etc/systemd/system/xo-server.service
|
||||
<Terminal shell title="xoa: xo-server unit with the extra CA certificate">{`
|
||||
cat /etc/systemd/system/xo-server.service
|
||||
# systemd service for XO-Server.
|
||||
[Unit]
|
||||
Description= XO Server
|
||||
@@ -288,20 +305,25 @@ TimeoutStopSec=4s
|
||||
Environment="NODE_EXTRA_CA_CERTS=/etc/ssl/poc.crt"
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
`}</Terminal>
|
||||
|
||||
###### Configuring Keycloak
|
||||
|
||||
1. Select your realm.
|
||||
- Open **Admin console → Manage realms** and choose the realm you use with XOA.
|
||||
2. Enable required actions.
|
||||
- Go to **Authentication → Required Actions**.
|
||||
- Check **Webauthn Register** and **Webauthn Register Passwordless**.
|
||||
3. Choose the WebAuthn authenticator.
|
||||
- In **Authentication → Flows**, edit the login flow you use (e.g., browser).
|
||||
- Add **WebAuthn Authenticator** as an **Alternative** (or replace the current authenticator with it).
|
||||
|
||||

|
||||
- Open **Admin console → Manage realms** and choose the realm you use with XOA.
|
||||
|
||||
2. Enable required actions.
|
||||
|
||||
- Go to **Authentication → Required Actions**.
|
||||
- Check **Webauthn Register** and **Webauthn Register Passwordless**.
|
||||
|
||||
3. Choose the WebAuthn authenticator.
|
||||
|
||||
- In **Authentication → Flows**, edit the login flow you use (e.g., browser).
|
||||
- Add **WebAuthn Authenticator** as an **Alternative** (or replace the current authenticator with it).
|
||||
|
||||
<UiDetail src="/img/xo5/keycloak-browser-flow.png" alt="The Keycloak browser flow details, with the WebAuthn Authenticator step added as an alternative" width={700} />
|
||||
|
||||
4. Disable OTP if not needed
|
||||
|
||||
@@ -313,32 +335,43 @@ These settings allow users to register and log in with FIDO2 (passkeys) while ke
|
||||
|
||||
1. Initiate the OIDC authentication request from the XOA client to Keycloak.
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/keycloak-passkey-flow-1.png" alt="XOA redirecting the OIDC authentication request to Keycloak" width={700} />
|
||||
|
||||
2. The user supplies their username and password at the Keycloak login screen.
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/keycloak-passkey-flow-2.png" alt="The Keycloak login screen asking for username and password" width={700} />
|
||||
|
||||
3. After credential validation, Keycloak presents a second‑factor challenge (User Verification or User Presence) that requires the user to press their Yubikey to complete the authentication.
|
||||
3. After credential validation, Keycloak presents a second-factor challenge (User Verification or User Presence) that requires the user to press their Yubikey to complete the authentication.
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/keycloak-passkey-flow-3.png" alt="The Keycloak second-factor challenge waiting for the security key" width={700} />
|
||||
|
||||
### SAML
|
||||
|
||||
This plugin allows SAML users to authenticate to Xen-Orchestra.
|
||||
The `auth-saml` plugin allows SAML users to authenticate to Xen Orchestra.
|
||||
|
||||
The first time a user signs in, XO will create a new XO user with the same identifier.
|
||||
|
||||
#### Configuration
|
||||
|
||||
:::warning
|
||||
When registering your Xen Orchestra instance to your identity provider, you must configure its callback URL to `https://<xo.company.net>/signin/saml/callback`!
|
||||
:::
|
||||
|
||||
In the "Settings" then "Plugins" view, expand the SAML plugin configuration. Then provide the needed fields:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/saml-plugin-config.png" alt="The auth-saml plugin configuration: certificate, entry point, issuer and username field" width={700} />
|
||||
|
||||
- **Certificate**: copy/paste the identity provider's certificate.
|
||||
- **Entry point**: entry point of the identity provider.
|
||||
- **Issuer**: issuer string to supply to the identity provider.
|
||||
- **Username field**: field to use as the XO username. Try `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress` if you are using Microsoft Entra ID (Azure Active Directory).
|
||||
|
||||
Optional settings let you disable the requested authentication context (known to help with Active Directory), force re-authentication, and require signed assertions or signed responses.
|
||||
|
||||
Save the configuration and then activate the plugin (button on top).
|
||||
|
||||
:::warning
|
||||
Since 5.111.1 version, you need to configure signature for Document **and** Assertion in your SAML Identity Provider.
|
||||
Since XO 5.111.1, you need to configure signature for Document **and** Assertion in your SAML Identity Provider: either the response or the assertion must be signed.
|
||||
|
||||
- **Keycloak:** In Client Settings, Signature and Encryption, check "Sign Documents" and "Sign Assertion".
|
||||
- **Azure:** In SAML Signing Certificate options, select **Sign SAML response and assertion**.
|
||||
@@ -347,9 +380,9 @@ Since 5.111.1 version, you need to configure signature for Document **and** Asse
|
||||
|
||||
#### Vendor specific
|
||||
|
||||
##### Google Workspace - SAML [support.google.com](https://support.google.com/a/answer/6087519?hl=en#zippy=)
|
||||
##### Google Workspace {#google-workspace---saml-supportgooglecom}
|
||||
|
||||
Use the screenshots below as a reference as how to setup SAML with Google Workspace.
|
||||
Google documents its SAML setup on [support.google.com](https://support.google.com/a/answer/6087519?hl=en#zippy=). Use the screenshots below as a reference as how to set up SAML with Google Workspace.
|
||||
|
||||
1. Sign in to your [Google Workspace Admin Dashboard](https://admin.google.com).
|
||||
2. Go to **Apps/Web and mobile apps**
|
||||
@@ -357,20 +390,25 @@ Use the screenshots below as a reference as how to setup SAML with Google Worksp
|
||||
4. Give your app a name and optionally a description.
|
||||
5. To see how the fields should be filled out, refer to the screenshots below.
|
||||
|
||||
> Note: Right now even when the authorization is successful, you will be redirected to the `https://xo.company.net/signin` page. However, just browse directly into the bare URL `https://xo.company.net`, and you'll now be logged in and can use the XO-dashboard.
|
||||
:::note
|
||||
Right now even when the authorization is successful, you will be redirected to the `https://xo.company.net/signin` page. However, just browse directly into the bare URL `https://xo.company.net`, and you'll now be logged in and can use the XO dashboard.
|
||||
:::
|
||||
|
||||
> If you get a certificate error. Try to add a newline at the bottom of the Certificate field in Xen Orchestra.
|
||||
:::tip
|
||||
If you get a certificate error, try to add a newline at the bottom of the Certificate field in Xen Orchestra.
|
||||
:::
|
||||
|
||||
The first login will create the user inside XO, as a non-privileged user. An administrator then has to promote the user to the appropriate group. (XO: Settings/Users).
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/saml-google-workspace-app-details.png" alt="The Google Workspace custom SAML app details, side by side with the matching XO plugin fields" width={700} />
|
||||
|
||||
Also make sure to adjust the SAML attribute mapping in the Google Workspace configuration. (Primary email -> email)
|
||||

|
||||
|
||||
<UiDetail src="/img/xo5/saml-google-workspace-attribute-mapping.png" alt="The Google Workspace SAML attribute mapping, with Primary email mapped to email" width={620} />
|
||||
|
||||
### GitHub
|
||||
|
||||
This plugin allows any GitHub user to authenticate to Xen Orchestra.
|
||||
The `auth-github` plugin allows any GitHub user to authenticate to Xen Orchestra.
|
||||
|
||||
The first time a user signs in, XO will create a new XO user with the same identifier (i.e. GitHub name), with _user_ permissions. An existing admin will need to apply the appropriate permissions for your environment.
|
||||
|
||||
@@ -380,19 +418,19 @@ First you need to configure a new app in your GitHub account. Go to your GitHub
|
||||
2. Enter your Xen Orchestra URL (or IP) under "Homepage URL"
|
||||
3. Add your "Authorization callback URL" (for example, https://homepageUrl/signin/github/callback)
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/github-oauth-app-form.png" alt="The GitHub OAuth App registration form, with the XO homepage and callback URLs filled in" width={620} />
|
||||
|
||||
When you get your Client ID and your Client secret, you can configure them in the GitHub Plugin inside the "Settings/Plugins" view of Xen Orchestra.
|
||||
When you get your Client ID and your Client secret, you can configure them in the GitHub plugin inside the "Settings/Plugins" view of Xen Orchestra. They are the only two fields to fill in.
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/github-plugin-config.png" alt="The auth-github plugin configuration, with the Client ID and Client secret fields" width={620} />
|
||||
|
||||
Be sure to activate the plugin after you save the configuration (button on top). When it's done, you'll see a link in the login view, this is where you'll go to authenticate:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/github-signin-link.png" alt="The XO login page with the GitHub sign in link below the credentials form" width={620} />
|
||||
|
||||
### Google
|
||||
|
||||
This plugin allows Google users to authenticate to Xen-Orchestra.
|
||||
The `auth-google` plugin allows Google users to authenticate to Xen Orchestra.
|
||||
|
||||
The first time a user signs in, XO will create a new XO user with the same identifier, without any permissions.
|
||||
|
||||
@@ -400,22 +438,30 @@ The first time a user signs in, XO will create a new XO user with the same ident
|
||||
|
||||
Go to Google's [Credentials page](https://console.developers.google.com/apis/credentials) and create a new project:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/google-create-project.png" alt="Creating a new project in the Google developer console" width={620} />
|
||||
|
||||
Configure an OAuth consent screen if requested then create OAuth 2.0 credentials:
|
||||
|
||||

|
||||

|
||||
<UiDetail src="/img/xo5/google-create-oauth-credentials.png" alt="The Create credentials menu, with OAuth client ID selected" width={620} />
|
||||
|
||||
<UiDetail src="/img/xo5/google-oauth-client-form.png" alt="The OAuth client creation form, with the authorized redirect URI pointing to the XO callback" width={620} />
|
||||
|
||||
Get your client ID and client secret:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/google-client-id-secret.png" alt="The modal displaying the generated OAuth client ID and client secret" width={480} />
|
||||
|
||||
#### Configure the XO plugin
|
||||
|
||||
In Settings, then Plugins, expand the Google plugin details and configure it with the information from the Google Console:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/google-plugin-config.png" alt="The auth-google plugin configuration: callback URL, client ID and client secret" width={620} />
|
||||
|
||||
- **Callback URL**: must be exactly the same as specified on the Google developer console.
|
||||
- **Client ID** and **Client secret**: the credentials generated above.
|
||||
|
||||
:::warning
|
||||
The optional **scope** setting selects which profile information is used to build the XO username (Google+ name or simple email address). Changing this value after users started logging in will break existing users.
|
||||
:::
|
||||
|
||||
Be sure to activate the plugin after you save the configuration (button on top).
|
||||
|
||||
@@ -427,20 +473,24 @@ You can now connect with your Google account in the login page.
|
||||
|
||||
ACLs are permissions that apply to preexisting objects, like users and groups.
|
||||
|
||||
:::note
|
||||
This section describes the original ACLs, used by the XO 5 interface. The REST API and XO 6 use a broader model: see [RBAC](../rbac.md).
|
||||
:::
|
||||
|
||||
### Who can manage ACLs?
|
||||
|
||||
Only a super admin (XO administrator) can manage ACLs.
|
||||
|
||||
### How can I view and edit ACLs?
|
||||
|
||||
The ACLs view can be accessed in the **Setting** panel.
|
||||
The ACLs view can be accessed in the **Settings** panel.
|
||||
|
||||
1. Select the user or group you want to apply permissions on
|
||||
2. Select the object on which the permission will apply
|
||||
3. Choose the role for this ACL
|
||||
4. Click the **Create** button.
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/acl-creation.png" alt="The ACL creation form: subject, object and role selectors followed by the Create button" width={700} />
|
||||
|
||||
:::tip
|
||||
You can click to add multiple objects at the same time!
|
||||
@@ -448,7 +498,7 @@ You can click to add multiple objects at the same time!
|
||||
|
||||
Your ACL is now available in the right list:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/acl-list.png" alt="The list of existing ACLs, each row showing the user, the object and the assigned role" width={620} />
|
||||
|
||||
You can edit or remove existing ACLs here.
|
||||
|
||||
@@ -506,13 +556,13 @@ If the OS install needs an ISO, you need to give this user 2 permissions:
|
||||
|
||||
## Self-service portal
|
||||
|
||||
The self-service feature allows users to create new VMs. This is different from delegating existing resources (VM's) to them, and it leads to a lot of possibilities.
|
||||
The self-service feature allows users to create new VMs. This is different from delegating existing resources (VMs) to them, and it leads to a lot of possibilities.
|
||||
|
||||
### Set of resources
|
||||
|
||||
To create a new set of resources to delegate, go to the "Self Service" section in the main menu:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/self-service-menu.png" alt="The Self Service entry in the XO main menu" width={180} />
|
||||
|
||||
#### Create a set
|
||||
|
||||
@@ -530,7 +580,7 @@ In this example below, we'll create a set called **"sandbox"** with:
|
||||
- "SSD NFS" is the only SR where they can create VMs
|
||||
- "Pool-wide network with eth0" is the only available network for them
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/self-service-set-creation.png" alt="The resource set creation form: name, subjects, pools, templates, SRs, networks and limits, with the eligible hosts below" width={700} />
|
||||
|
||||
As you can see, only compatible hosts are shown and can be used for this resource set (hosts in another pool aren't shown). This way, you can be sure to have resources free for tasks other than self-service.
|
||||
|
||||
@@ -556,21 +606,21 @@ A snapshot of a Self Service VM will use as much resources as a VM would. You ca
|
||||
|
||||
When you click on create, you can see the resource set and remove or edit it:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/self-service-set-quotas.png" alt="The saved resource set recap, with its quota gauges for CPUs, RAM and disk usage" width={700} />
|
||||
|
||||
### Usage (user side)
|
||||
|
||||
As soon as a user is granted a resource set, it displays a new button in their main view: "new".
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/self-service-new-vm-button.png" alt="The New button displayed in the user's main menu" width={160} />
|
||||
|
||||
Now, the user can create a VM with only the resources granted in the set:
|
||||
|
||||

|
||||
<UiShot light="/img/xo5/self-service-vm-creation.png" alt="The VM creation page restricted to the sandbox resource set: only the delegated template, SR and network are selectable" url="https://your-xo/v5/#/vms/new" />
|
||||
|
||||
And the recap before creation:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/self-service-quota-summary.png" alt="The summary gauges showing how much of the set's quota the new VM will consume" width={700} />
|
||||
|
||||
If the "Create" button is disabled, it means the user requested more resources than available.
|
||||
|
||||
@@ -586,8 +636,6 @@ Self-service is a major step in the Cloud. Combine it with our [Cloudinit compat
|
||||
|
||||
Now, your authorized users can create VMs with their SSH keys, grow template disks if needed, etc. Everything is inside a "sandbox" (the resource set) you defined earlier!
|
||||
|
||||

|
||||
|
||||
## Audit log
|
||||
|
||||
XO Audit Log is a plugin that records all important actions performed by users and provides the administrators an overview of each action. This gives them an idea of the users behavior regarding their infrastructure in order to track suspicious activities.
|
||||
@@ -612,10 +660,10 @@ The recording of the users' actions is disabled by default. To enable it:
|
||||
2. expand the `audit` configuration
|
||||
3. toggle active and save the configuration
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/audit-log-plugin-config.png" alt="The audit plugin configuration, with the active toggle enabled" width={620} />
|
||||
|
||||
Now, the audit plugin will record users' actions and upload the last record in the chain every day at **06:00 AM (UTC)**.
|
||||
|
||||
## Debugging
|
||||
|
||||
If you can't log in, please [check the logs of `xo-server`](https://docs.xen-orchestra.com/troubleshooting#logs).
|
||||
If you can't log in, please [check the logs of `xo-server`](../troubleshooting.md#logs).
|
||||
|
||||
@@ -1,19 +1,60 @@
|
||||
# V2V Migration Guide
|
||||
---
|
||||
sidebar_label: VMware migration (V2V)
|
||||
---
|
||||
|
||||
## 📌 Introduction
|
||||
# VMware migration (V2V)
|
||||
|
||||
Xen Orchestra 5.110 introduced a new migration backend for moving virtual machines from VMware to Vates (V2V). This replaces the old NFS-based method and now uses `nbdkit` alongside VMware’s VDDK libraries, delivering improved performance and reliability.
|
||||
## Introduction {#-introduction}
|
||||
|
||||
Xen Orchestra 5.110 introduced a new migration backend for moving virtual machines from VMware to XCP-ng (V2V). It replaces the old NFS-based method with `nbdkit` and VMware's VDDK libraries, delivering better performance and reliability.
|
||||
|
||||
The whole process is driven from Xen Orchestra, in **Import → VM → From VMware**. XO connects to your vCenter or ESXi host, reads the VM disks directly, and imports them into an XCP-ng storage repository:
|
||||
|
||||
<Schema label="XO reads the VM disks from ESXi through nbdkit and the VDDK libraries, and imports them into an XCP-ng pool. The source VM keeps running during most of the transfer" legend={[["#5ac8c8", "VMware"], ["#8e83fe", "XCP-ng"], ["#6aabf0", "XO"]]} maxWidth="640px">
|
||||
<svg viewBox="0 0 640 240" role="img" aria-label="A VM running on an ESXi host inside a VMware infrastructure is exported by Xen Orchestra using nbdkit and VDDK, then imported into an XCP-ng host in the destination pool, where the migrated VM is ready to boot; the source VM keeps running during the warm phase of the transfer">
|
||||
<rect x="16" y="40" width="192" height="168" rx="8" fill="none" stroke="rgba(255,255,255,0.22)" strokeDasharray="6 5" />
|
||||
<text x="28" y="62" fill="#c6d2e1" fontSize="12">VMware</text>
|
||||
<text x="28" y="78" fill="#7a8699" fontSize="10">source infrastructure</text>
|
||||
<rect x="32" y="92" width="160" height="100" rx="6" fill="rgba(255,255,255,0.04)" stroke="#5ac8c8" />
|
||||
<text x="112" y="110" fill="#c6d2e1" fontSize="10" textAnchor="middle">ESXi host</text>
|
||||
<rect x="54" y="122" width="116" height="46" rx="6" fill="rgba(90,200,200,0.12)" stroke="#5ac8c8" />
|
||||
<text x="112" y="141" fill="#c6d2e1" fontSize="12" textAnchor="middle">VM</text>
|
||||
<text x="112" y="157" fill="#7a8699" fontSize="9" textAnchor="middle">keeps running</text>
|
||||
<line x1="194" y1="134" x2="252" y2="134" stroke="#5ac8c8" strokeWidth="2" className="schema-flow" strokeDasharray="5 4" />
|
||||
<polygon points="262,134 252,128 252,140" fill="#5ac8c8" />
|
||||
<text x="228" y="122" fill="#5ac8c8" fontSize="9" textAnchor="middle">export</text>
|
||||
<rect x="266" y="108" width="108" height="52" rx="6" fill="rgba(255,255,255,0.04)" stroke="#6aabf0" />
|
||||
<text x="320" y="129" fill="#c6d2e1" fontSize="11" textAnchor="middle">Xen Orchestra</text>
|
||||
<text x="320" y="146" fill="#7a8699" fontSize="9" textAnchor="middle">nbdkit + VDDK</text>
|
||||
<text x="320" y="182" fill="#7a8699" fontSize="9" textAnchor="middle">reads only allocated blocks</text>
|
||||
<line x1="378" y1="134" x2="430" y2="134" stroke="#56c288" strokeWidth="2" className="schema-flow" strokeDasharray="5 4" />
|
||||
<polygon points="440,134 430,128 430,140" fill="#56c288" />
|
||||
<text x="404" y="122" fill="#56c288" fontSize="9" textAnchor="middle">import</text>
|
||||
<rect x="432" y="40" width="192" height="168" rx="8" fill="none" stroke="rgba(255,255,255,0.22)" strokeDasharray="6 5" />
|
||||
<text x="444" y="62" fill="#c6d2e1" fontSize="12">XCP-ng pool</text>
|
||||
<text x="444" y="78" fill="#7a8699" fontSize="10">destination</text>
|
||||
<rect x="448" y="92" width="160" height="100" rx="6" fill="rgba(255,255,255,0.04)" stroke="#8e83fe" />
|
||||
<text x="528" y="110" fill="#c6d2e1" fontSize="10" textAnchor="middle">XCP-ng host</text>
|
||||
<rect x="470" y="122" width="116" height="46" rx="6" fill="rgba(86,194,136,0.12)" stroke="#56c288" />
|
||||
<text x="528" y="141" fill="#c6d2e1" fontSize="12" textAnchor="middle">VM</text>
|
||||
<text x="528" y="157" fill="#7a8699" fontSize="9" textAnchor="middle">ready to boot</text>
|
||||
</svg>
|
||||
</Schema>
|
||||
|
||||
This guide walks you through the entire migration process:
|
||||
|
||||
- Preparing your Xen Orchestra environment
|
||||
- Preparing your VMware environment
|
||||
- Installing the required components
|
||||
- Running a test migration
|
||||
- Executing the final cutover
|
||||
|
||||
You’ll also find troubleshooting advice and best practices to maximize speed and minimize downtime.
|
||||
You will also find troubleshooting advice and best practices to maximize speed and minimize downtime.
|
||||
|
||||
## 🎁 Benefits
|
||||
:::note
|
||||
The V2V import is currently available in the XO 5 interface. The new XO 6 web UI does not expose it yet: even if you use XO 6 daily, switch to the XO 5 interface for the migration itself.
|
||||
:::
|
||||
|
||||
## Benefits {#-benefits}
|
||||
|
||||
### In short
|
||||
|
||||
@@ -27,14 +68,16 @@ The new V2V backend replaces the old approach, and delivers:
|
||||
|
||||
#### Ease of use and compatibility
|
||||
|
||||
The new backend only reads allocated blocks, which accelerates transfers, and snapshots have minimal impact on performance. There’s no longer any need for temporary NFS storage or remote VSAN targets. The system is also built to handle very large disks, with support for sizes beyond 2 TB planned in a future update.
|
||||
The new backend only reads allocated blocks, which accelerates transfers, and snapshots have minimal impact on performance. There is no longer any need for temporary NFS storage or remote VSAN targets. Very large disks are handled natively: disks bigger than the 2 TB VHD limit are automatically imported in the QCOW2 format, provided the destination storage repository supports it.
|
||||
|
||||
#### UI improvements
|
||||
|
||||
The interface has also seen significant improvements: a **progress bar** is now visible from the start of migration, **speed metrics** are recorded in the VDI, and **snapshots** are created at each step. This allows you to pause and resume the process safely without creating multiple VMs.
|
||||
The interface has also seen significant improvements: a **progress bar** is now visible from the start of the migration, **speed metrics** are recorded in the VDI, and **snapshots** are created at each step. This allows you to pause and resume the process safely without creating multiple VMs. The import is **cancellable**, and the connection settings are remembered by your browser between sessions.
|
||||
|
||||
Additionally, UEFI VMs are no longer forced into Secure Boot mode, which resolves previous boot issues.
|
||||
|
||||
Recent releases keep improving the workflow: since XO 6.6, a CD-ROM drive present on the source is recreated on the destination VM, and a two-step transfer (a first warm pass followed by a final run) tells you upfront whether the next run will be a full or a delta transfer.
|
||||
|
||||
#### Performance gains
|
||||
|
||||
Performance gains can be significant, though results depend on the environment:
|
||||
@@ -43,17 +86,18 @@ Performance gains can be significant, though results depend on the environment:
|
||||
|
||||
- **In less favorable situations**, such as a fully allocated disk with no snapshots and a powered-off VM, improvements are smaller, mainly due to compression between XO and ESXi. In general, the limiting factor is the import speed on the XCP-ng side, which scales well until the storage is saturated. Most of the transfer occurs while the VM is running, so production data remains safe.
|
||||
|
||||
## 👨🍳 Preparing the XO environment
|
||||
## Preparing the XO environment {#-preparing-the-xo-environment}
|
||||
|
||||
### Update Xen Orchestra
|
||||
|
||||
Make sure your Xen Orchestra instance is up to date. The import page now includes an automatic check that highlights errors and warnings before migration. Errors must be resolved, and warnings should be addressed when possible.
|
||||
Make sure your Xen Orchestra instance is up to date. The import page includes an automatic check that verifies the installed versions of `nbdkit`, the VDDK plugin and `nbdinfo`, and highlights errors and warnings before the migration. Errors must be resolved, and warnings should be addressed when possible.
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/v2v-prerequisite-check.png" alt="The prerequisite check on the import page, listing nbdkit, the VDDK plugin and nbdinfo with their status" width={480} />
|
||||
|
||||
### Dependencies
|
||||
|
||||
Install the following dependencies:
|
||||
|
||||
- `nbdkit`
|
||||
- The VDDK plugin
|
||||
- `nbdinfo`
|
||||
@@ -70,22 +114,29 @@ To install `nbdinfo` on Debian:
|
||||
|
||||
1. Go to the **Import → VM → From VMware** section.
|
||||
2. Click the button called **install nbdinfo (debian based system)**:
|
||||

|
||||
This starts the install.
|
||||
|
||||
<UiDetail src="/img/xo5/v2v-install-nbdinfo-button.png" alt="The install nbdinfo (debian based system) button on the From VMware import page" width={620} />
|
||||
|
||||
This starts the install.
|
||||
|
||||
3. Keep an eye on the current page to make sure the install goes as planned.
|
||||
- The **install nbdinfo** button will update to show the installation progress, and the page will display any warnings in real time as they appear:
|
||||

|
||||
- Additionally, the **Task** screen shows the `nbdinfo` install task, with its name, start date, start time and status indicator:
|
||||

|
||||
Thes task will be removed from the list upon completion.
|
||||
- The **install nbdinfo** button updates to show the installation progress, and the page displays any warnings in real time as they appear:
|
||||
|
||||
<UiDetail src="/img/xo5/v2v-nbdinfo-progress-import.png" alt="The import page while the nbdinfo installation task is running, with warnings shown in real time" width={620} />
|
||||
|
||||
- Additionally, the **Tasks** screen shows the `nbdinfo` install task, with its name, start date, start time and status indicator:
|
||||
|
||||
<UiDetail src="/img/xo5/v2v-nbdinfo-progress-tasks.png" alt="The Tasks screen showing the running nbdinfo install task with its status indicator" width={620} />
|
||||
|
||||
The task is removed from the list upon completion.
|
||||
|
||||
4. Once the installation finishes, the `nbdinfo` install screen updates automatically. It lets you know if everything was completed successfully and flags any warnings that came up during the process:
|
||||

|
||||
|
||||
:::tip
|
||||
`nbdkit` and the `nbdkit-plugin-vddk` are installed using the same approach.
|
||||
:::
|
||||
<UiDetail src="/img/xo5/v2v-nbdinfo-install-complete.png" alt="The import page after a completed nbdinfo installation, with the final status and warnings" width={620} />
|
||||
|
||||
:::tip
|
||||
`nbdkit` and the `nbdkit-plugin-vddk` are installed using the same approach.
|
||||
:::
|
||||
|
||||
#### Installing the other dependencies
|
||||
|
||||
@@ -96,47 +147,54 @@ You can compile `nbdkit` and `libnbd` from source on GitLab, but the correct dep
|
||||
##### Installing VDDK
|
||||
|
||||
1. Download the VMware Virtual Disk Development Kit (VDDK) from the [Broadcom developer portal](https://developer.broadcom.com/sdks/vmware-virtual-disk-development-kit-vddk/9.0?ref=xen-orchestra.com).
|
||||
2. Select the *tar.gz* archive, then drag and drop it directly into the Xen Orchestra interface:
|
||||

|
||||
An **install button** will appear.
|
||||
3. Click the button:
|
||||

|
||||
The installation should take just a few seconds.
|
||||
Once the installation is done, a **transfer form** will appear.:
|
||||

|
||||
:::warning
|
||||
Filling in this form and clicking the **Connect** button will start the VM import. However, make sure your VMware environment is ready!
|
||||
2. Select the _tar.gz_ archive, then drag and drop it directly into the Xen Orchestra interface:
|
||||
|
||||
Read [Preparing the VMware Environment](#-preparing-the-vmware-environment) to know more.
|
||||
<UiDetail src="/img/xo5/v2v-upload-vddk.png" alt="The import page with the drop zone used to upload the VDDK tar.gz archive" width={620} />
|
||||
|
||||
An **install button** will appear.
|
||||
|
||||
3. Click the button:
|
||||
|
||||
<UiDetail src="/img/xo5/v2v-install-vddk-button.png" alt="The button confirming the installation of the uploaded VDDK archive" width={620} />
|
||||
|
||||
The installation should take just a few seconds. Once it is done, a **transfer form** will appear:
|
||||
|
||||
<UiDetail src="/img/xo5/v2v-transfer-form.png" alt="The transfer form used to connect to VMware and import a VM into Xen Orchestra" width={620} />
|
||||
|
||||
:::warning
|
||||
Filling in this form and clicking the **Connect** button will start the VM import. Make sure your VMware environment is ready first!
|
||||
|
||||
Read [Preparing the VMware environment](#-preparing-the-vmware-environment) to know more.
|
||||
:::
|
||||
|
||||
## 👨🍳 Preparing the VMware Environment
|
||||
## Preparing the VMware environment {#-preparing-the-vmware-environment}
|
||||
|
||||
### Prerequisites
|
||||
|
||||
Before starting the migration, make sure your VMware environment meets the following conditions:
|
||||
|
||||
#### Network
|
||||
XO must be able to connect to the vsphere/esxi through the port running the web UI (default port: 443) and vddk (default port: 902). At the time of writing, there is no solution to select one network or another. If possible, keep one single network path from XO to VMware.
|
||||
|
||||
XO must be able to connect to the vSphere or ESXi host through the port running the web UI (default port: 443) and the VDDK data port (default port: 902). At the time of writing, there is no way to select one network or another, so if possible, keep a single network path from XO to VMware.
|
||||
|
||||
#### VMware disk support
|
||||
|
||||
##### ✅Supported
|
||||
##### Supported
|
||||
|
||||
- **Native snapshots** are supported. To migrate these:
|
||||
1. Shut them down completely.
|
||||
2. Remove all snapshots before attempting the migration.
|
||||
- **Warm migration** is supported. If warm migration fails:
|
||||
1. Stop the VM.
|
||||
2. Remove any snapshots.
|
||||
1. Shut them down completely.
|
||||
2. Remove all snapshots before attempting the migration.
|
||||
- **Warm migration** is supported. If a warm migration fails:
|
||||
1. Stop the VM.
|
||||
2. Remove any snapshots.
|
||||
|
||||
##### ⚠️ Unofficial support
|
||||
##### Unofficial support {#-unofficial-support}
|
||||
|
||||
VSAN configurations have not been fully tested, but they are expected to work.
|
||||
|
||||
##### ❌ Unsupported
|
||||
##### Unsupported {#-unsupported}
|
||||
|
||||
The following VMware disk types are not supporetd:
|
||||
The following VMware disk types are not supported:
|
||||
|
||||
- RDM (Raw Device Mapping)
|
||||
- Independent disks
|
||||
@@ -154,14 +212,14 @@ Here is the "surefire method" to prepare your VMware environment.
|
||||
It involves a lot of manual steps, but it lets you detect and fix issues without impacting production.
|
||||
|
||||
:::tip
|
||||
There’s also a "fire-and-forget" approach: launch the migration with `stop source` enabled, then start the VM once the migration is complete.
|
||||
There is also a "fire-and-forget" approach: launch the migration with the `Stop source` option enabled, then start the VM once the migration is complete.
|
||||
|
||||
This method is only recommended for non-critical VMs, and only after the first few migrations have gone smoothly.
|
||||
:::
|
||||
|
||||
Once the [prerequisites](#prerequisites) are met, follow these steps to prepare the source VM:
|
||||
|
||||
#### Optimize the Source VM
|
||||
#### Optimize the source VM {#optimize-the-source-vm}
|
||||
|
||||
1. Remove all existing snapshots from the VM.
|
||||
2. Take a new snapshot named `vm starting point` to serve as a baseline.
|
||||
@@ -179,93 +237,109 @@ Take another snapshot named `vm without tools`.
|
||||
|
||||
This snapshot captures the state of the VM without VMware-specific components, and will be used for the initial migration.
|
||||
|
||||
## 🧪 Initial test migration
|
||||
## Initial test migration {#-initial-test-migration}
|
||||
|
||||
Before making the final switch, **run a test migration first**. This lets you catch any issues before moving to production.
|
||||
|
||||
### What happens during the transfer
|
||||
|
||||
Understanding the warm migration mechanism helps you follow the progress:
|
||||
|
||||
1. If the source VM is running and has no snapshot, XO automatically takes one, named `[V2V] migration to XCP-ng`.
|
||||
2. XO creates the destination VM (its name ends with `importing...` while the transfer runs) and imports the read-only snapshot chain while the source VM keeps running in production.
|
||||
3. A snapshot of the destination VM is taken after this first pass, so the process can be resumed safely without creating duplicate VMs.
|
||||
4. If the `Stop source` option is enabled, XO then powers off the source VM in VMware, transfers only the final delta (the blocks written since the snapshot), and takes a final `complete import from V2V` snapshot.
|
||||
|
||||
As long as the import is partial (the source VM is still live), XO blocks the destination VM from starting normally, to prevent both copies from running at once.
|
||||
|
||||
### Perform the first migration attempt
|
||||
|
||||
1. **Start the V2V migration** in Xen Orchestra, without enabling the `Stop Source` option.\
|
||||
This will transfer the VM data up to the snapshot named `vm without tools`.
|
||||
:::tip
|
||||
You can safely close your browser while the migration runs.
|
||||
:::
|
||||
1. **Start the V2V migration** in Xen Orchestra, without enabling the `Stop source` option.\
|
||||
This will transfer the VM data up to the snapshot named `vm without tools`.
|
||||
:::tip
|
||||
You can safely close your browser while the migration runs.
|
||||
:::
|
||||
2. **Monitor the migration progress** using one of these methods:
|
||||
- Check the VM status in Xen Orchestra (it should show `importing...`).
|
||||
- Follow the disk transfer progress indicators.
|
||||
- Check the VM status in Xen Orchestra (its name should show `importing...`).
|
||||
- Follow the disk transfer progress indicators.
|
||||
|
||||
### Testing the migrated VM
|
||||
|
||||
Once the migration is complete:
|
||||
|
||||
1. Start the migrated VM copy on your XCP-ng environment.
|
||||
1. Start the migrated VM copy on your XCP-ng environment. Since the source VM is still running, XO protects the partially synced copy: confirm the force start when prompted.
|
||||
|
||||
:::tip
|
||||
- Use an **isolated network** to avoid IP conflicts.
|
||||
- The **VM state** might be slightly inconsistent since memory and cache data aren't fully synced.
|
||||
:::
|
||||
:::tip
|
||||
- Use an **isolated network** to avoid IP conflicts.
|
||||
- The **VM state** might be slightly inconsistent since memory and cache data aren't fully synced.
|
||||
:::
|
||||
|
||||
2. Check the following during testing:
|
||||
|
||||
- The VM boots up without issues.
|
||||
- Network connectivity is working properly.
|
||||
- Xen Tools installs and runs correctly.
|
||||
- The VM boots up without issues.
|
||||
- Network connectivity is working properly.
|
||||
- Xen Tools installs and runs correctly.
|
||||
|
||||
3. Document any fixes or adjustments required to stabilize the VM.
|
||||
|
||||
### Remove the test copy
|
||||
|
||||
Once you’ve finished your checks and taken notes, delete the test VM. This will free up resources and prevent any confusion before the final migration.
|
||||
Once you have finished your checks and taken notes, delete the test VM. This will free up resources and prevent any confusion before the final migration.
|
||||
|
||||
## 🏁 Final migration
|
||||
## Final migration {#-final-migration}
|
||||
|
||||
### Run the production migration
|
||||
|
||||
When you're ready for the final migration:
|
||||
|
||||
- Shut down the source VM completely.
|
||||
- Start the V2V migration in Xen Orchestra with the `Stop Source` option enabled.\
|
||||
This ensures the final sync happens while the VM is powered off, and prevents any inconsistencies.
|
||||
- Start the V2V migration in Xen Orchestra with the `Stop source` option enabled.\
|
||||
This ensures the final sync happens while the VM is powered off, and prevents any inconsistencies.
|
||||
|
||||
### Post-migration tasks
|
||||
|
||||
Once the migration is complete:
|
||||
|
||||
- Apply any fixes or tweaks you identified during the test migration.
|
||||
- The migrated VM will include snapshots for rollback. If needed, create additional snapshots before making further changes.
|
||||
- Apply any fixes or tweaks you identified during the test migration, and install the Xen guest tools if you have not already.
|
||||
- The migrated VM includes the snapshots taken during the import, which you can use for rollback. If needed, create additional snapshots before making further changes.
|
||||
|
||||
## 🆘 Troubleshooting migration issues
|
||||
## Troubleshooting migration issues {#-troubleshooting-migration-issues}
|
||||
|
||||
If you encounter problems during migration, try these steps to diagnose and resolve them:
|
||||
|
||||
- **Check VMware logs**\
|
||||
Look for disk access errors in the VMware logs. These may point to issues with the source storage or VM configuration.
|
||||
Look for disk access errors in the VMware logs. These may point to issues with the source storage or VM configuration.
|
||||
|
||||
- **Update software versions**\
|
||||
Ensure `nbdkit` and `nbdinfo` are up to date. Older versions can cause compatibility issues with the VDDK plugin.
|
||||
Ensure `nbdkit` and `nbdinfo` are up to date. Older versions can cause compatibility issues with the VDDK plugin. The [prerequisite check](#update-xen-orchestra) on the import page flags outdated versions.
|
||||
|
||||
- **Remove active snapshots**\
|
||||
Make sure no active snapshots remain on the source VM. Snapshots can disrupt migration consistency.
|
||||
Make sure no active snapshots remain on the source VM. Snapshots can disrupt migration consistency.
|
||||
|
||||
- **Verify destination storage**\
|
||||
Confirm the XCP-ng storage repository has enough free space for the migrated VM.
|
||||
Confirm the XCP-ng storage repository has enough free space for the migrated VM.
|
||||
|
||||
- **Test network connectivity**\
|
||||
Ensure stable network connectivity between the VMware environment, Xen Orchestra, and XCP-ng hosts.
|
||||
Ensure stable network connectivity between the VMware environment, Xen Orchestra, and XCP-ng hosts.
|
||||
|
||||
- **Retry with cold migration**\
|
||||
If warm migration fails, power off the VM, remove all snapshots, and try again.
|
||||
If warm migration fails, power off the VM, remove all snapshots, and try again.
|
||||
|
||||
## ❓ Need more help?
|
||||
## Need more help? {#-need-more-help}
|
||||
|
||||
### Booting issues when importing VMs
|
||||
|
||||
:::tip
|
||||
When migrating a VM from VMware, the system may fail to boot if the required Xen drivers are not pre-installed.
|
||||
|
||||
To avoid this, use the `dracut` utility on the source VM prior to migration. For the specific driver injection procedure, refer to the [XCP-ng migration guide](https://docs.xcp-ng.org/installation/migrate-to-xcp-ng/#ova).
|
||||
:::
|
||||
|
||||
## 🚀 Boosting migration performance
|
||||
## Boosting migration performance {#-boosting-migration-performance}
|
||||
|
||||
Migration speed depends on several factors. By identifying bottlenecks and optimizing your setup, you can significantly improve performance.
|
||||
|
||||
### Common bottlenecks
|
||||
|
||||
The V2V migration process can be slowed down by:
|
||||
|
||||
- XAPI ingestion speed limits
|
||||
@@ -274,18 +348,21 @@ The V2V migration process can be slowed down by:
|
||||
- ESXi host export speed
|
||||
|
||||
### Optimizing network performance
|
||||
|
||||
For the best results:
|
||||
|
||||
#### Xen Orchestra to XCP-ng connection
|
||||
- Run Xen Orchestra directly within the target XCP-ng pool to reduce network hops and latency.
|
||||
- Use the highest available bandwidth, ideally 10Gbps or faster.
|
||||
|
||||
- Run Xen Orchestra directly within the target XCP-ng pool to reduce network hops and latency.
|
||||
- Use the highest available bandwidth, ideally 10Gbps or faster.
|
||||
|
||||
#### Xen Orchestra to VMware connection
|
||||
|
||||
Ensure a dedicated 10Gbps+ connection with low latency to your vCenter or ESXi hosts.
|
||||
|
||||
### Storage recommendations
|
||||
|
||||
Use **fast SSD storage** for both the XCP-ng storage repository and Xen Orchestra’s working directory.
|
||||
Use **fast SSD storage** for both the XCP-ng storage repository and Xen Orchestra's working directory.
|
||||
This speeds up the initial migration and enables smoother live migrations afterward.
|
||||
|
||||
### CPU and compute resources
|
||||
@@ -293,7 +370,7 @@ This speeds up the initial migration and enables smoother live migrations afterw
|
||||
If CPU becomes a bottleneck:
|
||||
|
||||
- **Allocate high-performance CPUs** to your Xen Orchestra appliance.
|
||||
- For large environments, consider **parallel migrations** using multiple Xen Orchestra instances —but balance this with your network capacity.
|
||||
- For large environments, consider **parallel migrations** using multiple Xen Orchestra instances, but balance this with your network capacity.
|
||||
|
||||
### Migration strategy
|
||||
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
# VM Templates
|
||||
|
||||
<InterfaceNote />
|
||||
|
||||
Virtual machine templates in Xen Orchestra make it easy to deploy new VMs by providing a ready-to-use configuration with predefined hardware specs and settings. Instead of manually setting up each VM from scratch, you can use templates to speed up deployment and keep things consistent.
|
||||
|
||||

|
||||
<UiShot light="/img/xo5/template-menu.png" alt="The Templates view, from Home" url="https://your-xo/v5/#/home?t=VM-template" />
|
||||
|
||||
## Creating Templates
|
||||
|
||||
@@ -13,13 +15,13 @@ There are a few ways to create a VM template in Xen Orchestra:
|
||||
Set up a VM with your preferred OS and settings, then convert it into a template.
|
||||
|
||||
:::warning
|
||||
Once you convert a VM into a template, it won’t show up in the VM list anymore—this change is permanent.
|
||||
Once you convert a VM into a template, it won’t show up in the VM list anymore: this change is permanent.
|
||||
:::
|
||||
|
||||
1. Select your VM and go to the **Advanced** tab.
|
||||
2. Click **Convert to template**, then confirm.
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/convert-to-template.png" alt="Convert to template, in the VM Advanced tab" width={700} />
|
||||
|
||||
### Clone an Existing Template
|
||||
|
||||
@@ -30,13 +32,13 @@ Duplicate one of the built-in templates and customize it to match your needs.
|
||||
3. Click the **Copy button** in the header.
|
||||
4. Fill out the details in the dialog box.
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/copy-template.png" alt="Select templates, then copy them from the header" width={700} />
|
||||
|
||||
### Create a VM and Convert It
|
||||
|
||||
Set up a new VM (without installing an OS), adjust its hardware settings, and turn it into a template. This is useful if you just want a predefined hardware setup without an OS baked in.
|
||||
|
||||
To know more on VM creation, read the [Infrastructure Management → VM Creation](./manage_infrastructure#vm-creation) section.
|
||||
To learn more about VM creation, read the [VM creation](./manage_infrastructure#vm-creation) section.
|
||||
|
||||
## Viewing Template Properties
|
||||
|
||||
@@ -46,33 +48,33 @@ To check a template’s settings in Xen Orchestra:
|
||||
|
||||
1. Head to the **Home → Templates** section.
|
||||
2. Check the box next to the template(s) you want to inspect.
|
||||
3. Click the hamburger button at the corresponding line to see details like CPU, RAM, and template tags.
|
||||
3. Click the hamburger button on the corresponding line to see details like CPU, RAM, and template tags.
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/template-details-ui.png" alt="Template details, expanded from the Home › Templates list" width={700} />
|
||||
|
||||
### From the REST API
|
||||
|
||||
If you need more technical details that aren’t shown in the UI, you can use the Xen Orchestra API to dig deeper.
|
||||
If you need more technical details than what the UI shows, the Xen Orchestra API has everything.
|
||||
|
||||
To know more on the REST API, read [its documentation](https://github.com/vatesfr/xen-orchestra/blob/master/packages/xo-server/docs/rest-api.md).
|
||||
To learn more, read the [REST API documentation](../automation/restapi.md).
|
||||
|
||||
All collections are listed when you run `GET /rest/v0`, including the `vm-templates` collection:
|
||||
|
||||

|
||||
<UiShot light="/img/xo5/template-list.png" alt="The vm-templates collection, straight from the REST API" url="https://your-xo/rest/v0/vm-templates" />
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/rest-api-template-example.png" alt="A single VM template object, from the REST API" width={560} />
|
||||
|
||||
### From the CLI
|
||||
|
||||
You can also use the CLI tools to dig deeper.
|
||||
You can also inspect a template with the `xe` CLI, from a host console.
|
||||
|
||||
For example, if your template is named `My Debian Template`, you can get its details in the CLI like this:
|
||||
For example, if your template is named `My Debian Template`:
|
||||
|
||||
```sh
|
||||
<Terminal shell title="inspect a template with xe, from a host console">{`
|
||||
xe template-list name-label="My Debian Template"
|
||||
uuid=$(xe template-list name-label="My Debian Template" --minimal)
|
||||
xe template-param-list uuid=$uuid | less
|
||||
```
|
||||
`}</Terminal>
|
||||
|
||||
## Deleting a Template
|
||||
|
||||
@@ -82,8 +84,8 @@ Need to delete a template? Here’s how:
|
||||
Before deleting a template, make sure to find and remove any attached disks. Otherwise, you'll end up with orphaned VDIs.
|
||||
:::
|
||||
|
||||
1. In Xen Orchestra, open the template, go to **Home → Templates** section.
|
||||
2. Check the box next to the template(s) you want to copy.
|
||||
1. In Xen Orchestra, go to the **Home → Templates** section.
|
||||
2. Check the box next to the template(s) you want to delete.
|
||||
3. Click the trash can icon in the header and confirm the deletion.
|
||||
|
||||
## Viridian extensions
|
||||
@@ -94,12 +96,12 @@ VMs include a parameter to enable Viridian extensions.
|
||||
|
||||
Viridian is a codename for [Hyper-V](https://learn.microsoft.com/en-us/windows-server/virtualization/hyper-v/hyper-v-overview), a native hypervisor developed by Microsoft that allows the creation of virtual machines on x86-64 systems running Windows.
|
||||
|
||||
Viridian extensions —referred to as "Viridian enlightenments" by Microsoft— are used by any "recent" Windows OS to work properly. Consequently, the Viridian setting in Xen Orchestra is typically enabled by default for all Windows templates from Windows 2012 onwards.
|
||||
Viridian extensions (referred to as "Viridian enlightenments" by Microsoft) are used by any "recent" Windows OS to work properly. Consequently, the Viridian setting in Xen Orchestra is typically enabled by default for all Windows templates from Windows 2012 onwards.
|
||||
|
||||
### Step-by-step guide
|
||||
|
||||
:::warning
|
||||
We strongly advise to create Windows templates by starting from a built-in Windows template, as the Viridian setting in Xen Orchestra is only relevant for those.
|
||||
We strongly advise creating Windows templates by starting from a built-in Windows template, as the Viridian setting in Xen Orchestra is only relevant for those.
|
||||
:::
|
||||
|
||||
#### Templates based on built-in Windows templates
|
||||
@@ -107,12 +109,12 @@ We strongly advise to create Windows templates by starting from a built-in Windo
|
||||
To find and enable the Viridian setting for your template:
|
||||
|
||||
1. Navigate to the **Home → VMs** menu.\
|
||||
A list of VMs appears.
|
||||
A list of VMs appears.
|
||||
2. Choose your VM from the list and click its name.\
|
||||
The VM details screen appears.
|
||||
The VM details screen appears.
|
||||
3. Click the **Advanced** tab to show more settings for your VM.
|
||||
4. In the **Xen settings** section, scroll to the end and activate the **Viridian** toggle switch:
|
||||

|
||||
<UiDetail src="/img/xo5/viridian-extensions.png" alt="The Viridian toggle, in the Xen settings of the VM Advanced tab" width={620} />
|
||||
Viridian extensions are now enabled for your VM. You can now safely use this VM to create your Windows template.
|
||||
|
||||
#### Enabling Viridian for other non-Windows VM templates
|
||||
@@ -121,7 +123,7 @@ To enable Viridian enlightenments for other non-Windows VM templates, follow the
|
||||
|
||||
## Cloud-init and Cloudbase-init
|
||||
|
||||
If you want VMs to set themselves up automatically after deployment, **Cloud-Init** (for Linux) and **Cloudbase-Init** (for Windows) can help.
|
||||
If you want VMs to set themselves up automatically after deployment, **Cloud-init** (for Linux) and **Cloudbase-init** (for Windows) can help.
|
||||
|
||||
### Cloud-init
|
||||
|
||||
@@ -142,10 +144,12 @@ This means that you can easily customize your VM when you create it from a compa
|
||||
|
||||
As of release 5.101, Xen Orchestra also supports Cloudbase-init. This tool provides equivalent functionality to Cloud-init but is specifically designed for Windows virtual machines.
|
||||
|
||||
To build such a template, follow the dedicated [Windows templates with Cloudbase-init](../windows-templates.md) guide.
|
||||
|
||||
### Requirements
|
||||
|
||||
You only need to use a template of a VM with Cloud-init (for Linux VMs) or Cloudbase-init (for Windows VMs) installed inside it.
|
||||
[Check this blog post to learn how to install CloudInit](https://xen-orchestra.com/blog/centos-cloud-template-for-xenserver/).
|
||||
The only requirement is a template whose VM has Cloud-init (for Linux) or Cloudbase-init (for Windows) installed inside it.
|
||||
[Check this blog post to learn how to install Cloud-init](https://xen-orchestra.com/blog/centos-cloud-template-for-xenserver/).
|
||||
|
||||
:::tip
|
||||
In XOA 5.31, we changed the Cloud-init config drive type from [OpenStack](https://cloudinit.readthedocs.io/en/latest/topics/datasources/configdrive.html) to the [NoCloud](https://cloudinit.readthedocs.io/en/latest/topics/datasources/nocloud.html) type. This will allow us to pass network configuration to VMs in the future. For 99% of users, including default cloud-init installs, this change will have no effect. However if you have previously modified your cloud-init installation in a VM template to only look for `openstack` drive types (for instance with the `datasource_list` setting in `/etc/cloud/cloud.cfg`) you need to modify it to also look for `nocloud`.
|
||||
@@ -153,64 +157,74 @@ In XOA 5.31, we changed the Cloud-init config drive type from [OpenStack](https:
|
||||
|
||||
### Example: How to create a Cloudbase-init template with Windows Server?
|
||||
|
||||
Refer to the [Windows Templates with Cloudbase-init: Step-by-step Guide & Best Practices](../windows-templates) document for complete instructions.
|
||||
Refer to the [Windows templates with Cloudbase-init](../windows-templates.md) guide for complete instructions.
|
||||
|
||||
### Example: How to create a Cloud-init template with Ubuntu 22.04 LTS?
|
||||
|
||||
1. Create a VM with e.g. 2 CPU, 8 GiB of RAM, 10 GiB of disk space, and install Ubuntu 22.04 LTS on it.
|
||||
2. Upon reboot, `apt update` and `apt upgrade` the machine.
|
||||
3. Install the [Guest Tools](https://docs.xcp-ng.org/vms/#%EF%B8%8F-guest-tools).
|
||||
4. Install the "cloud-initramfs-growroot" so that the VM can apply a Cloud Config:
|
||||
```sh
|
||||
sudo apt install cloud-initramfs-growroot
|
||||
```
|
||||
5. Run the command `sudo cloud-init clean`.
|
||||
6. Clear out the machine-id so it can be regenerated when the template is used:
|
||||
```sh
|
||||
sudo truncate -s 0 /etc/machine-id /var/lib/dbus/machine-id
|
||||
```
|
||||
7. Shutdown the VM and create a template from that image.
|
||||
Create a VM with e.g. 2 vCPUs, 8 GiB of RAM and 10 GiB of disk space, and install Ubuntu 22.04 LTS on it. Once it reboots, bring it up to date and install the [Guest Tools](https://docs.xcp-ng.org/vms/#%EF%B8%8F-guest-tools):
|
||||
|
||||
<Terminal shell title="update the future template">{`
|
||||
sudo apt update
|
||||
sudo apt upgrade
|
||||
`}</Terminal>
|
||||
|
||||
Install `cloud-initramfs-growroot` so the VM can grow its file system when a Cloud Config asks for it:
|
||||
|
||||
<Terminal shell title="allow the root file system to grow">{`
|
||||
sudo apt install cloud-initramfs-growroot
|
||||
`}</Terminal>
|
||||
|
||||
Finally, reset the Cloud-init state and clear the machine-id, so both are regenerated on every VM created from the template:
|
||||
|
||||
<Terminal shell title="reset Cloud-init and the machine-id">{`
|
||||
sudo cloud-init clean
|
||||
sudo truncate -s 0 /etc/machine-id /var/lib/dbus/machine-id
|
||||
`}</Terminal>
|
||||
|
||||
Shut down the VM and [convert it into a template](#from-an-existing-vm).
|
||||
|
||||
### Usage
|
||||
|
||||
First, select your compatible template (CloudInit ready) and name it:
|
||||
First, select your compatible template (Cloud-init ready) and name it:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/cloud-init-1.png" alt="Pick a Cloud-init-ready template and name your VM" width={620} />
|
||||
|
||||
Then, activate the config drive and insert your SSH key. Or you can also use a custom CloudInit configuration:
|
||||
Then, activate the config drive and insert your SSH key. Or you can also use a custom Cloud-init configuration:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/cloud-init-2.png" alt="Activate the config drive, then provide your SSH key or a custom config" width={620} />
|
||||
|
||||
> CloudInit configuration examples are [available here](http://cloudinit.readthedocs.org/en/latest/topics/examples.html).
|
||||
:::tip
|
||||
Cloud-init configuration examples are [available in the official documentation](https://cloudinit.readthedocs.io/en/latest/reference/examples.html).
|
||||
:::
|
||||
|
||||
You can extend the disk size (**in this case, the template disk was 8 GiB originally**). We'll extend it to 20GiB:
|
||||
You can extend the disk size (**in this case, the template disk was 8 GiB originally**). We'll extend it to 20 GiB:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/cloud-init-3.png" alt="Extend the template disk at creation time" width={620} />
|
||||
|
||||
Finally, create the VM:
|
||||
|
||||

|
||||
<UiDetail src="/img/xo5/cloud-init-4.png" alt="Create the VM" width={620} />
|
||||
|
||||
Now start the VM and SSH to its IP:
|
||||
|
||||
- **the system has the right VM hostname** (from VM name)
|
||||
- you don't need to use a password to access it (thanks to your SSH key):
|
||||
- **the system has the right hostname** (taken from the VM name)
|
||||
- you don't need a password to access it (thanks to your SSH key):
|
||||
|
||||
```console
|
||||
$ ssh centos@192.168.100.226
|
||||
[centos@tmp-app1 ~]$
|
||||
```
|
||||
<Terminal title="SSH into the new VM, no password needed">{`
|
||||
ssh ubuntu@192.168.100.226
|
||||
ubuntu@tmp-app1:~$
|
||||
`}</Terminal>
|
||||
|
||||
The default `cloud-init` configuration can allow you to be to be a sudoer directly:
|
||||
The default Cloud-init configuration allows you to become a sudoer directly:
|
||||
|
||||
```console
|
||||
[centos@tmp-app1 ~]$ sudo -s
|
||||
[root@tmp-app1 centos]#
|
||||
```
|
||||
<Terminal title="sudoer out of the box">{`
|
||||
sudo -s
|
||||
root@tmp-app1:/home/ubuntu#
|
||||
`}</Terminal>
|
||||
|
||||
Check the root file system size: indeed, **it was automatically increased** to what you need:
|
||||
Check the root file system size: **it was automatically grown** to the size you asked for:
|
||||
|
||||
```console
|
||||
[centos@tmp-app1 ~]$ df -h
|
||||
/dev/xvda1 20G 1,2G 18G 6% /
|
||||
```
|
||||
<Terminal title="the root file system was grown automatically">{`
|
||||
df -h /
|
||||
/dev/xvda1 20G 1.2G 18G 6% /
|
||||
`}</Terminal>
|
||||
|
||||
@@ -1,286 +0,0 @@
|
||||
# XOA Support
|
||||
|
||||
This is the section dedicated to all XOA details and how to get support on it.
|
||||
|
||||
:::tip
|
||||
As a XOA user, you can open tickets in your support panel: [https://support.vates.fr/](https://support.vates.fr/).
|
||||
:::
|
||||
|
||||
## Technical Support
|
||||
|
||||
XOA is the only way to get our pro support, which is available remotely via SSH and a special tunnel.
|
||||
|
||||
### XOA Check
|
||||
|
||||
XOA check is a way to test if you XOA is correctly configured. It should be the first thing to do if you have any problem!
|
||||
|
||||
To run this check, in the web UI, you can access the support section in the XOA menu. In this section you can launch an `xoa check` command:
|
||||
|
||||

|
||||
|
||||
### Support tunnel
|
||||
|
||||
Open a secure support tunnel so our team can remotely investigate on your XOA. For that, we need to get the "support ID". See below:
|
||||
|
||||

|
||||
|
||||
<a id="ssh-pro-support"></a>
|
||||
|
||||
If your web UI is not working, you can also open the secure support tunnel from the CLI. To open a private tunnel (we are the only one with the private key), you can use the command `xoa support tunnel` like below:
|
||||
|
||||
```console
|
||||
$ xoa support tunnel
|
||||
The support tunnel has been created.
|
||||
|
||||
Do not stop this command before the intervention is over!
|
||||
Give this id to the support: 40713
|
||||
```
|
||||
|
||||
Give us this number, and we'll be able to access your XOA in a secure manner. Then, close the tunnel with `Ctrl+C` after your issue has been solved by support.
|
||||
|
||||
:::tip
|
||||
The user `xoa-support` is used by the tunnel. If you want to deactivate this bundled user, you can run `chage -E 0 xoa-support`. To re-activate this account, you must run `chage -E 1 xoa-support`.
|
||||
:::
|
||||
|
||||
## XOA VM Specifications
|
||||
|
||||
By default, the VM is configured with:
|
||||
|
||||
- 2 vCPUs
|
||||
- 2GiB of RAM
|
||||
- 20GiB of free SR space (2GiB on thin pro SR)
|
||||
|
||||
For use on huge infrastructure (more than 500+ VMs), feel free to increase the RAM.
|
||||
|
||||
## Alternative install
|
||||
|
||||
Please only use this if you have issues with [the default way to deploy XOA](../xo5/installation#xoa).
|
||||
|
||||
### Via a bash script
|
||||
|
||||
Alternatively, you can deploy it by connecting to your XCP-ng/XenServer host and executing the following:
|
||||
|
||||
```sh
|
||||
bash -c "$(wget --no-verbose -O- https://xoa.io/deploy)"
|
||||
```
|
||||
|
||||
:::tip
|
||||
This won't write or modify anything on your XCP-ng/XenServer host: it will just import the XOA VM into your default storage repository.
|
||||
:::
|
||||
|
||||
:::warning
|
||||
If you are using an old XCP-ng/XenServer version, you may get a `curl` error:
|
||||
|
||||
```
|
||||
curl: (35) error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version
|
||||
```
|
||||
|
||||
It means that the secure HTTPS protocol is not supported, you can bypass this using the unsecure command instead:
|
||||
|
||||
```sh
|
||||
bash -c "$(wget --no-verbose -O- http://xoa.io/deploy)"
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
Follow the instructions:
|
||||
|
||||
- Your IP configuration will be requested: it's set to **DHCP by default**; otherwise, you can enter a fixed IP address (eg `192.168.0.10`)
|
||||
- If DHCP is selected, the script will continue automatically. Otherwise, a netmask, gateway, and DNS server should be provided.
|
||||
- XOA will be deployed on your default storage repository. You can move it elsewhere anytime after.
|
||||
|
||||
### Via a manual XVA download
|
||||
|
||||
You can also download XOA from xen-orchestra.com in an XVA file. Once you've got the XVA file, you can import it with `xe vm-import filename=xoa_unified.xva` or via XenCenter.
|
||||
|
||||
If you want to use static IP address for your appliance:
|
||||
|
||||
```sh
|
||||
xe vm-param-set uuid="$uuid" \
|
||||
xenstore-data:vm-data/ip="$ip" \
|
||||
xenstore-data:vm-data/netmask="$netmask" \
|
||||
xenstore-data:vm-data/gateway="$gateway"
|
||||
```
|
||||
|
||||
If you want to replace the default DNS server:
|
||||
|
||||
```sh
|
||||
xe vm-param-set uuid="$uuid" xenstore-data:vm-data/dns="$dns"
|
||||
```
|
||||
|
||||
After the VM is imported, you just need to start it with `xe vm-start vm="XOA"` or with XenCenter.
|
||||
|
||||
## First console connection
|
||||
|
||||
### Deployed with the [web deploy form](https://vates.tech/deploy/)
|
||||
|
||||
In that case, you already set the password for `xoa` user. If you forgot it, see below.
|
||||
|
||||
### Manually deployed
|
||||
|
||||
If you connect via SSH or console for the first time without using our [web deploy form](https://vates.tech/deploy/), be aware **there is NO default password set for security reasons**. To set it, you need to connect to your host to find the XOA VM UUID (eg via `xe vm-list`).
|
||||
|
||||
Next, you can replace `<UUID>` with the UUID you found previously, and `<password>` with your password:
|
||||
|
||||
```sh
|
||||
xe vm-param-set uuid=<UUID> xenstore-data:vm-data/system-account-xoa-password=<password>
|
||||
```
|
||||
|
||||
:::tip
|
||||
Don't forget to use quotes for your password, eg: `xenstore-data:vm-data/system-account-xoa-password='MyPassW0rd!'`
|
||||
:::
|
||||
|
||||
Finally, you must reboot the VM to implement the changes.
|
||||
|
||||
You can now connect with the `xoa` username and password you defined in the previous command, eg with `ssh xoa@<XOA IP ADDRESS>`.
|
||||
|
||||
### Using sudo
|
||||
|
||||
To avoid typing `sudo` for any admin command, you can have a root shell with `sudo -s`:
|
||||
|
||||
```console
|
||||
$ sudo -s
|
||||
|
||||
We trust you have received the usual lecture from the local System
|
||||
Administrator. It usually boils down to these three things:
|
||||
|
||||
#1) Respect the privacy of others.
|
||||
#2) Think before you type.
|
||||
#3) With great power comes great responsibility.
|
||||
|
||||
[sudo] password for xoa:
|
||||
$
|
||||
```
|
||||
|
||||
## Network configuration
|
||||
|
||||
XOA uses **DHCP** by default, so if you need to configure the IP address, please run the command `xoa network static`. It will ask you network details:
|
||||
|
||||
```console
|
||||
$ xoa network static
|
||||
? Static IP for this machine 192.168.100.120/24
|
||||
? Gateway 192.168.100.254
|
||||
? IP of the DNS server 192.168.100.254
|
||||
```
|
||||
|
||||
Xen Orchestra is now accessible in your browser at `https://your-vm-ip`.
|
||||
|
||||
You can access the VM console through XenCenter or using VNC through a SSH tunnel.
|
||||
|
||||
If you want to go back in DHCP, just run `xoa network dhcp`
|
||||
|
||||
### Other interfaces
|
||||
|
||||
If you need to configure other interfaces than the default one, you can use the same commands with the name of the interface to configure as supplementary argument:
|
||||
|
||||
```console
|
||||
$ xoa network static enX1
|
||||
? Static IP for this machine 192.168.100.120
|
||||
? Network mask (eg 255.255.255.0) 255.255.255.0
|
||||
|
||||
$ xoa network dhcp enX1
|
||||
```
|
||||
|
||||
## Secondary IP addresses
|
||||
|
||||
To add more IP addresses on an already configured interface, you can use the `--add` flag:
|
||||
|
||||
```
|
||||
$ xoa network static --add
|
||||
? Static IP for this machine 192.168.200.120/24
|
||||
```
|
||||
|
||||
## Firewall
|
||||
|
||||
By default XOA is firewalled, with only ports 22, 80 and 443 opened. You can see the current status of the firewall using the `sudo ufw status verbose` command:
|
||||
|
||||
```
|
||||
Status: active
|
||||
Logging: on (low)
|
||||
Default: deny (incoming), allow (outgoing)
|
||||
New profiles: skip
|
||||
|
||||
To Action From
|
||||
-- ------ ----
|
||||
22 ALLOW IN Anywhere
|
||||
80 ALLOW IN Anywhere
|
||||
443 ALLOW IN Anywhere
|
||||
22/tcp LIMIT IN Anywhere
|
||||
22 ALLOW IN Anywhere (v6)
|
||||
80 ALLOW IN Anywhere (v6)
|
||||
443 ALLOW IN Anywhere (v6)
|
||||
22/tcp LIMIT IN Anywhere (v6)
|
||||
```
|
||||
|
||||
If you want to open or close ports, please check the [documentation of UFW](https://help.ubuntu.com/community/UFW).
|
||||
|
||||
## Default XO account
|
||||
|
||||
Default user is **[email protected]** with **admin** as a password.
|
||||
|
||||
:::warning
|
||||
If you are using the default credentials, **please** create a new admin account and remove this one.
|
||||
:::
|
||||
|
||||
In any case, if you lose your password, you can reset the database and get the default credentials back.
|
||||
|
||||
## Timezone
|
||||
|
||||
You can verify that your time is correctly set with the `date` command. To set XOA to your current timezone, use `sudo dpkg-reconfigure tzdata`.
|
||||
|
||||
## Setting a custom NTP server
|
||||
|
||||
By default, XOA is configured to use the `systemd-timesyncd` daemon, along with the standard Debian NTP servers:
|
||||
|
||||
```
|
||||
pool 0.debian.pool.ntp.org iburst
|
||||
pool 1.debian.pool.ntp.org iburst
|
||||
pool 2.debian.pool.ntp.org iburst
|
||||
pool 3.debian.pool.ntp.org iburst
|
||||
```
|
||||
|
||||
If you'd like to use another pool, you can make the changes directly in `/etc/systemd/timesyncd.conf`.
|
||||
|
||||
You will need to be root to edit this file (or use `sudo`). We recommend adding your custom server to the top of the list, leaving the Debian server entries if possible.
|
||||
|
||||
If you'd like to simply change NTP servers, use the `xoa network ntp` command:
|
||||
|
||||
```console
|
||||
$ xoa network ntp
|
||||
? NTP servers (space separated)
|
||||
```
|
||||
|
||||
For changes to take effect, you will need to restart NTP: `systemctl restart systemd-timesyncd.service`.
|
||||
|
||||
## Restart the service
|
||||
|
||||
You can restart Xen Orchestra by accessing XOA via SSH (or console) and running `systemctl restart xo-server.service`.
|
||||
|
||||
To check the status of `xo-server`, use `systemctl status xo-server.service`, it should display something like this:
|
||||
|
||||
```
|
||||
xo-server.service - XO Server
|
||||
Loaded: loaded (/etc/systemd/system/xo-server.service; enabled)
|
||||
Active: active (running) since Thu 2014-08-14 10:59:46 BST; 21min ago
|
||||
Main PID: 394 (node)
|
||||
CGroup: /system.slice/xo-server.service
|
||||
└─394 node /usr/local/bin/xo-server
|
||||
|
||||
Aug 14 10:59:46 xoa systemd[1]: Starting XO Server...
|
||||
Aug 14 10:59:46 xoa systemd[1]: Started XO Server.
|
||||
Aug 14 10:59:48 xoa xo-server[394]: WebServer listening on http://0.0.0.0:80
|
||||
```
|
||||
|
||||
## Migrate from an older XOA
|
||||
|
||||
If you still use the first XOA (which was not the "unified" version), you can easily migrate all your settings (ACLs, users, servers, etc) to the new version painlessly.
|
||||
|
||||
To do so, go into "Settings/Config" of your old XOA. Export the configuration: you'll download a `config.json` file.
|
||||
|
||||

|
||||
|
||||
Now go to your new unified XOA, "Settings/Config" and import the `config.json` file you downloaded previously, by doing a drag and drop:
|
||||
|
||||

|
||||
|
||||
That's it!
|
||||
@@ -1,520 +0,0 @@
|
||||
# Ansible dynamic inventory
|
||||
|
||||
## Introduction
|
||||
|
||||
Dynamic inventory is a powerful Ansible feature that enables you to automatically discover hosts to manage from an external source. With **Xen Orchestra**, you can now use dynamic inventory to automatically discover and manage your virtual machines (VMs) directly from your virtualized infrastructure.
|
||||
|
||||
This guide will show you how to configure Xen Orchestra's dynamic inventory and automate the management of your VM fleet.
|
||||
|
||||
:::note
|
||||
This guide is designed for [Ansible](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html) version 2.19 or higher and requires the `community.general` collection.
|
||||
:::
|
||||
|
||||
:::tip
|
||||
With dynamic inventory, there is no need to manually maintain static inventory files. Your VMs are automatically discovered and classified into groups based on their properties.
|
||||
:::
|
||||
|
||||
## Configuring Xen Orchestra Dynamic Inventory
|
||||
|
||||
### Installing prerequisites
|
||||
|
||||
Ensure that you have the `community.general` collection installed.
|
||||
|
||||
```bash
|
||||
# Install the community.general collection
|
||||
ansible-galaxy collection install community.general
|
||||
|
||||
# Verify the installation
|
||||
ansible-doc -t inventory community.general.xen_orchestra
|
||||
```
|
||||
### Basic configuration
|
||||
|
||||
1. **Create a configuration file for the dynamic inventory: `test.xen_orchestra.yaml`**
|
||||
|
||||
:::tip
|
||||
Please note that the plugin configuration file must end with one of the following extensions: `xen_orchestra.yml` or `xen_orchestra.yaml` (e.g. `test.xen_orchestra.yml`)
|
||||
:::
|
||||
|
||||
```yaml
|
||||
# xen orchestra connection
|
||||
plugin: community.general.xen_orchestra
|
||||
api_host: ws://your-xo-hostname
|
||||
user: your_username
|
||||
password: your_password
|
||||
validate_certs: false
|
||||
use_ssl: false
|
||||
|
||||
# Automatic groups
|
||||
groups:
|
||||
running: power_state == “Running”
|
||||
halted: power_state == “Halted”
|
||||
windows: “‘Windows’ in name_label”
|
||||
linux: “‘Linux’ in name_label” or “‘Ubuntu’ in name_label” or “‘CentOS’ in name_label” or “‘Debian’ in name_label”
|
||||
|
||||
# Compound variables
|
||||
compose:
|
||||
ansible_host: ipv4_addresses[0] if ipv4_addresses else None
|
||||
ansible_user: “root”
|
||||
xo_vm_name: name_label
|
||||
xo_pool: pool_name
|
||||
```
|
||||
|
||||
:::warning
|
||||
For security reasons, we recommend using environment variables or Ansible Vault to store credentials.
|
||||
:::
|
||||
|
||||
2. **Configuration with environment variables**
|
||||
|
||||
```yaml
|
||||
plugin: community.general.xen_orchestra
|
||||
api_host: “{{xen_api_host}}”
|
||||
user: “{{ xen_api_user }}”
|
||||
password: “{{ xen_api_password }}”
|
||||
validate_certs: true
|
||||
use_ssl: false
|
||||
```
|
||||
|
||||
Use Ansible Vault to create an encrypted file for your secrets:
|
||||
|
||||
```bash
|
||||
ansible-vault create vault.yml
|
||||
```
|
||||
and place the contents:
|
||||
```yaml
|
||||
xen_api_user: your_user
|
||||
xen_api_password: your_password
|
||||
xen_api_host: your-xo-hostname
|
||||
```
|
||||
|
||||
## Using dynamic inventory
|
||||
|
||||
1. **Test dynamic inventory**
|
||||
|
||||
```yaml
|
||||
# List all hosts
|
||||
ansible-inventory -i xo_inventory.yaml --list
|
||||
|
||||
# Display groups in tree form
|
||||
ansible-inventory -i xo_inventory.yaml --graph
|
||||
|
||||
# Provides information about a specific host (VM UUID in XO)
|
||||
ansible-inventory -i xo_inventory.yaml --host=uuid-of-your-vm
|
||||
```
|
||||
|
||||
:::tip
|
||||
If you are using Ansible Vault, don't forget to add `--ask-vault-pass` to the end of your commands.
|
||||
If you are using a vault password file, you can avoid typing the password each time by adding `--vault-password-file ~/.vault_pass.txt` to the end of your commands.
|
||||
:::
|
||||
|
||||
2. **Example output**
|
||||
|
||||
```json
|
||||
{
|
||||
"ansible_host": null,
|
||||
"cpus": 1,
|
||||
"has_ip": false,
|
||||
"ip": null,
|
||||
"is_managed": true,
|
||||
"memory": 21474xxx,
|
||||
"name_label": "XO Tutorial",
|
||||
"os_version": {
|
||||
"distro": "Ubuntu",
|
||||
"name": "Ubuntu 24.04",
|
||||
"uname": "6.8.0-57-generic"
|
||||
},
|
||||
"power_state": "running",
|
||||
"tags": [],
|
||||
"type": "VM",
|
||||
"uuid": "0ae54d06-xxx-100c-00e8-xxxxxxx",
|
||||
"xo_power_state": "running",
|
||||
"xo_vm_name": "XO Tutorial"
|
||||
}
|
||||
```
|
||||
|
||||
## Advanced Use of Dynamic Inventory
|
||||
|
||||
### Filtering VMs
|
||||
|
||||
You can filter the VMs included in the inventory:
|
||||
|
||||
```yaml
|
||||
plugin: community.general.xen_orchestra
|
||||
api_host: ws://your-xo-hostname
|
||||
user: your_user
|
||||
password: your_password
|
||||
validate_certs: true
|
||||
use_ssl: false
|
||||
|
||||
# Filters
|
||||
filters:
|
||||
- pool_name == “Production”
|
||||
- power_state == “Running”
|
||||
- name_label != “template-*”
|
||||
|
||||
# Exclusive filter
|
||||
strict: false
|
||||
```
|
||||
|
||||
### Complex custom groups
|
||||
|
||||
Create groups based on complex conditions:
|
||||
|
||||
```yaml
|
||||
plugin: community.general.xen_orchestra
|
||||
api_host: ws://your-xo-hostname
|
||||
username: your_username
|
||||
password: your_password
|
||||
validate_certs: true
|
||||
use_ssl: false
|
||||
|
||||
groups:
|
||||
# By state
|
||||
powered_on: power_state == “Running”
|
||||
powered_off: power_state == “Halted”
|
||||
|
||||
# By operating system
|
||||
ubuntu_servers: “‘Ubuntu’ in name_label and ‘server’ in name_label.lower()”
|
||||
web_servers: “‘web’ in name_label.lower() or ‘apache’ in name_label.lower() or ‘nginx’ in name_label.lower()”
|
||||
db_servers: “‘db’ in name_label.lower() or ‘database’ in name_label.lower() or ‘mysql’ in name_label.lower() or ‘postgres’ in name_label.lower()”
|
||||
|
||||
# By pool
|
||||
production_vms: pool_name == “your_production_name”
|
||||
development_vms: pool_name == “your_development_name”
|
||||
lab_vms: “pool_name == ‘Main Lab’”
|
||||
|
||||
|
||||
# By tags (if your XO uses tags)
|
||||
critical_vms: "' critical' in tags" if tags is defined else false
|
||||
backup_excluded: “‘no-backup’ in tags” if tags is defined else false
|
||||
|
||||
keyed_groups:
|
||||
# Creates groups by pool
|
||||
- prefix: pool
|
||||
key: pool_name
|
||||
|
||||
# Creates groups by VM template
|
||||
- prefix: template
|
||||
key: template_name
|
||||
```
|
||||
|
||||
### Configuring host variables
|
||||
|
||||
Customize Ansible variables for each host:
|
||||
|
||||
```yaml
|
||||
plugin: community.general.xen_orchestra
|
||||
api_host: ws://your-xo-hostname
|
||||
user: your_user
|
||||
password: your_password
|
||||
validate_certs: true
|
||||
use_ssl: false
|
||||
|
||||
compose:
|
||||
# Sets ansible_host as the first IPv4 address
|
||||
ansible_host: |
|
||||
{% if ipv4_addresses and ipv4_addresses[0] %}
|
||||
{{ ipv4_addresses[0] }}
|
||||
{% else %}
|
||||
{{ name_label | lower | replace(' ', '-') }}.local
|
||||
{% endif %}
|
||||
|
||||
# Sets the user based on the operating system
|
||||
ansible_user: |
|
||||
{% if ‘Windows’ in name_label %}
|
||||
administrator
|
||||
{% elif ‘Ubuntu’ in name_label %}
|
||||
ubuntu
|
||||
{% elif ‘CentOS’ in name_label %}
|
||||
centos
|
||||
{% else %}
|
||||
root
|
||||
{% endif %}
|
||||
|
||||
# Xen Orchestra custom variables
|
||||
xo_vm_id: id
|
||||
xo_vm_name: name_label
|
||||
xo_pool: pool_name
|
||||
xo_template: template_name
|
||||
xo_power_state: power_state
|
||||
xo_memory: memory_max
|
||||
xo_cpus: cpus
|
||||
|
||||
# Default variables
|
||||
vars:
|
||||
ansible_connection: ssh
|
||||
ansible_ssh_common_args: '-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'
|
||||
xo_inventory_source: “xen_orchestra”
|
||||
```
|
||||
|
||||
## Use in Ansible Playbooks
|
||||
|
||||
### Playbook with dynamic inventory
|
||||
|
||||
```yaml
|
||||
# playbook-xo-maintenance.yaml
|
||||
---
|
||||
- name: VM maintenance via XO inventory
|
||||
hosts: uuid_of_your_vm # you can use (all/group_label/statut_vm/...)
|
||||
gather_facts: true
|
||||
become: yes
|
||||
|
||||
tasks:
|
||||
- name: Update package index
|
||||
apt:
|
||||
update_cache: yes
|
||||
cache_valid_time: 3600
|
||||
when: ansible_distribution in [“Ubuntu”, “Debian”]
|
||||
|
||||
- name: Update system packages
|
||||
apt:
|
||||
name: “*”
|
||||
state: latest
|
||||
when: ansible_distribution in [“Ubuntu”, “Debian”]
|
||||
register: apt_upgrade
|
||||
|
||||
- name: Check if a reboot is required
|
||||
stat:
|
||||
path: /var/run/reboot-required
|
||||
register: reboot_required_file
|
||||
when: ansible_distribution in [“Ubuntu”, “Debian”]
|
||||
|
||||
- name: Reboot if necessary
|
||||
reboot:
|
||||
msg: “Reboot after update”
|
||||
connect_timeout: 5
|
||||
reboot_timeout: 300
|
||||
pre_reboot_delay: 0
|
||||
post_reboot_delay: 30
|
||||
test_command: uptime
|
||||
when: reboot_required_file.stat.exists
|
||||
|
||||
- name: Clean up package cache
|
||||
apt:
|
||||
autoclean: yes
|
||||
autoremove: yes
|
||||
when: ansible_distribution in [“Ubuntu”, “Debian”]
|
||||
```
|
||||
|
||||
### Managing VMs by group
|
||||
|
||||
```yaml
|
||||
# manage-vm-groups.yaml
|
||||
---
|
||||
- name: Configuring application servers
|
||||
hosts: group_label
|
||||
gather_facts: true
|
||||
become: yes
|
||||
|
||||
tasks:
|
||||
- name: Installing basic packages
|
||||
apt:
|
||||
name:
|
||||
- curl
|
||||
- wget
|
||||
- htop
|
||||
- net-tools
|
||||
state: present
|
||||
update_cache: yes
|
||||
|
||||
- name: Timezone configuration
|
||||
timezone:
|
||||
name: Europe/Paris
|
||||
|
||||
- name: Creation of custom motd file
|
||||
copy:
|
||||
content: |
|
||||
VM managed by Ansible via Xen Orchestra
|
||||
Template: {{ xo_template }}
|
||||
Pool: {{ xo_pool }}
|
||||
dest: /etc/motd
|
||||
owner: root
|
||||
group: root
|
||||
mode: 0644
|
||||
|
||||
- name: Maintain specific VMs
|
||||
hosts: lab_vms
|
||||
gather_facts: true
|
||||
become: yes
|
||||
|
||||
tasks:
|
||||
- name: Check disk space
|
||||
shell: df -h /
|
||||
register: disk_usage
|
||||
|
||||
- name: Check memory usage
|
||||
shell: free -h
|
||||
register: memory_usage
|
||||
|
||||
- name: Display system information
|
||||
debug:
|
||||
msg: |
|
||||
VM: {{ xo_vm_name }}
|
||||
Disk: {{ disk_usage.stdout_lines[1] if disk_usage.stdout_lines|length > 1 else ‘N/A’ }}
|
||||
Memory: {{ memory_usage.stdout_lines[1] if memory_usage.stdout_lines|length > 1 else ‘N/A’ }}
|
||||
```
|
||||
|
||||
### Monitoring and Reporting Playbook
|
||||
|
||||
```yaml
|
||||
# monitoring-playbook.yaml
|
||||
---
|
||||
- name: Collect information from XO VMs
|
||||
hosts: uuid_of_your_vm # use 'all' if you want to target all VMs
|
||||
gather_facts: true
|
||||
become: yes
|
||||
|
||||
tasks:
|
||||
- name: Collect detailed information
|
||||
setup:
|
||||
gather_subset:
|
||||
- hardware
|
||||
- network
|
||||
- virtual
|
||||
|
||||
- name: Check memory usage
|
||||
shell: free -m | awk 'NR==2{printf "%.2f%%", $3*100/$2 }'
|
||||
register: memory_usage
|
||||
|
||||
- name: Check CPU usage
|
||||
shell: top -bn1 | grep "Cpu(s)" | awk '{print $2}' | cut -d'%' -f1
|
||||
register: cpu_usage
|
||||
|
||||
- name: Check uptime
|
||||
shell: uptime -p
|
||||
register: uptime
|
||||
|
||||
- name: Create XO report
|
||||
local_action:
|
||||
module: copy
|
||||
content: |
|
||||
XEN ORCHESTRA REPORT - {{ ansible_date_time.iso8601 }}
|
||||
===================================================
|
||||
{% for host in groups['all'] %}
|
||||
VM: {{ hostvars[host].xo_vm_name }}
|
||||
UUID: {{ hostvars[host].xo_vm_id }}
|
||||
IP: {{ hostvars[host].ansible_host }}
|
||||
Hostname: {{ hostvars[host].ansible_hostname }}
|
||||
Memory: {{ hostvars[host].memory_usage.stdout }}
|
||||
CPU: {{ hostvars[host].cpu_usage.stdout }}%
|
||||
Uptime: {{ hostvars[host].uptime.stdout }}
|
||||
Pool: {{ hostvars[host].xo_pool }}
|
||||
Template: {{ hostvars[host].xo_template }}
|
||||
Status: {{ hostvars[host].xo_power_state }}
|
||||
------------------------------------------
|
||||
{% endfor %}
|
||||
dest: "./xo-report-{{ ansible_date_time.epoch }}.txt"
|
||||
run_once: true
|
||||
|
||||
- name: Monitoring summary
|
||||
debug:
|
||||
msg: |
|
||||
XO monitoring completed
|
||||
Report generated: xo-report-{{ ansible_date_time.epoch }}.txt
|
||||
{{ groups['all'] | length }} VMs inventoried
|
||||
```
|
||||
|
||||
## Best Practices and Security
|
||||
|
||||
### Using Ansible Vault
|
||||
|
||||
:::warning
|
||||
Always secure your credentials with Ansible Vault in production environments to prevent unauthorized access and sensitive data leaks. Failing to protect secrets can expose passwords, API keys, and other confidential information, putting your infrastructure and data at risk.
|
||||
:::
|
||||
|
||||
1. **Create a secure vault file**
|
||||
|
||||
```bash
|
||||
ansible-vault create vault.yaml
|
||||
```
|
||||
|
||||
```yaml
|
||||
xen_api_user: your_username
|
||||
xen_api_password: your_password
|
||||
xen_api_host: your-xo-hostname
|
||||
```
|
||||
|
||||
2. **Inventory configuration with vault**
|
||||
|
||||
```yaml
|
||||
plugin: community.general.xen_orchestra
|
||||
api_host: "{{xen_api_host}}"
|
||||
user: "{{ xen_api_user }}"
|
||||
password: "{{ xen_api_password }}"
|
||||
validate_certs: true
|
||||
use_ssl: false
|
||||
```
|
||||
|
||||
3. **Execution with vault**
|
||||
|
||||
```bash
|
||||
ansible-inventory -i test.xen_orchestra.yaml --list --ask-vault-pass
|
||||
```
|
||||
|
||||
### Managing Multiple Environments
|
||||
|
||||
Create inventory configurations per environment:
|
||||
|
||||
```yaml
|
||||
plugin: community.general.xen_orchestra
|
||||
api_host: ws://xo-production.company.com
|
||||
user: "{{ vault_xo_user }}"
|
||||
password: "{{ vault_xo_password }}"
|
||||
filters:
|
||||
- pool_name == "your_pool_name"
|
||||
```
|
||||
|
||||
## Troubleshooting and Debugging
|
||||
|
||||
### Testing and Validation
|
||||
|
||||
```bash
|
||||
ansible-inventory -i your_file.xen_orchestra.yml --list
|
||||
|
||||
ANSIBLE_DEBUG=1 ansible-inventory -i your_file.xen_orchestra.yml --list
|
||||
|
||||
ansible-inventory -i your_file.xen_orchestra.yml --host=uuid-vm-specific
|
||||
|
||||
ansible -i your_file.xen_orchestra.yml all -m ping
|
||||
```
|
||||
|
||||
### Common Issue Resolution
|
||||
|
||||
1. **Connection Problems**
|
||||
- **Error**: Unable to connect to the Xen Orchestra API.
|
||||
- **Reason**: Incorrect URL or credentials.
|
||||
- **Solution**: Check the URL and credentials.
|
||||
```bash
|
||||
# Verify URL and credentials
|
||||
ANSIBLE_DEBUG=1 ansible-inventory -i your_file.xen_orchestra.yml --list
|
||||
```
|
||||
|
||||
2. **VMs Not Found**
|
||||
- **Error**: No VMs found in inventory.
|
||||
- **Reason**: Applied filters may be excluding all VMs.
|
||||
- **Solution**: Check the applied filters.
|
||||
```yaml
|
||||
filters:
|
||||
- power_state == "Running"
|
||||
strict: false
|
||||
```
|
||||
|
||||
3. **Variable Issues**
|
||||
- **Error**: Undefined or incorrect variables.
|
||||
- **Reason**: Issues with variable definitions in the configuration file.
|
||||
- **Solution**: Ensure all variables are properly defined.
|
||||
```yaml
|
||||
compose:
|
||||
ansible_host: ipv4_addresses[0] if ipv4_addresses else "unknown"
|
||||
ansible_user: "{{ 'ubuntu' if 'Ubuntu' in name_label else 'root' }}"
|
||||
```
|
||||
|
||||
## Conclusion
|
||||
|
||||
The Xen Orchestra dynamic inventory for Ansible provides a powerful and automated method to manage your virtualized infrastructure. By eliminating manual inventory maintenance, you gain agility, reliability, and efficiency.
|
||||
|
||||
## Related links
|
||||
|
||||
- [Dynamic inventory source code](https://github.com/ansible-collections/community.general/blob/main/plugins/inventory/xen_orchestra.py)
|
||||
- [Ansible documentation on dynamic inventories](https://xen-orchestra.com/blog/virtops3-ansible-with-xen-orchestra/)
|
||||
- [community.general collection](https://docs.ansible.com/ansible/latest/collections/community/general/xen_orchestra_inventory.html)
|
||||
- [XCP-ng Forum](https://xcp-ng.org/forum/)
|
||||
@@ -1 +1,39 @@
|
||||
---
|
||||
sidebar_label: Backups in XO 6
|
||||
---
|
||||
|
||||
# Backups
|
||||
|
||||
XO 6 puts backup health where you look every day: on the dashboards. This page covers what you can see and follow from XO 6; creating and editing backup jobs is currently done in XO 5 (see [XO 6 vs. XO 5](xo6vsxo5.md)).
|
||||
|
||||
## Backup health on the dashboard
|
||||
|
||||
The Xen Orchestra dashboard dedicates three panels to data protection:
|
||||
|
||||
- **Backup jobs status**: how the runs of the last 7 days went.
|
||||
- **Backup jobs issues**: jobs whose last 3 runs need attention.
|
||||
- **VMs protection**: how many VMs are covered by at least one backup job, and how many are not protected at all.
|
||||
|
||||
<UiShot light="/img/xo6/dashboard-light.png" dark="/img/xo6/dashboard-dark.png" alt="The dashboard, with backup health panels at the bottom" url="https://your-xo/v6/#/dashboard" />
|
||||
|
||||
## The Backups view
|
||||
|
||||
The **Backups** tab at the Xen Orchestra level lists your backup jobs, with their mode (rolling snapshot, delta, full and so on), the outcome of their last 3 runs, and their schedules. Each job opens on its own page with four tabs: **Runs** (the execution history), **Configuration**, **Backed up VMs** and **Targets**, plus a marked link to configure the job in XO 5.
|
||||
|
||||
<UiShot light="/img/xo6/backup-jobs-light.png" dark="/img/xo6/backup-jobs-dark.png" alt="The backup jobs list" url="https://your-xo/v6/#/backups" />
|
||||
|
||||
## Per-VM protection
|
||||
|
||||
Every VM dashboard answers the question "is this VM protected?" directly:
|
||||
|
||||
- **Last 3 backup runs** with the protection status. A VM in no active backup job is flagged, with a link to configure a job for it.
|
||||
- **Last 3 backup archives** available for restore.
|
||||
- **Last replication** date, when the VM is covered by a replication job.
|
||||
|
||||
The **Backups** tab of the VM lists the jobs covering that specific VM.
|
||||
|
||||
<UiShot light="/img/xo6/vm-dashboard-light.png" dark="/img/xo6/vm-dashboard-dark.png" alt="A VM dashboard, with protection status and backup panels" url="https://your-xo/v6/#/vm/…/dashboard" />
|
||||
|
||||
## Where the rest lives
|
||||
|
||||
Backup restore, job creation and editing, backup repositories (S3, NFS, SMB and Azure), mirror backups, sequences and health checks are managed in XO 5 for now, and are documented in the [XO 5 backup documentation](../xo5/backups.md). Everything you configure there is immediately reflected in the XO 6 views above.
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
# Community support
|
||||
|
||||
We do our best to assist users running Xen Orchestra from the sources on [our community forums](https://xcp-ng.org/forum/category/12/xen-orchestra). However there's no guarantee you will receive a solution (from us or the community), nor any guarantee on a timeframe. Usually we are responsive, but keep in mind that if you need production level support, you should consider subscribing to our [XOA offers](https://vates.tech/pricing-and-support/).
|
||||
|
||||
:::warning
|
||||
If you installed your XO from a 3rd party script (any method outside [our official documentation](../xo5/installation.md#from-the-sources)), please report your issue **first** on the 3rd party script repository. We can't waste time debugging 3rd party installers that very often lag behind our own deployment methods and fall out of date.
|
||||
:::
|
||||
|
||||
## Current version
|
||||
|
||||
With Xen Orchestra from the sources, you can check your current commit hash in the **About** section:
|
||||
|
||||

|
||||
|
||||
:::tip
|
||||
You can compare this hash to the current commit list in [our GitHub repository](https://github.com/vatesfr/xen-orchestra/commits/master).
|
||||
:::
|
||||
|
||||
## Report a bug
|
||||
|
||||
:::warning
|
||||
Before reporting a bug, please check that your **current version is up-to-date with the latest commit on `master`!** See the "Current version" section below.
|
||||
:::
|
||||
|
||||
If you have issues with XO installed from the sources (via GitHub), please **always** first:
|
||||
|
||||
1. update your XO to the latest `master` commit (see how-to in the [dedicated section](../xo5/installation.md#updating)) and retest again
|
||||
2. if the issue persists, double check you have all the requirements checked from the [installation section](../xo5/installation.md#from-the-sources) and test again
|
||||
3. then, if you still experience problems, remove and rebuild from scratch
|
||||
|
||||
Only after that, you can go to the [dedicated forum](https://xcp-ng.org/forum/category/12/xen-orchestra) to ask about your problem.
|
||||
|
||||
:::tip
|
||||
If you want a consistent and tested solution for using Xen Orchestra, we strongly advise using our preconfigured and validated [Xen Orchestra Virtual Appliance](../xo5/installation.md#xoa).
|
||||
:::
|
||||
|
||||
## Feature requests
|
||||
|
||||
The best way to submit a feature request is to:
|
||||
|
||||
1. Ask on the forum first, explaining **why you need it**.
|
||||
2. If the discussion is fruitful, we might ask you to [create the request on our GitHub repository](https://github.com/vatesfr/xen-orchestra/issues/new/choose) and choose "Feature request".
|
||||
3. Wait for the feature to be released!
|
||||
|
||||
:::tip
|
||||
Obviously, XOA users get a higher priority to get new features, since they contribute directly to the project with a subscription. However, your feedback/ideas are always welcome, and the more popular the feature request is, the higher the chances it will be added!
|
||||
:::
|
||||
@@ -1 +1,57 @@
|
||||
# Core concepts
|
||||
|
||||
XO 6 organizes everything around a simple idea: **every level of your infrastructure gets the same treatment**. Your whole Xen Orchestra, a pool, a host or a single VM each have their own page, with a dashboard and a consistent set of tabs. Once you know how one page works, you know them all.
|
||||
|
||||
## The object hierarchy
|
||||
|
||||
Xen Orchestra manages any number of pools, wherever they are:
|
||||
|
||||
- **Xen Orchestra** (the top level): everything connected to this XO, across all pools and sites.
|
||||
- **Pool**: a group of XCP-ng hosts sharing storage and networks, managed as one unit.
|
||||
- **Host**: an XCP-ng server inside a pool.
|
||||
- **VM**: a virtual machine running on a host.
|
||||
|
||||
The tree view on the left mirrors this hierarchy, and every page shows its object's place in it (a VM page links to its host and pool, and so on).
|
||||
|
||||
## Dashboards at every level
|
||||
|
||||
Each level opens on a **dashboard** that answers "is everything fine here?" at its own scale.
|
||||
|
||||
At the top level, the dashboard aggregates the whole infrastructure: pool, host and VM status, total memory, CPUs and storage, alarms, missing patches per pool and host, backup job health and how many VMs are protected by a backup job:
|
||||
|
||||
<UiShot light="/img/xo6/dashboard-light.png" dark="/img/xo6/dashboard-dark.png" alt="The Xen Orchestra dashboard" url="https://your-xo/v6/#/dashboard" />
|
||||
|
||||
At the pool level, the same layout narrows to the pool: host and VM status, alarms, the exact list of missing patches, storage and RAM usage per host, and CPU provisioning:
|
||||
|
||||
<UiShot light="/img/xo6/pool-dashboard-light.png" dark="/img/xo6/pool-dashboard-dark.png" alt="A pool dashboard" url="https://your-xo/v6/#/pool/…/dashboard" />
|
||||
|
||||
Host and VM dashboards follow the same principle, down to the quick info of a single VM (state, IP address reported by the guest tools, OS, vCPUs, RAM, virtualization mode) and its individual backup protection status.
|
||||
|
||||
## Tabs, tables and the side panel
|
||||
|
||||
Object pages are organized in tabs. The exact set depends on the object:
|
||||
|
||||
| Level | Tabs |
|
||||
| ------------- | --------------------------------------------------------------------------- |
|
||||
| Xen Orchestra | Dashboard, Backups, Tasks, Pools, Hosts, VMs |
|
||||
| Pool | Dashboard, Stats, System, Network, Security, Storage, Tasks, Hosts, VMs |
|
||||
| Host | Dashboard, Console, Stats, System, Network, Storage, Tasks, VMs |
|
||||
| VM | Dashboard, Console, Backups, Stats, System, Network, VDIs, Snapshots, Tasks |
|
||||
|
||||
Tables (networks, tasks, backup jobs, snapshots and so on) share the same tooling everywhere:
|
||||
|
||||
- a **Search Engine** field with a query builder, to filter large tables precisely,
|
||||
- pagination controls,
|
||||
- an eye icon per row that opens the **side panel** with the details of that row, so you never lose the context of the list.
|
||||
|
||||
<UiShot light="/img/xo6/pool-networks-light.png" dark="/img/xo6/pool-networks-dark.png" alt="Networks of a pool, with the query builder and the side panel" url="https://your-xo/v6/#/pool/…/networks" />
|
||||
|
||||
## Tasks: everything is tracked
|
||||
|
||||
Every level has a **Tasks** tab. It records what happens on your infrastructure: user authentications, API calls, rolling pool reboots, backup runs and any other operation, with their outcome and when they ended. When you need to understand what happened and when, start there.
|
||||
|
||||
<UiShot light="/img/xo6/tasks-light.png" dark="/img/xo6/tasks-dark.png" alt="The tasks view" url="https://your-xo/v6/#/tasks" />
|
||||
|
||||
## Where XO 5 fits
|
||||
|
||||
XO 6 is an official release under active development. A few operations still live in XO 5, and XO 6 tells you explicitly: buttons and links marked with an external-link icon (for example **Manage VM lifecycle in XO 5**, or the **Stats** tab) open the right XO 5 page for that same object. Both interfaces work on the same data at the same time, so there is no synchronization to think about. The current split is documented in [XO 6 vs. XO 5](xo6vsxo5.md).
|
||||
|
||||
@@ -1 +1,50 @@
|
||||
# Getting started
|
||||
|
||||
XO 6 is the new generation of the Xen Orchestra web interface. Since its first official release, it is the default interface of your Xen Orchestra: log in as usual and you land in XO 6.
|
||||
|
||||
:::info
|
||||
XO 6 currently requires an administrator account: other users are redirected to XO 5 for now. XO 6 and XO 5 run side by side on the same Xen Orchestra and manage the same infrastructure. You can switch to XO 5 at any time with the **XO 5** link in the top-right corner, and some advanced operations open directly in XO 5 (they are clearly marked with an external-link icon). See [XO 6 vs. XO 5](xo6vsxo5.md) for the current split.
|
||||
:::
|
||||
|
||||
## Accessing XO 6
|
||||
|
||||
Open your Xen Orchestra URL in a browser and log in with your usual credentials. XO 6 is served as the default interface, and it is also directly reachable at `https://your-xo/v6/`.
|
||||
|
||||
<UiShot light="/img/xo6/dashboard-light.png" dark="/img/xo6/dashboard-dark.png" alt="The XO 6 dashboard right after login" url="https://your-xo/v6/#/dashboard" />
|
||||
|
||||
On first login, a welcome message summarizes the state of the project: XO 6 is an official release under active development, new capabilities land continuously, and everything you do not find yet in XO 6 is one click away in XO 5.
|
||||
|
||||
## The layout
|
||||
|
||||
The interface is built around three areas:
|
||||
|
||||
- **The tree view**, on the left: your whole infrastructure as a tree, from your Xen Orchestra down to every pool, host and VM. It is the main way to navigate.
|
||||
- **The main area**: the page of the selected object, organized in tabs (dashboard, console, networks, tasks and so on, depending on the object).
|
||||
- **The side panel**, on the right of tables: click the eye icon on a row to inspect an object without leaving the list.
|
||||
|
||||
The top bar carries the **XO 5** switch, the **Third party apps** menu (with the EasyVirt DC Scope and DC NetScope integrations), a quick view of the last 24 hours of tasks, and your account menu.
|
||||
|
||||
## Make it yours
|
||||
|
||||
The **Settings** page (from the account menu) lets you pick a light, dark or automatic color mode, one of five interface themes (default, nord, solarized, dracula, monokai), and your language: the interface is translated into 21 languages, with community translations managed on Weblate.
|
||||
|
||||
## Navigating with the tree view
|
||||
|
||||
The tree view lists every connected pool with its hosts and VMs, each with a live status icon. Click any object to open its page. The counter next to a host or pool tells you how many VMs live there at a glance.
|
||||
|
||||
The **search field** filters the whole tree as you type, which is the fastest way to reach an object in a large infrastructure:
|
||||
|
||||
<UiShot light="/img/xo6/treeview-search-light.png" dark="/img/xo6/treeview-search-dark.png" alt="Filtering the tree view" url="https://your-xo/v6/#/dashboard" />
|
||||
|
||||
Next to the tree view, the **Administration** tab of the sidebar gives access to user management (see [Users and administration](management.md#users-and-administration)).
|
||||
|
||||
## Your first tour
|
||||
|
||||
A good way to discover XO 6 in a few minutes:
|
||||
|
||||
1. Start on the **dashboard**: it aggregates the health of everything Xen Orchestra manages, including pool, host and VM status, resource totals, missing patches, alarms and backup health. See [Core concepts](coreconcepts.md).
|
||||
2. Click a **pool** in the tree view: same idea, scoped to the pool, with its networks, storage and hosts one tab away.
|
||||
3. Click a **VM**: quick info, live console, snapshots, backup protection status, all in tabs.
|
||||
4. Open the **Tasks** tab at any level: every operation, API call and authentication is tracked there.
|
||||
|
||||
When something is not available in XO 6 yet, follow the marked links to XO 5 and finish the operation there: both interfaces act on the same objects instantly.
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
---
|
||||
slug: support
|
||||
---
|
||||
|
||||
# Introduction to Support
|
||||
|
||||
:::tip
|
||||
See the dedicated sub-section to read more about [XOA support and usage](../xo5/xoa.md).
|
||||
:::
|
||||
|
||||
Xen Orchestra will run in a controlled/tested environment thanks to XOA ([Xen Orchestra virtual Appliance](https://vates.tech/deploy/)). **This is the only way to get pro support**. Any account with a registered XOA can access a [dedicated support panel](https://xen-orchestra.com/#!/member/support).
|
||||
|
||||
XOA is available in multiple plans:
|
||||
|
||||
- Free
|
||||
- Starter
|
||||
- Enterprise
|
||||
- Premium
|
||||
|
||||
Higher tier support plans include faster ticket response times (and cover more features). Paid support plans and response times are based on the plan you have, plans can be [reviewed here](https://vates.tech/pricing-and-support/).
|
||||
|
||||
:::tip
|
||||
If you have a subscription (or at least a registered free XOA), you can open a ticket describing your issue directly from your [personal account page here](https://xen-orchestra.com/#!/member/support)
|
||||
:::
|
||||
|
||||
## XOA Free support
|
||||
|
||||
With the free version of the Xen Orchestra Appliance (XOA free), **you can open private support tickets** and we will do our best to assist you, however, this support is limited and is not guaranteed in regards to response times or resolutions offered.
|
||||
|
||||
## Community support
|
||||
|
||||
Lastly while Xen Orchestra is free and Open Source software, supporting and developing it takes a lot of effort. If you are considering using Xen Orchestra in production, please subscribe for one of our [professional support plans](https://vates.tech/pricing-and-support/).
|
||||
|
||||
Read more in the [dedicated section for community support](community.md).
|
||||
@@ -1,233 +0,0 @@
|
||||
# Deploy Kubernetes with recipes
|
||||
|
||||
## Introduction
|
||||
|
||||
Xen Orchestra includes a Kubernetes cluster [recipe](../xo5/advanced#recipes) that provides a simple way to deploy an official Kubernetes distribution called **MicroK8s** (maintained by Canonical).
|
||||
|
||||
:::tip
|
||||
One of the key benefits of MicroK8s is its automatic security updates. For example, patch releases (like 1.30.x to 1.30.x+1) are applied automatically. This saves Kubernetes admins a lot of time and effort.
|
||||
:::
|
||||
|
||||
### Networking and CNI
|
||||
|
||||
This recipe uses **Calico**, the default Container Network Interface (CNI) plugin included with MicroK8s, to handle container networking. Calico provides secure networking and network policies for Kubernetes, and its default configuration is ready for production—no additional setup required.
|
||||
|
||||
If you need to adjust the Calico setup (for example, to modify the CIDR range), check the [MicroK8s documentation](https://microk8s.io/docs/change-cidr) for step-by-step instructions.
|
||||
|
||||
#### Configure the pod CIDR
|
||||
|
||||
Since version 5.113 of Xen Orchestra, the pod and service CIDR can be customized via the recipe form. There is no need to perform manual configuration to change them. See [Deployment steps - 3.vii](./kubernetes.md#deployment-steps).
|
||||
|
||||
:::note
|
||||
The default CIDR for pods is `10.1.0.0/16`. All pods are assigned an IP address in that range.
|
||||
|
||||
The default service CIDR is `10.152.183.0/24`. `10.152.183.1` will typically be reserved for the Kubernetes API, and `10.152.183.10` will be used by CoreDNS.
|
||||
:::
|
||||
|
||||
### Cloud Controller Manager
|
||||
|
||||
This recipe automatically deploys the [Xen Orchestra Cloud Controller Manager](https://github.com/vatesfr/xenorchestra-cloud-controller-manager/tree/main). The Cloud Controller Manager (CCM) acts as a bridge between your Kubernetes cluster and the underlying Xen Orchestra instance.
|
||||
|
||||
It takes care of node initialization and sets the correct labels and taints for effective cluster management. When it notices that a VM has been deleted from Xen Orchestra, it automatically cleans up the associated node and removes it from the cluster.
|
||||
|
||||
For the CCM to function properly, the Xen Orchestra instance must be reachable by the cluster nodes (VMs) via either an FQDN or IP address. (See [Deployment steps - 3.vi](./kubernetes.md#deployment-steps).)
|
||||
|
||||
The recipe automatically generates an API token for the current user with a validity of 6 months.
|
||||
|
||||
:::warning
|
||||
You will need to renew this token and update the `xenorchestra-cloud-controller-manager` secret in the Kubernetes cluster before it expires to maintain CCM functionality.
|
||||
:::
|
||||
|
||||
#### Viewing the Current Token
|
||||
|
||||
To view the current token configuration in the secret:
|
||||
|
||||
```bash
|
||||
kubectl get secret xenorchestra-cloud-controller-manager \
|
||||
--namespace=kube-system \
|
||||
-o json | jq -r '.data["config.yaml"]' | base64 -d
|
||||
```
|
||||
|
||||
#### Refreshing the API Token
|
||||
|
||||
To refresh the token, generate a new one using the Xen Orchestra API and update the Kubernetes secret:
|
||||
|
||||
```bash
|
||||
# 1. Generate a new token (replace with your XO URL)
|
||||
# `-k` is needed if the cert is invalid
|
||||
NEW_TOKEN=$(curl -X 'POST' \
|
||||
--header 'Cookie: authenticationToken=<current-token>' \
|
||||
'https://your-xo-instance.example.com/rest/v0/users/me/authentication_tokens' \
|
||||
-H 'accept: application/json' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{
|
||||
"description": "token for CCM",
|
||||
"expiresIn": "6 months"
|
||||
}' | jq -r '.token.id')
|
||||
|
||||
# 2. Update the secret with the new token
|
||||
kubectl get secret xenorchestra-cloud-controller-manager \
|
||||
--namespace=kube-system \
|
||||
-o json | \
|
||||
jq --arg token "$NEW_TOKEN" '.data["config.yaml"] |= (@base64d | sub("token: .+"; "token: " + $token) | @base64)' | \
|
||||
kubectl apply -f -
|
||||
```
|
||||
|
||||
## Before you start
|
||||
|
||||
Make sure your infrastructure meets these requirements:
|
||||
|
||||
- A running Xen Orchestra instance connected to an XCP-ng pool
|
||||
- A **VM template** for the base OS (e.g. an Ubuntu image)
|
||||
- Enough resources to host the **control plane** and **worker nodes**
|
||||
- The Xen Orchestra instance must be reachable by the cluster nodes/VMs - It can be reached via an FQDN or an IP address - This is for the XO CCM (Cloud Controller Manager).
|
||||
|
||||
## Deployment steps
|
||||
|
||||
1. In Xen Orchestra 5, go to **Hub → Recipes**.\
|
||||
A list of recipes will appear:
|
||||

|
||||
2. Go to the **Kubernetes cluster** recipe and click **Create**.\
|
||||
A cluster creation form appears:
|
||||

|
||||
3. Configure your cluster:
|
||||
1. Select a pool where you want to deploy your cluster.
|
||||
2. Select a storage repository, a network and a Kubernetes version.
|
||||
3. Enter a name for your cluster.\
|
||||
The name will be used to tag VMs (see [VM tagging](./kubernetes.md#vm-tagging)).
|
||||
4. Define the number of worker nodes.
|
||||
5. Define the number of nodes used for the control plane.
|
||||
6. Define the FQDN or IP address that will be used by the Cloud Controller Manager (CCM) to reach this Xen Orchestra instance.\
|
||||
*If the instance use a self signed HTTPS certificate, toggle "Allow insecure XO connection"*.
|
||||
7. (Optional). If you want to change the default CIDR for your cluster pods and services, check the **Use a custom cluster CIDR** box and specify the new IP ranges to use.
|
||||

|
||||
9. (Optional). If you want your cluster to use static IP addresses, check the **Static IP addresses** box and specify the IP address parameters:
|
||||

|
||||
4. Click **OK** to start deploying the cluster.
|
||||
|
||||
Xen Orchestra handles the rest: cloning VMs, assigning IPs, bootstrapping Kubernetes and configuring internal networking.
|
||||
|
||||
### VM tagging
|
||||
|
||||
:::tip
|
||||
The name provided to the cluster is also used to tag VMs, so that you can easily find them all:
|
||||
:::
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
## During deployment
|
||||
|
||||
Follow the progress on the **Task** screen while the cluster is being created:
|
||||

|
||||
|
||||
## Using your cluster
|
||||
|
||||
### Connecting to your cluster
|
||||
|
||||
Once the cluster and its VMs are ready, SSH into the first control plane node. From there, you can manage your Kubernetes cluster.
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
$ ssh debian@<replace-by-vm-ip>
|
||||
|
||||
$ debian@cp-1:~$ microk8s kubectl get nodes
|
||||
NAME STATUS ROLES AGE VERSION
|
||||
cp-1 Ready <none> 40m v1.33.0
|
||||
cp-2 Ready <none> 30m v1.33.0
|
||||
cp-3 Ready <none> 31m v1.33.0
|
||||
worker-1 Ready <none> 31m v1.33.0
|
||||
worker-2 Ready <none> 31m v1.33.0
|
||||
worker-3 Ready <none> 31m v1.33.0
|
||||
```
|
||||
|
||||
### Adjusting VM Resources
|
||||
|
||||
The VMs in your Kubernetes cluster are created with default CPU and RAM settings, but you can easily adjust these to match your workload needs.
|
||||
|
||||
This gives you the flexibility to fine-tune performance or cut costs, depending on what your use case demands.
|
||||
|
||||
### Keeping your cluster updated
|
||||
|
||||
:::tip
|
||||
MicroK8s handles **patch releases** automatically by design, so you always benefit from the latest security fixes and improvements without manual intervention. We think this is a great feature as it helps keep your cluster secure and up to date effortlessly.
|
||||
:::
|
||||
|
||||
For **minor version upgrades** (for example, from `1.30.x` to `1.31.x`), you will need to follow the official [MicroK8s upgrade guide](https://microk8s.io/docs/upgrading?ref=xen-orchestra.com). These upgrades typically involve:
|
||||
|
||||
- Checking the current version with `microk8s version`
|
||||
- Refreshing the MicroK8s snap to the desired channel
|
||||
- Restarting the nodes if necessary
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
# Check current version
|
||||
microk8s version
|
||||
|
||||
# Upgrade to a new minor release
|
||||
sudo snap refresh microk8s --channel=1.31/stable
|
||||
```
|
||||
:::warning
|
||||
Always review the MicroK8s documentation for the most up-to-date instructions before performing a minor upgrade.
|
||||
:::
|
||||
|
||||
### Managing your cluster with external tools
|
||||
|
||||
Once the deployment finishes, Xen Orchestra provides a `kubeconfig` file. You can use it to manage your cluster with external tools:
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
$ microk8s config
|
||||
apiVersion: v1
|
||||
clusters:
|
||||
- cluster:
|
||||
certificate-authority-data: [...]
|
||||
server: https://10.1.134.51:16443
|
||||
name: microk8s-cluster
|
||||
contexts:
|
||||
- context:
|
||||
cluster: microk8s-cluster
|
||||
user: admin
|
||||
name: microk8s
|
||||
current-context: microk8s
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users:
|
||||
- name: admin
|
||||
user:
|
||||
client-certificate-data: LS0tLS1CRU[...]
|
||||
client-key-data: LS0tLS1CRUdJ[...]
|
||||
```
|
||||
|
||||
### Add-ons
|
||||
|
||||
In addition to the core components of the Kubernetes control plane, this recipe automatically installs the following add-ons:
|
||||
|
||||
- **DNS:** Deploys CoreDNS for internal address resolution.
|
||||
- **Helm:** Installs [Helm 3](https://helm.sh/), the Kubernetes package manager.
|
||||
- **RBAC:** Enable [Role-based access control (RBAC)](https://kubernetes.io/docs/reference/access-authn-authz/rbac/) for authorization.
|
||||
|
||||
When **high availability (HA)** is enabled, the recipe also includes:
|
||||
|
||||
- **HA-cluster:** Ensures high availability for clusters with three or more nodes.
|
||||
- **[Kube-VIP](https://kube-vip.io/):** Provides a virtual IP and load balancer for the control plane, deployed via the official Helm chart.
|
||||
|
||||
## Best Practices
|
||||
|
||||
When deploying Kubernetes clusters with recipes, it’s important to plan for performance and reliability.
|
||||
|
||||
- Always allocate enough CPU and memory resources for both control plane and worker nodes. Using three control plane nodes ensures high availability in production environments.
|
||||
- Place the VMs on shared storage to allow live migration if needed.
|
||||
- For security, restrict SSH and api-server accesses and consider enabling RBAC and network policies once the cluster is running.
|
||||
|
||||
Finally, keep your base template up to date with the latest OS patches and Kubernetes tools to avoid compatibility issues.
|
||||
|
||||
## Related links
|
||||
|
||||
- [Kubernetes official documentation](https://kubernetes.io/docs/home/)
|
||||
- [MicroK8s official documentation](https://microk8s.io/docs)
|
||||
- [CoreDNS official documentation](https://coredns.io/manual/toc/)
|
||||
@@ -1 +1,101 @@
|
||||
---
|
||||
sidebar_label: Management in XO 6
|
||||
---
|
||||
|
||||
# Management
|
||||
|
||||
This page walks through day-to-day management in XO 6: pools, hosts and VMs. For the general layout and navigation, start with [Getting started](gettingstarted.md).
|
||||
|
||||
## Pools
|
||||
|
||||
A pool page opens on its dashboard: host and VM status, alarms, the list of missing patches with their versions, storage and RAM usage per host, and CPU provisioning at a glance.
|
||||
|
||||
<UiShot light="/img/xo6/pool-dashboard-light.png" dark="/img/xo6/pool-dashboard-dark.png" alt="A pool dashboard, with missing patches and resource usage" url="https://your-xo/v6/#/pool/…/dashboard" />
|
||||
|
||||
The other tabs cover the pool's building blocks:
|
||||
|
||||
- **System**: identity and properties of the pool.
|
||||
- **Network**: pool-wide networks and host internal networks, each with a query builder and a details side panel. You can create networks (including bonded and host internal networks) and delete them; editing an existing network opens XO 5.
|
||||
- **Security**: security-related settings of the pool.
|
||||
- **Storage**: the pool's storage repositories, with connect, disconnect and delete actions (SR creation opens XO 5).
|
||||
- **Tasks**: what happened on this pool.
|
||||
- **Hosts** and **VMs**: filtered lists scoped to this pool.
|
||||
|
||||
From a pool you can also connect a new pool to Xen Orchestra (**Connect pool**, from the top level) and create a VM (**New VM**).
|
||||
|
||||
## Hosts
|
||||
|
||||
The host dashboard shows the quick info of the server: XCP-ng version, hardware model, sockets and RAM, whether it is the primary host, plus alarms and its missing patches.
|
||||
|
||||
<UiShot light="/img/xo6/host-dashboard-light.png" dark="/img/xo6/host-dashboard-dark.png" alt="A host dashboard" url="https://your-xo/v6/#/host/…/dashboard" />
|
||||
|
||||
Two host tabs deserve a special mention:
|
||||
|
||||
- **Console**: a live console to the XCP-ng host itself, with fullscreen mode, an option to open it chrome-less in a dedicated tab, and Ctrl+Alt+Del (a console clipboard is visible in the interface but marked coming soon).
|
||||
|
||||
<UiShot light="/img/xo6/host-console-light.png" dark="/img/xo6/host-console-dark.png" alt="The host console" url="https://your-xo/v6/#/host/…/console" />
|
||||
|
||||
- **Change state**: host power operations (start, shutdown) from the header of the page, plus enable, disable, PIF scanning and the bug-tools archive download from the host action menus.
|
||||
|
||||
The remaining tabs (System, Network, Storage, Tasks, VMs) follow the same patterns as pools.
|
||||
|
||||
## VMs
|
||||
|
||||
The VM page is where you will spend most of your time. Its dashboard gathers the quick info (state, IP address, OS, vCPUs, RAM, virtualization mode, guest tools version and tags), the last backup runs and the protection status, the last replication, and the VM alarms.
|
||||
|
||||
<UiShot light="/img/xo6/vm-dashboard-light.png" dark="/img/xo6/vm-dashboard-dark.png" alt="A VM dashboard" url="https://your-xo/v6/#/vm/…/dashboard" />
|
||||
|
||||
### Lifecycle
|
||||
|
||||
The **Change state** menu in the header drives the VM lifecycle: pause, suspend, reboot, force reboot, shutdown and force shutdown (and start, or start on a specific host, for a halted VM). The VM action menu goes further: duplicate the VM, export it as XVA or OVA, snapshot it, or delete it.
|
||||
|
||||
<UiShot light="/img/xo6/vm-change-state-light.png" dark="/img/xo6/vm-change-state-dark.png" alt="VM power actions" url="https://your-xo/v6/#/vm/…/dashboard" />
|
||||
|
||||
### Console
|
||||
|
||||
The **Console** tab is a full VNC console in the browser: fullscreen, open chrome-less in a new tab, and send Ctrl+Alt+Del (a two-way console clipboard is visible in the interface but marked coming soon).
|
||||
|
||||
<UiShot light="/img/xo6/vm-console-light.png" dark="/img/xo6/vm-console-dark.png" alt="The VM console" url="https://your-xo/v6/#/vm/…/console" />
|
||||
|
||||
### Storage, network and snapshots
|
||||
|
||||
- **VDIs**: the virtual disks of the VM, with real actions: create or attach a disk, connect and disconnect, migrate a VDI to another storage repository, export its content, detach or delete it.
|
||||
- **Network**: its virtual interfaces, with connect, disconnect, delete and VIF creation.
|
||||
- **Snapshots**: the snapshot history, with the last snapshot and last revert highlighted. Take a new snapshot, revert the VM to any of them, or delete them, directly from XO 6.
|
||||
|
||||
<UiShot light="/img/xo6/vm-snapshots-light.png" dark="/img/xo6/vm-snapshots-dark.png" alt="VM snapshots" url="https://your-xo/v6/#/vm/…/snapshots" />
|
||||
|
||||
### Creating a VM
|
||||
|
||||
**New VM** (from a pool, or from the VMs lists) opens the VM creation form. Picking a template unlocks the full form: install settings (SSH key, cloud-init user and network config, ISO, PXE), name and description, boot firmware with vTPM and Secure Boot options, affinity host, high availability, vCPUs and RAM, network interfaces and disks, and whether to boot the VM right after creation. Creating several VMs at once is not available yet; for that, use XO 5.
|
||||
|
||||
<UiShot light="/img/xo6/new-vm-light.png" dark="/img/xo6/new-vm-dark.png" alt="Creating a VM: it starts with a template" url="https://your-xo/v6/#/vm/new" />
|
||||
|
||||
## Traffic rules {#traffic-rules}
|
||||
|
||||
Traffic rules are the first feature built for XO 6 first: allow or block traffic **network-wide or per virtual interface (VIF)**, from a single place. Typical use case: isolating VMs that share a subnet or a VLAN, without touching anything inside the guests.
|
||||
|
||||
They live in two places:
|
||||
|
||||
- **Pool → Security tab**: every traffic rule of the pool, across all its networks and VIFs, in one consolidated view.
|
||||
- **VIF → Traffic rules tab**: the rules of one specific interface (also reachable from the VIF column in the VM Network tab).
|
||||
|
||||
<UiShot light="/img/xo6/pool-security-light.png" dark="/img/xo6/pool-security-dark.png" alt="The pool Security tab gathers every traffic rule of the pool" url="https://your-xo/v6/#/pool/…/security" />
|
||||
|
||||
A rule is simple to express: allow or block, a protocol (ARP, ICMP, IP, TCP or UDP), a port for TCP/UDP, an IP address or a CIDR subnet, a direction (from, to, or both), and the object it applies to: a whole network, or a single VIF.
|
||||
|
||||
<UiShot light="/img/xo6/traffic-rule-new-light.png" dark="/img/xo6/traffic-rule-new-dark.png" alt="The new traffic rule form: policy, protocol, direction, IP range, and the network or VIF it applies to" url="https://your-xo/v6/#/traffic-rule/new" />
|
||||
|
||||
:::warning Prerequisites
|
||||
Traffic rules are enforced by the [SDN Controller plugin](../xo5/sdn_controller.md): it must be loaded, and switched to the **XAPI plugin** mode ([`useDirectChannel = false`](../configuration.md#sdn-controller-mode)). XO 6 shows a notification guiding you through the switch, and a [migration script](../xo5/sdn_controller.md#migration-path) converts existing rules.
|
||||
:::
|
||||
|
||||
Everything is also available through the [REST API](../automation/restapi.md), where rules can additionally be updated in place, making network policies easy to automate.
|
||||
|
||||
## Users and administration
|
||||
|
||||
The **Administration** tab of the sidebar covers who can access your Xen Orchestra. **Users** are listed in XO 6 with their details, groups and authentication tokens (creating and editing users still happens in XO 5); **Groups**, **Roles** and **LDAP or other authentication providers** open their XO 5 configuration pages.
|
||||
|
||||
<UiShot light="/img/xo6/administration-light.png" dark="/img/xo6/administration-dark.png" alt="The administration panel" url="https://your-xo/v6/#/admin/user-management/users" />
|
||||
|
||||
For the permission model itself (roles, scopes and delegation), see [RBAC](../rbac.md).
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
# Packer provider
|
||||
@@ -1,141 +0,0 @@
|
||||
# Powershell module
|
||||
|
||||
## Introduction
|
||||
|
||||
Xen Orchestra (XO) is a powerful tool for managing XCP-ng and XenServer virtualisation environments. However, relying solely on the web interface can result in repetitive manual tasks. For system administrators, particularly those working in Windows-centric environments, **PowerShell** is the go-to automation tool. The `xo-powershell` module combines the strengths of these two tools by offering PowerShell's scripting capabilities to interact directly with the Xen Orchestra API. This article presents the most impactful features of the module, which can significantly simplify and accelerate the management of your virtualisation infrastructure.
|
||||
|
||||
## Single-Line Installation and Connection
|
||||
|
||||
The `xo-powershell` module stands out for its ease of adoption, with simple installation from the [PowerShell Gallery](https://www.powershellgallery.com/packages/xo-powershell/) in a single command.
|
||||
|
||||
:::info
|
||||
**Prerequisites**: PowerShell 7.0 or higher. The module is compatible with Windows PowerShell and PowerShell Core.
|
||||
:::
|
||||
|
||||
```bash
|
||||
Install-Module -Name xo-powershell -AllowPrerelease
|
||||
```
|
||||
|
||||
Likewise, connecting to your Xen Orchestra instance is just as straightforward, requiring only the host address and an API token.
|
||||
|
||||
:::info
|
||||
**Obtaining the API token**: In Xen Orchestra, go to User Space → Edit my settings → Authentication tokens to generate an API token. [Learn more about authentication](https://docs.xcp-ng.org/management/manage-at-scale/xo-api/#authentification).
|
||||
:::
|
||||
|
||||
```bash
|
||||
Connect-XoSession -HostName "https://your-xo-server" -Token "your-api-token"
|
||||
```
|
||||
|
||||
## The Power of the Pipeline for Advanced Automation
|
||||
|
||||
What distinguishes this module from a simple API wrapper is its deep integration with the PowerShell pipeline. Most commands are designed to pass objects to one another, allowing the creation of single-line commands that are both powerful and expressive.
|
||||
|
||||
### Example (Simple Usage Examples)
|
||||
|
||||
* **List XCP-ng servers:**
|
||||
```bash
|
||||
Get-XoServer
|
||||
```
|
||||

|
||||
|
||||
* **Monitor ongoing tasks:**
|
||||
```bash
|
||||
Get-XoTask
|
||||
```
|
||||

|
||||
|
||||
* **Get information about virtual disks:**
|
||||
```bash
|
||||
Get-XoVdi
|
||||
```
|
||||

|
||||
|
||||
* **To stop all virtual machines whose name contains "`Test`," the following command suffices:**
|
||||
|
||||
```bash
|
||||
Get-XoVm | Where-Object { $_.Name -like "*Test*" } | Stop-XoVm
|
||||
```
|
||||
|
||||
- This command first retrieves the list of all VMs, filters it to keep only those whose name matches the criteria, and then passes only these VMs to the `Stop-XoVm` command.
|
||||
|
||||
- This is possible because `Get-XoVm` does not simply return text but a collection of PowerShell objects. Each VM object has properties (`.Name`, `.Memory`, etc.) that can be inspected by `Where-Object` before the complete object is passed to the next command.
|
||||
|
||||
|
||||
* **This principle also applies to more complex filtering, such as suspending running VMs with more than 4 GB of memory.**
|
||||
|
||||
```bash
|
||||
Get-XoVm -PowerState Running | Where-Object { $_.Memory.size -gt 4294967296 } | Suspend-XoVm
|
||||
```
|
||||
|
||||
:::info
|
||||
This capability transforms script writing, moving from a series of disconnected commands to a fluid flow of data and actions.
|
||||
:::
|
||||
|
||||
## Extended Environment Control (VM Management)
|
||||
|
||||
Although virtual machine management is an essential function, the scope of the module is much broader, offering complete control over the entire virtualisation environment. It provides in-depth coverage of all facets of the infrastructure.
|
||||
|
||||
- **Practical Use Cases**
|
||||
|
||||
| Scenario | Command Sequence | Benefit |
|
||||
| :--- | :--- | :--- |
|
||||
| **Storage Audit** | `Get-XoSr` → `Get-XoVdi` → `Get-XoVmVdi` | Comprehensive storage utilization view |
|
||||
| **Maintenance Planning** | `Get-XoHost` → `Get-XoVm` → `Stop-XoVm` → `Wait-XoTask` | Planned maintenance without data loss |
|
||||
| **Session Verification** | `Test-XoSession` | Verify automation readiness |
|
||||
|
||||
This extended control is particularly useful. The 'Wait-XoTask' command enables the creation of robust scripts that wait for lengthy operations (such as creating a **snapshot**) to complete before continuing execution. This functionality makes the module a true command-line interface for Xen Orchestra and not just a tool for a few common tasks.
|
||||
|
||||
### Example: Creating virtual machine snapshots
|
||||
|
||||
This demonstration shows how to create and verify a virtual machine snapshot.
|
||||
|
||||
- **Step 1: Identify a Base VM**
|
||||
|
||||
```bash
|
||||
Get-XoVm | Format-Table Name, Uuid, PowerState
|
||||
```
|
||||

|
||||
|
||||
- **Step 2: Create a Snapshot**
|
||||
|
||||
```bash
|
||||
New-XoVmSnapshot -VmUuid "993d84c2-2571-8451-8073-afa8ef510a8d" -SnapshotName "your-snapshot-name"
|
||||
```
|
||||

|
||||
|
||||
- **Step 3: Verify Snapshot Creation**
|
||||
|
||||
```bash
|
||||
Get-XoVmSnapshot -Filter "name_label:your-snapshot-name"
|
||||
```
|
||||

|
||||
|
||||

|
||||
|
||||
<!--
|
||||
## Export Your Disks and Snapshots Directly to VHD or RAW
|
||||
|
||||
The module simplifies complex tasks such as exporting virtual disks (VDI) and their snapshots. The ideal way to back up the current state of a virtual disk is to use the `Export-XoVdi` command.
|
||||
|
||||
```bash
|
||||
Export-XoVdi -VdiId "a1b2c3d4" -Format vhd -OutFile "C:\exports\disk_backup.vhd"
|
||||
```
|
||||
|
||||
Furthermore, to create an archive of a *point-in-time* version of a disk, you can export one of its snapshots directly. This is ideal for backup or migration workflows based on specific restoration points, as it does not affect the active VM.
|
||||
|
||||
```bash
|
||||
Export-XoVdiSnapshot -VdiSnapshotId "e5f6g7h8" -Format vhd -OutFile "C:\archives\disk_snapshot_archive.vhd"
|
||||
```
|
||||
|
||||
This distinction enables granular backup and migration strategies that are fully script-managed.
|
||||
-->
|
||||
|
||||
## Conclusion: Rethink Your XCP-ng Management
|
||||
|
||||
The `Xo-powershell` module is much more than just a collection of commands: it is a gateway to powerful, scalable and efficient automation within the XCP-ng/Xen Orchestra ecosystem. Leveraging the PowerShell pipeline and a comprehensive set of commands aligns it with the DevOps philosophy, bringing automation practices closer to Windows administrators and helping them save valuable time while reducing the risk of human error.
|
||||
|
||||
## Related links
|
||||
|
||||
- [PowerShell Gallery](https://www.powershellgallery.com/packages/xo-powershell/)
|
||||
- [PowerShell module GitHub](https://xcp-ng.org/forum/category/29/infrastructure-as-code)
|
||||
- [Learn more about authentication](https://docs.xcp-ng.org/management/manage-at-scale/xo-api/#authentification)
|
||||
@@ -1,466 +0,0 @@
|
||||
# Pulumi provider
|
||||
|
||||
## Introduction
|
||||
|
||||
Manually managing infrastructure can lead to errors and increased complexity. With Infrastructure as Code (IaC), however, we can describe our infrastructure in configuration files, making it **predictable**, **reproducible** and **versioned**.
|
||||
|
||||
This tutorial will guide you through using **Pulumi**, a modern IaC tool, to automate the deployment and updating of your **virtual machines (VMs)** on **Xen Orchestra (XO)**.
|
||||
|
||||
:::note
|
||||
Pulumi supports several programming languages (TypeScript, Python, Go, .NET, etc.), but we will use TypeScript for this example. To do this, you need to install Node/NPM version 20 or higher.
|
||||
:::
|
||||
|
||||
:::tip
|
||||
Pulumi's approach allows you to use real programming languages to define your infrastructure, offering more flexibility and power than traditional configuration languages.
|
||||
:::
|
||||
|
||||
## Launching virtual machines in XO with Pulumi
|
||||
|
||||
In this tutorial, we will guide you through the process of using `Pulumi` to launch a virtual machine (VM) on your Xen Orchestra (XO) instance and demonstrate how to easily modify it.
|
||||
|
||||
:::note
|
||||
Since Pulumi relies on the Xen Orchestra API to abstract hosts, pools, networks, disks and virtual machines (VMs), as well as to manipulate them declaratively, ensure you have a functioning Xen Orchestra instance connected to XCP-ng before you begin.
|
||||
:::
|
||||
|
||||
**Here are the four main steps we will follow:**
|
||||
|
||||
1. Install Pulumi
|
||||
2. Create a Pulumi project
|
||||
3. Use Pulumi to provision the VM
|
||||
4. Add an additional network interface to the VM
|
||||
|
||||
:::tip
|
||||
The code used in this tutorial can be found on [GitHub](https://github.com/vatesfr/pulumi-xenorchestra), but we will write it from scratch step by step.
|
||||
:::
|
||||
|
||||
### Installing Pulumi
|
||||
|
||||
If you haven't installed Pulumi yet, follow the [official Pulumi tutorial](https://www.pulumi.com/docs/install/) to install it on your system.
|
||||
|
||||
:::info
|
||||
**Required version**: This tutorial requires Pulumi version v3.0+ or newer, as well as the Xen Orchestra provider version v2.0+.
|
||||
:::
|
||||
|
||||
### Using VM Templates in Xen Orchestra
|
||||
|
||||
Pulumi needs a starting point to create a VM. This can be a `template` that already contains an operating system installed with **cloud-init** capabilities (or **Cloudbase-init** for Windows), as well as **Xen/Guest Tools** for better integration with Xen Orchestra.
|
||||
|
||||
:::info
|
||||
We recommend using the pre-built templates from the **XOA Hub** for optimal results.
|
||||
- **Debian 13** (with cloud-init)
|
||||
- **Ubuntu 22.04/24.04** (with cloud-init)
|
||||
- **etc.**
|
||||
|
||||
For more information on templates:
|
||||
- [Creating VM templates](https://docs.xen-orchestra.com/vm-templates#creating-templates)
|
||||
- [Cloud-init and Cloudbase-init](https://docs.xen-orchestra.com/vm-templates#cloud-init-and-cloudbase-init)
|
||||
:::
|
||||
|
||||
### Provisioning your VM with Pulumi
|
||||
|
||||
Now that Pulumi is installed and you have a VM template ready in your environment, you can start writing the configuration files that describe your infrastructure.
|
||||
|
||||
1. **Creating the Pulumi project**
|
||||
|
||||
Create a new directory for your project and initialise the project:
|
||||
|
||||
```bash
|
||||
mkdir xo-pulumi-project
|
||||
cd xo-pulumi-project
|
||||
pulumi new typescript
|
||||
```
|
||||
|
||||
2. **Installing the Xen Orchestra provider**
|
||||
|
||||
Install the Pulumi Xen Orchestra package:
|
||||
|
||||
```bash
|
||||
npm install @vates/pulumi-xenorchestra
|
||||
```
|
||||
|
||||
3. **Securely configuring credentials**
|
||||
|
||||
In order to authenticate Pulumi with your **Xen Orchestra API**, credentials are required.
|
||||
|
||||
:::warning
|
||||
Never store passwords directly in your code. The recommended method is to use environment variables.
|
||||
:::
|
||||
|
||||
- Create a `~/.xoa` file in your home directory containing the following content:
|
||||
|
||||
```bash
|
||||
export XOA_URL=ws://hostname-of-your-deployment
|
||||
export XOA_USER=YOUR_USERNAME
|
||||
export XOA_PASSWORD=YOUR_PASSWORD
|
||||
```
|
||||
Or, if you are using a token:
|
||||
```bash
|
||||
export XOA_URL=ws://hostname-of-your-deployment
|
||||
export XOA_TOKEN=YOUR_TOKEN
|
||||
```
|
||||
|
||||
- Then, before running Pulumi, load these variables into your terminal session:
|
||||
|
||||
```bash
|
||||
eval $(cat ~/.xoa)
|
||||
```
|
||||
|
||||
:::tip
|
||||
It is also possible to use the Pulumi configuration to store the credentials.
|
||||
|
||||
```bash
|
||||
pulumi config set xenorchestra:url ws://your-xo-hostname
|
||||
pulumi config set xenorchestra:token YOUR_TOKEN --secret
|
||||
```
|
||||
:::
|
||||
|
||||
4. **Defining existing resources (data sources)**
|
||||
|
||||
Pulumi needs to be aware of the resources already in place in XO (e.g. your pool, network and storage). To achieve this, we use data calls to retrieve existing information.
|
||||
|
||||
Edit the `index.ts` file and replace its contents with:
|
||||
|
||||
```typescript
|
||||
import * as pulumi from "@pulumi/pulumi";
|
||||
import * as xenorchestra from "@vates/pulumi-xenorchestra";
|
||||
|
||||
// Retrieving the pool
|
||||
const pool = xenorchestra.getXoaPool({
|
||||
nameLabel: "Main pool",
|
||||
});
|
||||
|
||||
// Retrieve the template
|
||||
const template = xenorchestra.getXoaTemplate({
|
||||
nameLabel: "Ubuntu 24.04 Cloud-Init",
|
||||
});
|
||||
|
||||
// Retrieve the storage repository
|
||||
const storageRepository = pool.then(p =>
|
||||
xenorchestra.getXoaStorageRepository({
|
||||
nameLabel: "ZFS",
|
||||
poolId: p.id,
|
||||
})
|
||||
);
|
||||
|
||||
// Retrieve the network
|
||||
const network = pool.then(p =>
|
||||
xenorchestra.getXoaNetwork({
|
||||
nameLabel: "Pool-wide network",
|
||||
poolId: p.id,
|
||||
})
|
||||
);
|
||||
```
|
||||
|
||||
:::tip
|
||||
Using explicit `nameLabel` values is appropriate for this tutorial.
|
||||
However, in real-world environments, it is recommended to use **unique names** to avoid conflicts or misconfigurations when multiple resources share similar labels.
|
||||
:::
|
||||
|
||||
5. **Defining the VM resource**
|
||||
|
||||
Now that Pulumi knows where to find the template, storage and network, we can define the VM that we want to create.
|
||||
|
||||
Add the following code to the end of your `index.ts` file:
|
||||
|
||||
:::tip
|
||||
If your template uses multiple disks, make sure you declare the same number of disks in your VM resource and pay attention to the order. The disks must be at least the same size as those in the template.
|
||||
:::
|
||||
|
||||
```typescript
|
||||
// Creating the VM
|
||||
const vm = new xenorchestra.Vm("xo-pulumi-tutorial", {
|
||||
memoryMax: 2 * 1024 * 1024 * 1024, // 2GB
|
||||
cpus: 1,
|
||||
nameLabel: "XO Pulumi Tutorial",
|
||||
template: template.then(t => t.id),
|
||||
networks: [
|
||||
{
|
||||
networkId: network.then(n => n.id),
|
||||
},
|
||||
],
|
||||
disks: [
|
||||
{
|
||||
srId: storageRepository.then(sr => sr.id),
|
||||
nameLabel: "VM root volume",
|
||||
size: 50 * 1024 * 1024 * 1024, // 50GB
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
// Export
|
||||
export const vmId = vm.id;
|
||||
export const vmName = vm.nameLabel;
|
||||
export const ipv4 = vm.ipv4Addresses;
|
||||
```
|
||||
|
||||
This code describes the characteristics of the VM to be created, including its `name`, `memory` and `CPU`. It uses the retrieved data to connect to the correct model, network and storage.
|
||||
|
||||
6. **Deploying the VM**
|
||||
|
||||
It's time to bring our VM to life!
|
||||
|
||||
* Run `pulumi up`
|
||||
|
||||
This command will analyse your code and show you what it is about to do. The output will indicate that a new resource is going to be created.
|
||||
|
||||
```bash
|
||||
pulumi up
|
||||
```
|
||||
|
||||
Pulumi will then show you a preview of the changes and ask for confirmation before proceeding.
|
||||
|
||||
```bash
|
||||
Previewing update (dev)
|
||||
|
||||
View in Browser (Ctrl+O): https://app.pulumi.com/batchayw-org/xo-pulumi-project/dev/previews/13fa0ed6-67f7-463d-8e18-83a1fa9571e2
|
||||
|
||||
Type Name Plan
|
||||
+ pulumi:pulumi:Stack xo-pulumi-project-dev create
|
||||
+ └─ xenorchestra:index:Vm xo-pulumi-tutorial create
|
||||
|
||||
Outputs:
|
||||
ipv4 : [unknown]
|
||||
vmId : [unknown]
|
||||
vmName: "XO Pulumi Tutorial"
|
||||
|
||||
Resources:
|
||||
+ 2 to create
|
||||
|
||||
Do you want to perform this update?
|
||||
```
|
||||
|
||||
* Confirm with `yes`
|
||||
|
||||
Pulumi will then deploy the VM on Xen Orchestra.
|
||||
|
||||
```bash
|
||||
Updating (dev)
|
||||
|
||||
View in Browser (Ctrl+O): https://app.pulumi.com/batchayw-org/xo-pulumi-project/dev/updates/1
|
||||
|
||||
Type Name Status
|
||||
+ pulumi:pulumi:Stack xo-pulumi-project-dev created (19s)
|
||||
+ └─ xenorchestra:index:Vm xo-pulumi-tutorial created (17s)
|
||||
|
||||
Outputs:
|
||||
vmId : "0ae54d06-e3e2-100c-00e8-46f67945e37c"
|
||||
vmName: "XO Pulumi Tutorial"
|
||||
|
||||
Resources:
|
||||
+ 2 created
|
||||
|
||||
Duration: 21s
|
||||
```
|
||||
🚀🎉 Congratulations! Your VM has now been deployed via Pulumi on XO.
|
||||
|
||||

|
||||
|
||||
Any future changes to this VM can now be easily **revised** and **versioned**.
|
||||
|
||||
To demonstrate this, let's imagine that this VM needs a second network interface. Let's see how we can easily implement this change.
|
||||
|
||||
### Updating existing infrastructure
|
||||
|
||||
One of Pulumi's greatest strengths lies in its ability to manage changes throughout your infrastructure's lifecycle.
|
||||
|
||||
Our goal is straightforward: to add a second network interface to the VM we just created.
|
||||
|
||||
To achieve this, simply edit the `index.ts` file and add a second network block to your VM definition.
|
||||
|
||||
```typescript
|
||||
// Create the virtual machine with two network interfaces
|
||||
const vm = new xenorchestra.Vm("xo-pulumi-tutorial", {
|
||||
memoryMax: 2 * 1024 * 1024 * 1024, // 2GB
|
||||
cpus: 1,
|
||||
nameLabel: "XO Pulumi Tutorial",
|
||||
template: template.then(t => t.id),
|
||||
networks: [
|
||||
{
|
||||
networkId: network.then(n => n.id),
|
||||
},
|
||||
// Second network interface
|
||||
{
|
||||
networkId: network.then(n => n.id),
|
||||
},
|
||||
],
|
||||
disks: [
|
||||
{
|
||||
srId: storageRepository.then(sr => sr.id),
|
||||
nameLabel: "VM root volume",
|
||||
size: 50 * 1024 * 1024 * 1024, // 50GB
|
||||
},
|
||||
],
|
||||
});
|
||||
```
|
||||
|
||||
The process for applying changes is exactly the same as for creating them.
|
||||
|
||||
* Run `pulumi up`
|
||||
|
||||
This time, the output will be different. Pulumi has detected that the resource already exists and needs to be modified, not created. You will be able to see exactly which network block is going to be added.
|
||||
|
||||
```bash
|
||||
Previewing update (dev)
|
||||
|
||||
View in Browser (Ctrl+O): https://app.pulumi.com/batchayw-org/xo-pulumi-project/dev/previews/9c687495-ba9d-4a8a-8446-f9bb8c2f1826
|
||||
|
||||
Type Name Plan Info
|
||||
pulumi:pulumi:Stack xo-pulumi-project-dev
|
||||
~ └─ xenorchestra:index:Vm xo-pulumi-tutorial update [diff: ~networks]
|
||||
|
||||
Resources:
|
||||
~ 1 to update
|
||||
1 unchanged
|
||||
|
||||
Do you want to perform this update?
|
||||
```
|
||||
|
||||
* Confirm with `yes`
|
||||
|
||||
After confirmation, Pulumi will add the new network interface to your existing VM.
|
||||
|
||||
```bash
|
||||
Updating (dev)
|
||||
|
||||
View in Browser (Ctrl+O): https://app.pulumi.com/batchayw-org/xo-pulumi-project/dev/updates/2
|
||||
|
||||
Type Name Status Info
|
||||
pulumi:pulumi:Stack xo-pulumi-project-dev
|
||||
~ └─ xenorchestra:index:Vm xo-pulumi-tutorial updated (29s) [diff: ~networks]
|
||||
|
||||
Outputs:
|
||||
vmId : "0ae54d06-e3e2-100c-00e8-46f67945e37c"
|
||||
vmName: "XO Pulumi Tutorial"
|
||||
|
||||
Resources:
|
||||
~ 1 updated
|
||||
1 unchanged
|
||||
|
||||
Duration: 32s
|
||||
```
|
||||
|
||||
With just a few lines of code, you can modify your infrastructure in a controlled and reproducible manner.
|
||||
|
||||
* ***Before modification: single network interface***
|
||||

|
||||
|
||||
* ***After adding the second network interface***
|
||||

|
||||
|
||||
|
||||
## Advanced Features
|
||||
|
||||
### Using Cloud-Init
|
||||
|
||||
Pulumi supports `cloud-init` configuration to customize your VMs during deployment.
|
||||
|
||||
```typescript
|
||||
const vmWithCloudInit = new xenorchestra.Vm("vm-with-cloudinit", {
|
||||
// ... other parameters
|
||||
cloudConfig: `#cloud-config
|
||||
users:
|
||||
- name: demo
|
||||
sudo: ALL=(ALL) NOPASSWD:ALL
|
||||
ssh-authorized-keys:
|
||||
- ssh-rsa <YOUR_PUBLIC_KEY_HERE>
|
||||
packages:
|
||||
- nginx
|
||||
- git
|
||||
runcmd:
|
||||
- systemctl enable nginx
|
||||
- systemctl start nginx
|
||||
`,
|
||||
});
|
||||
```
|
||||
|
||||
### Managing multiple disks
|
||||
|
||||
You can easily add multiple disks to a VM.
|
||||
|
||||
```typescript
|
||||
const vmWithMultipleDisks = new xenorchestra.Vm(“vm-multi-disk”, {
|
||||
// ... other parameters
|
||||
disks: [
|
||||
{
|
||||
srId: storageRepository.then(sr => sr.id),
|
||||
nameLabel: “System disk”,
|
||||
size: 30 * 1024 * 1024 * 1024, // 30 GB
|
||||
},
|
||||
{
|
||||
srId: storageRepository.then(sr => sr.id),
|
||||
nameLabel: “Data disk”,
|
||||
size: 100 * 1024 * 1024 * 1024, // 100 GB
|
||||
},
|
||||
],
|
||||
});
|
||||
```
|
||||
|
||||
### Tag configuration
|
||||
|
||||
Add tags to organize and manage your resources.
|
||||
|
||||
```typescript
|
||||
const taggedVm = new xenorchestra.Vm(“tagged-vm”, {
|
||||
// ... other parameters
|
||||
tags: [“production”, “web-server”, “pulumi-managed”],
|
||||
});
|
||||
```
|
||||
|
||||
## Debugging and logs
|
||||
|
||||
The provider supports detailed logging to facilitate troubleshooting and debugging.
|
||||
|
||||
* **Enabling Pulumi logs**
|
||||
|
||||
To enable debug logging, use the verbosity flags.
|
||||
|
||||
```bash
|
||||
pulumi up --debug
|
||||
```
|
||||
Or for more details
|
||||
```bash
|
||||
pulumi up --logtostderr -v=9
|
||||
```
|
||||
|
||||
* **Xen Orchestra provider logs**
|
||||
|
||||
The Xen Orchestra provider also logs its activities. These logs can be viewed in the Pulumi output when debug mode is enabled.
|
||||
|
||||
:::note
|
||||
Only enable debug logging when troubleshooting, as it can significantly increase log verbosity and impact performance.
|
||||
:::
|
||||
|
||||
## Best practices
|
||||
|
||||
### State Management
|
||||
|
||||
:::warning
|
||||
Pulumi state contains sensitive information about your infrastructure. Always use a secure backend such as a self-hosted solution or local encrypted storage.
|
||||
:::
|
||||
|
||||
```bash
|
||||
# Configuration with local encrypted backend (recommended for full control)
|
||||
pulumi login file://~ # Encrypted local storage in home directory
|
||||
pulumi login --local # Default location
|
||||
|
||||
# Or configuration with a self-hosted backend
|
||||
pulumi login s3://my-pulumi-state-bucket
|
||||
pulumi login gs://my-pulumi-state-bucket
|
||||
pulumi login azblob://my-pulumi-state-bucket
|
||||
```
|
||||
|
||||
## Conclusion
|
||||
|
||||
The Pulumi provider for Xen Orchestra is an important step towards VirtOps, which involves applying DevOps practices to virtualisation. By adopting Infrastructure as Code with Pulumi, you can achieve greater reliability, reproducibility and efficiency while transforming infrastructure management into a more collaborative and auditable process.
|
||||
|
||||
:::note
|
||||
For detailed documentation on the provider, see the [official NPM package](https://github.com/vatesfr/pulumi-xenorchestra), which contains up-to-date information on all resources, data sources, and versions.
|
||||
:::
|
||||
|
||||
## Related links
|
||||
|
||||
- [Pulumi documentation](https://www.pulumi.com/docs)
|
||||
- [Pulumi code examples](https://github.com/vatesfr/pulumi-xenorchestra/tree/v2.3.0/examples)
|
||||
- [Pulumi GitHub](https://github.com/vatesfr/pulumi-xenorchestra/issues)
|
||||
- [Xen Orchestra docs](https://docs.xen-orchestra.com)
|
||||
- [XCP-ng forum](https://xcp-ng.org/forum/)
|
||||
@@ -1,171 +0,0 @@
|
||||
# Purchase
|
||||
|
||||
With a subscription, you'll have both Pro Support and XOA Appliance with various features (depending on XOA Edition).
|
||||
|
||||
:::tip
|
||||
To find which XOA Edition fits your needs, please read the [feature matrix page](https://xen-orchestra.com/#!/featuresmatrix) on Xen Orchestra website.
|
||||
:::
|
||||
|
||||
You can buy XOA in multiple ways, depending on your needs. Click on the following links for more documentation:
|
||||
|
||||
- [for your company (direct purchase)](purchase.md#direct-purchase)
|
||||
- [through your purchase department (purchaser)](purchase.md#via-your-purchase-departement)
|
||||
- [for your own client (reseller)](https://vates.tech/blog/empowering-partnerships-an-inside-look-at-vates-new-partner-program/)
|
||||
|
||||
## Direct purchase
|
||||
|
||||
This is the easiest purchase option: you can buy XOA with your registered email account on [https://xen-orchestra.com](https://xen-orchestra.com).
|
||||
|
||||
### Choose your edition
|
||||
|
||||
You can choose the edition you want in two places:
|
||||
|
||||
- [the pricing page](https://vates.tech/pricing-and-support/)
|
||||
- [your account/purchases page](https://xen-orchestra.com/#!/purchases)
|
||||
|
||||
:::tip
|
||||
You need to be logged in to make a purchase. If you don't have an account, please [register here](https://xen-orchestra.com/#!/signup).
|
||||
:::
|
||||
|
||||
From your account page, click on the purchase menu, then select the edition you need:
|
||||
|
||||

|
||||
|
||||
### Purchase options
|
||||
|
||||
The second step is to select your purchase option:
|
||||
|
||||
- Subscription: only available with a credit card payment. Choose this option for a monthly payment or a yearly payment **renewed automatically** each year.
|
||||
|
||||
- Paid period: **check or wire transfer only**. This purchase allows you to subscribe for a one, two or three year period
|
||||
|
||||
:::tip
|
||||
|
||||
- A 2 year subscription period grants you 1 month discounted
|
||||
- A 3 year subscription period grants you 2 months discounted
|
||||
:::
|
||||
|
||||
Then you need to fill in your information and select **"Buy for my own use"** (direct purchase)
|
||||
|
||||

|
||||
|
||||
### Billing information
|
||||
|
||||
You need to complete all the required information on this page in order to move forward.
|
||||
|
||||
:::tip
|
||||
If you are part of the Eurozone, you will need to provide a valid EU VAT number in order to proceed to payment. Transactions between companies inside the Eurozone are VAT free.
|
||||
Transactions outside the Eurozone are VAT free.
|
||||
:::
|
||||
|
||||

|
||||
|
||||
### Select your payment mode
|
||||
|
||||
Credit Card, Wire transfer or Bank check are the three payment methods available on our store. Some methods can be unavailable regarding the purchase option you have selected during step one.
|
||||
|
||||
:::tip
|
||||
Wire transfer is not available for monthly and yearly subscription - Credit Card is not available for paid period.
|
||||
:::
|
||||
|
||||

|
||||
|
||||
:::tip
|
||||
All required information for wire transfer and Check payment will be available in the last step of the payment AND on your proforma invoice.
|
||||
:warning: Please, use an explicit reference for your wire transfer in order for us to easily identify your payment.
|
||||
:::
|
||||
|
||||
## Via your purchase departement
|
||||
|
||||
If you can't purchase using your own account, usually because you need to go through a dedicated purchase department in your company, this is the process you need to follow.
|
||||
|
||||
Typically, you will provide two contacts:
|
||||
|
||||
- The "billing contact" (in general, the purchaser email). This account will have access to invoices. This is the account doing the purchase. Once purchased, the license needs to be bound to the second contact account, the technical contact.
|
||||
- The "technical contact", the email of the system administrator using the solution and making support requests.
|
||||
|
||||
### As "billing contact"
|
||||
|
||||
1. First of all, you need to create an account as a purchaser (eg: "purchase.dept@example.com"). Once it's done, you need to go inside the member page, in the **purchases** menu.
|
||||
|
||||

|
||||
|
||||
Now, you just have to pick the edition of Xen Orchestra you want to purchase for your IT team.
|
||||
|
||||
2. On the first payment screen, after you choose the plan and the subscription method. You can select the option "Buy for another account"
|
||||
|
||||

|
||||
|
||||
3. Once the payment is completed, you will have to bind the plan with the end-user account (technical contact). If the end-user doesn't have an account yet, the system will create one and send an e-mail to your end user.
|
||||
|
||||

|
||||
|
||||
That's it, you have now completed the purchase.
|
||||
|
||||
:::warning
|
||||
Once you have bound the plan to your end user account, you cannot change it. Double check the spelling of the e-mail before binding the account.
|
||||
:::
|
||||
|
||||
## Invoices
|
||||
|
||||
Invoices are available in PDF format. You can find them [in your account](https://xen-orchestra.com/#!/member).
|
||||
|
||||
Get in the "Invoices" tab:
|
||||
|
||||

|
||||
|
||||
:::tip
|
||||
You can download your invoice in PDF format, by clicking in the "Export" row, on the invoice name with the PDF extension.
|
||||
:::
|
||||
|
||||
## Ask for a quote
|
||||
|
||||
You can ask for an automatic quote on our website via the pricing page or directly from you personal account page.
|
||||
|
||||

|
||||
|
||||
Choose the plan you want, the years of commitment that suits you, then fill out the information required (it should be prefilled with your account information).
|
||||
|
||||
If you want to purchase XO using the quote you receive, you just have to enter the quote number into the purchase menu, on your personal account page.
|
||||
|
||||
## Edit your card information
|
||||
|
||||
If you choose a Stripe payment, you can always edit the credit card information in case it changes. To do so, you only have to login to your personal account page and access the _profile_ menu.
|
||||
|
||||

|
||||
|
||||
## Upgrade your plan
|
||||
|
||||
If you want to upgrade your active plan to a higher version of Xen Orchestra, you can do it from your **personal space**.
|
||||
|
||||
### Step by step
|
||||
|
||||
1. Connect on your personal account on the [website](https://xen-orchestra.com/#!/login?source=member.index).
|
||||
|
||||

|
||||
|
||||
2. Go on the purchase menu
|
||||
|
||||

|
||||
|
||||
3. Pick the line corresponding to the account you want to upgrade. Click on the "upgrade" button on the right.
|
||||
|
||||

|
||||
|
||||
4. At this point, you will see a standard subscription page. **Choose the same payment method you used to purchase the initial plan** and confirm the purchase.
|
||||
|
||||

|
||||
|
||||
5. If you choose wire transfer, you have now the possibility to download a quote. As you can see, the remaining period of your previous plan is now a credit note applied on this upgrade.
|
||||
|
||||

|
||||
|
||||
6. As for a regular purchase, upload a proof of payment in order for us to activate your new plan as soon as possible.
|
||||
|
||||

|
||||
|
||||
7. **Enjoy your new plan!**
|
||||
|
||||
:::tip
|
||||
As a reseller, the process is quite the same. The only difference is that you have to pick your customer line into you reseller space and not your personal space.
|
||||
:::
|
||||
@@ -1,598 +0,0 @@
|
||||
# Terraform provider
|
||||
|
||||
## Introduction
|
||||
|
||||
Managing infrastructure manually often leads to errors and complexity. With Infrastructure as Code (IaC), we describe our infrastructure in configuration files to make it **predictable**, **reproducible**, and **version-controlled**.
|
||||
This tutorial will guide you through using **Terraform** or **OpenTofu**, the leading IaC tools, to automate the deployment and updating of your **VMs** on **Xen Orchestra**.
|
||||
|
||||
:::note
|
||||
This guide works with both **Terraform** and **OpenTofu**. OpenTofu is a community-driven fork of Terraform that maintains compatibility.
|
||||
:::
|
||||
|
||||
:::tip
|
||||
Terraform’s two-step workflow (`plan` then `apply`) gives you full control. You can preview all changes before applying them, ensuring safe and predictable deployments while saving time and effort.
|
||||
:::
|
||||
|
||||
## Launching Virtual Machines in XO with Terraform
|
||||
|
||||
In this guide, we’ll walk you step-by-step through using `Terraform` to launch a virtual machine (VM) on your Xen Orchestra (XO) instance, and then show you how to modify it easily.
|
||||
|
||||
:::note
|
||||
*Before starting, make sure you have a running **Xen Orchestra** instance connected to an **XCP-ng** pool.*
|
||||
:::
|
||||
|
||||
**Here are the 4 main steps we’ll follow:**
|
||||
|
||||
1. Install Terraform
|
||||
2. Create a VM template
|
||||
3. Provision the VM with Terraform
|
||||
4. Add an additional network interface to the VM
|
||||
|
||||
:::tip
|
||||
The code used in this tutorial can be found on [GitHub](https://github.com/vatesfr/terraform-provider-xenorchestra), but we’ll write it from scratch step by step.
|
||||
:::
|
||||
|
||||
### Installing Terraform
|
||||
|
||||
If you haven’t installed Terraform yet, start by following the [official Hashicorp tutorial](https://developer.hashicorp.com/terraform/install) to install it on your system.
|
||||
|
||||
:::info
|
||||
**Required Version**: This tutorial requires Terraform `1.13.1` or newer, or OpenTofu `1.10.0` or newer.
|
||||
:::
|
||||
|
||||
### Using VM Templates in Xen Orchestra
|
||||
|
||||
Terraform needs a starting point to create a VM: a `template` that already contains an installed operating system with **cloud-init** capabilities (or **Cloudbase-init** for Windows), as well as **Xen/Guest Tools** for better integration with Xen Orchestra. This setup enables automatic customization during deployment and simplifies VM management, including IP assignment and hostname configuration.
|
||||
|
||||
:::info
|
||||
We recommend using pre-built templates from the **XOA Hub** for optimal results:
|
||||
- **Debian 13** (with cloud-init)
|
||||
- **Ubuntu 22.04/24.04** (with cloud-init)
|
||||
- **etc.**
|
||||
|
||||
For more information about templates:
|
||||
- [Creating VM Templates](https://docs.xen-orchestra.com/vm-templates#creating-templates)
|
||||
- [Cloud-init and Cloudbase-init](https://docs.xen-orchestra.com/vm-templates#cloud-init-and-cloudbase-init)
|
||||
- [Windows Templates with Cloudbase-init](https://xen-orchestra.com/blog/windows-templates-with-cloudbase-init-step-by-step-guide-best-practices/)
|
||||
:::
|
||||
|
||||
### Provisioning Your VM with Terraform
|
||||
|
||||
Now that Terraform is installed and your environment has a VM template ready, let’s start writing the configuration files that describe our infrastructure.
|
||||
|
||||
We will now create the configuration files that describe our infrastructure.
|
||||
|
||||
1. **Configure the Provider**
|
||||
|
||||
The first step is to tell Terraform to communicate with Xen Orchestra by declaring the **official provider**. Create a file named `provider.tf` and add the following code.
|
||||
|
||||
:::info
|
||||
**Provider Version**: This tutorial uses version `~> 0.35` of the Xen Orchestra provider. Check the [official provider documentation](https://registry.terraform.io/providers/vatesfr/xenorchestra/latest) for the latest version and release notes.
|
||||
:::
|
||||
|
||||
```tf
|
||||
# provider.tf
|
||||
terraform {
|
||||
required_providers {
|
||||
xenorchestra = {
|
||||
source = "vatesfr/xenorchestra"
|
||||
version = "~> 0.35"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This code tells Terraform to download [Xen Orchestra Terraform provider](https://github.com/vatesfr/terraform-provider-xenorchestra) from the [official Terraform registry](https://registry.terraform.io/providers/vatesfr/xenorchestra/latest).
|
||||
|
||||
Next, open your terminal in this folder and run `terraform init`. This command reads your configuration, downloads the Xen Orchestra provider, and sets up your working environment.
|
||||
|
||||
You should see output confirming successful initialization.
|
||||
|
||||
```bash
|
||||
william@william:~$ terraform init
|
||||
Initializing the backend...
|
||||
Initializing provider plugins...
|
||||
- Finding vatesfr/xenorchestra versions matching "~> 0.35"...
|
||||
- Installing vatesfr/xenorchestra v0.35.1...
|
||||
- Installed vatesfr/xenorchestra v0.35.1 (self-signed, key ID 3084D82948625D89)
|
||||
Partner and community providers are signed by their developers.
|
||||
If you'd like to know more about provider signing, you can read about it here:
|
||||
https://developer.hashicorp.com/terraform/cli/plugins/signing
|
||||
Terraform has created a lock file .terraform.lock.hcl to record the provider
|
||||
selections it made above. Include this file in your version control repository
|
||||
so that Terraform can guarantee to make the same selections by default when
|
||||
you run "terraform init" in the future.
|
||||
|
||||
Terraform has been successfully initialized!
|
||||
|
||||
You may now begin working with Terraform. Try running "terraform plan" to see
|
||||
any changes that are required for your infrastructure. All Terraform commands
|
||||
should now work.
|
||||
|
||||
If you ever set or change modules or backend configuration for Terraform,
|
||||
rerun this command to reinitialize your working directory. If you forget, other
|
||||
commands will detect it and remind you to do so if necessary.
|
||||
```
|
||||
|
||||
2. **Handle Credentials Securely**
|
||||
|
||||
To authenticate Terraform with your **Xen Orchestra API**, it needs credentials.
|
||||
|
||||
:::warning
|
||||
Never store passwords directly in your code. The recommended method is to use environment variables.
|
||||
:::
|
||||
|
||||
- Create a file `~/.xoa` in your home directory with the following content.
|
||||
|
||||
```bash
|
||||
export XOA_URL=ws://hostname-of-your-deployment
|
||||
export XOA_USER=YOUR_USERNAME
|
||||
export XOA_PASSWORD=YOUR_PASSWORD
|
||||
```
|
||||
Or using a token:
|
||||
|
||||
```bash
|
||||
export XOA_URL=ws://hostname-of-your-deployment
|
||||
export XOA_TOKEN=YOUR_TOKEN
|
||||
```
|
||||
|
||||
- Then, before running Terraform, load these variables into your terminal session.
|
||||
|
||||
```bash
|
||||
eval $(cat ~/.xoa)
|
||||
```
|
||||
|
||||
:::tip
|
||||
It’s also possible to use variables to configure authentication details.
|
||||
This can be useful in some cases, especially to avoid storing credentials in plain text.
|
||||
|
||||
```bash
|
||||
provider "xenorchestra" {
|
||||
# Must be ws or wss
|
||||
token = local.xoa_token # or set the XOA_TOKEN environment variable
|
||||
url = "ws://${local.xoa_url}" # or set the XOA_URL environment variable
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
3. **Define Existing Resources (Data Sources)**
|
||||
|
||||
Terraform needs to know about existing resources in XO (your pool, network, storage, etc.). For that, we use `data` blocks and read-only queries that fetch existing information. This avoids hardcoding technical identifiers (UUIDs, etc.) and makes your configuration more readable and portable.
|
||||
|
||||
Create a file named `vm.tf` (or `data-source.tf`, as most people do) and add the following code, making sure to replace the `name_label` values with the exact names of your resources in Xen Orchestra (the names of your pool, network, storage repository, and VM template, respectively).
|
||||
|
||||
```tf
|
||||
# vm.tf
|
||||
|
||||
data "xenorchestra_pool" "pool" {
|
||||
name_label = "Main pool"
|
||||
}
|
||||
|
||||
data "xenorchestra_template" "vm_template" {
|
||||
name_label = "Ubuntu 24.04 Cloud-Init"
|
||||
}
|
||||
|
||||
data "xenorchestra_sr" "sr" {
|
||||
name_label = "ZFS"
|
||||
pool_id = data.xenorchestra_pool.pool.id
|
||||
}
|
||||
|
||||
data "xenorchestra_network" "network" {
|
||||
name_label = "Pool-wide network"
|
||||
pool_id = data.xenorchestra_pool.pool.id
|
||||
}
|
||||
```
|
||||
|
||||
:::tip
|
||||
Using explicit `name_label` values is fine for this tutorial.
|
||||
However, in real environments, it’s recommended to use **unique names** to prevent conflicts or misconfigurations when multiple resources share similar labels.
|
||||
:::
|
||||
|
||||
4. **Verify Data Sources**
|
||||
|
||||
At this stage, even before defining our VM, we can run `terraform plan` for the first time. This is an excellent practice to ensure that Terraform can successfully connect to Xen Orchestra and locate all the resources we have declared.
|
||||
|
||||
```bash
|
||||
william@william:~$ terraform plan
|
||||
data.xenorchestra_pool.pool: Reading...
|
||||
data.xenorchestra_template.vm_template: Reading...
|
||||
data.xenorchestra_pool.pool: Read complete after 0s [id=355ee47d-ff4c-4924-3db2-fd86ae629676]
|
||||
data.xenorchestra_network.network: Reading...
|
||||
data.xenorchestra_sr.sr: Reading...
|
||||
data.xenorchestra_network.network: Read complete after 0s [id=a12df741-f34f-7d05-f120-462f0ab39a48]
|
||||
data.xenorchestra_template.vm_template: Read complete after 0s [id=d0b0869b-2503-0c17-1e5e-3725f6eba342]
|
||||
data.xenorchestra_sr.sr: Read complete after 0s [id=86a9757d-9c05-9fe0-e79a-8243cb1f37f3]
|
||||
|
||||
No changes. Your infrastructure matches the configuration.
|
||||
|
||||
Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.
|
||||
```
|
||||
|
||||
The message `No changes. Infrastructure is up-to-date.` or `No changes. Your infrastructure matches the configuration.` is exactly what we’re expecting. It confirms that our data sources are correctly configured and that Terraform has successfully found the corresponding `pool`, `template`, `SR`, and `network`.
|
||||
|
||||
5. **Define the VM Resource**
|
||||
|
||||
Now that Terraform knows where to find the template, storage, and network, we can finally define the VM we want to create.
|
||||
|
||||
Add the following code block at the end of your `vm.tf` file, or create a new file named `resources.tf`.
|
||||
|
||||
:::tip
|
||||
If your template uses multiple disks, be careful to declare the same number of disks in your VM resource, paying attention to the order. The disks must be at least the same size as those in the template.
|
||||
:::
|
||||
|
||||
```tf
|
||||
resource "xenorchestra_vm" "vm" {
|
||||
memory_max = 2147467264
|
||||
cpus = 1
|
||||
name_label = "XO terraform tutorial"
|
||||
template = data.xenorchestra_template.vm_template.id
|
||||
|
||||
network {
|
||||
network_id = data.xenorchestra_network.network.id
|
||||
}
|
||||
|
||||
disk {
|
||||
sr_id = data.xenorchestra_sr.sr.id
|
||||
name_label = "VM root volume"
|
||||
size = 50214207488
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This `resource` block describes the characteristics of the VM to be created : its `name`, `memory`, and `CPU`. It uses the information retrieved from the data sources to connect to the correct template, network, and storage.
|
||||
|
||||
:::note
|
||||
The code above uses the `.vm_template.id` and `.sr.id` references to match the data sources we defined, ensuring that the configuration works properly.
|
||||
:::
|
||||
|
||||
6. **Plan and Deploy the VM**
|
||||
|
||||
It’s time to bring our VM to life !
|
||||
|
||||
* Run `terraform plan`
|
||||
|
||||
This command will analyze your code and show you what it’s about to do. The output will indicate that a new resource is going to be created.
|
||||
|
||||
```bash
|
||||
william@william:~$ terraform plan
|
||||
data.xenorchestra_pool.pool: Reading...
|
||||
data.xenorchestra_template.vm_template: Reading...
|
||||
data.xenorchestra_pool.pool: Read complete after 1s [id=355ee47d-ff4c-4924-3db2-fd86ae629676]
|
||||
data.xenorchestra_network.network: Reading...
|
||||
data.xenorchestra_sr.sr: Reading...
|
||||
data.xenorchestra_template.vm_template: Read complete after 1s [id=d0b0869b-2503-0c17-1e5e-3725f6eba342]
|
||||
data.xenorchestra_network.network: Read complete after 0s [id=a12df741-f34f-7d05-f120-462f0ab39a48]
|
||||
data.xenorchestra_sr.sr: Read complete after 0s [id=86a9757d-9c05-9fe0-e79a-8243cb1f37f3]
|
||||
|
||||
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following
|
||||
symbols:
|
||||
+ create
|
||||
|
||||
Terraform will perform the following actions:
|
||||
|
||||
# xenorchestra_vm.vm will be created
|
||||
+ resource "xenorchestra_vm" "vm" {
|
||||
+ auto_poweron = false
|
||||
+ clone_type = "fast"
|
||||
+ core_os = false
|
||||
+ cpu_cap = 0
|
||||
+ cpu_weight = 0
|
||||
+ cpus = 1
|
||||
+ destroy_cloud_config_vdi_after_boot = false
|
||||
+ exp_nested_hvm = false
|
||||
+ hvm_boot_firmware = "bios"
|
||||
+ id = (known after apply)
|
||||
+ ipv4_addresses = (known after apply)
|
||||
+ ipv6_addresses = (known after apply)
|
||||
+ memory_max = 2147467264
|
||||
+ memory_min = (known after apply)
|
||||
+ name_label = "XO terraform tutorial"
|
||||
+ power_state = "Running"
|
||||
+ start_delay = 0
|
||||
+ template = "d0b0869b-2503-0c17-1e5e-3725f6eba342"
|
||||
+ vga = "std"
|
||||
+ videoram = 8
|
||||
|
||||
+ disk {
|
||||
+ name_label = "VM root volume"
|
||||
+ position = (known after apply)
|
||||
+ size = 50214207488
|
||||
+ sr_id = "86a9757d-9c05-9fe0-e79a-8243cb1f37f3"
|
||||
+ vbd_id = (known after apply)
|
||||
+ vdi_id = (known after apply)
|
||||
}
|
||||
|
||||
+ network {
|
||||
+ device = (known after apply)
|
||||
+ ipv4_addresses = (known after apply)
|
||||
+ ipv6_addresses = (known after apply)
|
||||
+ mac_address = (known after apply)
|
||||
+ network_id = "a12df741-f34f-7d05-f120-462f0ab39a48"
|
||||
}
|
||||
}
|
||||
|
||||
Plan: 1 to add, 0 to change, 0 to destroy.
|
||||
```
|
||||
|
||||
* Run `terraform apply`
|
||||
|
||||
If the plan looks good to you, run this command to apply the changes. Terraform will ask for final confirmation, type `yes` and press `Enter`.
|
||||
|
||||
```bash
|
||||
william@william:~$ terraform apply
|
||||
data.xenorchestra_template.vm_template: Reading...
|
||||
data.xenorchestra_pool.pool: Reading...
|
||||
data.xenorchestra_pool.pool: Read complete after 1s [id=355ee47d-ff4c-4924-3db2-fd86ae629676]
|
||||
data.xenorchestra_network.network: Reading...
|
||||
data.xenorchestra_sr.sr: Reading...
|
||||
data.xenorchestra_template.vm_template: Read complete after 1s [id=d0b0869b-2503-0c17-1e5e-3725f6eba342]
|
||||
data.xenorchestra_network.network: Read complete after 0s [id=a12df741-f34f-7d05-f120-462f0ab39a48]
|
||||
data.xenorchestra_sr.sr: Read complete after 0s [id=86a9757d-9c05-9fe0-e79a-8243cb1f37f3]
|
||||
|
||||
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following
|
||||
symbols:
|
||||
+ create
|
||||
|
||||
Terraform will perform the following actions:
|
||||
|
||||
# xenorchestra_vm.vm will be created
|
||||
+ resource "xenorchestra_vm" "vm" {
|
||||
+ auto_poweron = false
|
||||
+ clone_type = "fast"
|
||||
+ core_os = false
|
||||
+ cpu_cap = 0
|
||||
+ cpu_weight = 0
|
||||
+ cpus = 1
|
||||
+ destroy_cloud_config_vdi_after_boot = false
|
||||
+ exp_nested_hvm = false
|
||||
+ hvm_boot_firmware = "bios"
|
||||
+ id = (known after apply)
|
||||
+ ipv4_addresses = (known after apply)
|
||||
+ ipv6_addresses = (known after apply)
|
||||
+ memory_max = 2147467264
|
||||
+ memory_min = (known after apply)
|
||||
+ name_label = "XO terraform tutorial"
|
||||
+ power_state = "Running"
|
||||
+ start_delay = 0
|
||||
+ template = "d0b0869b-2503-0c17-1e5e-3725f6eba342"
|
||||
+ vga = "std"
|
||||
+ videoram = 8
|
||||
|
||||
+ disk {
|
||||
+ name_label = "VM root volume"
|
||||
+ position = (known after apply)
|
||||
+ size = 50214207488
|
||||
+ sr_id = "86a9757d-9c05-9fe0-e79a-8243cb1f37f3"
|
||||
+ vbd_id = (known after apply)
|
||||
+ vdi_id = (known after apply)
|
||||
}
|
||||
|
||||
+ network {
|
||||
+ device = (known after apply)
|
||||
+ ipv4_addresses = (known after apply)
|
||||
+ ipv6_addresses = (known after apply)
|
||||
+ mac_address = (known after apply)
|
||||
+ network_id = "a12df741-f34f-7d05-f120-462f0ab39a48"
|
||||
}
|
||||
}
|
||||
|
||||
Plan: 1 to add, 0 to change, 0 to destroy.
|
||||
|
||||
Do you want to perform these actions?
|
||||
Terraform will perform the actions described above.
|
||||
Only 'yes' will be accepted to approve.
|
||||
|
||||
Enter a value: yes
|
||||
|
||||
xenorchestra_vm.vm: Creating...
|
||||
xenorchestra_vm.vm: Still creating... [00m10s elapsed]
|
||||
xenorchestra_vm.vm: Creation complete after 17s [id=66ec6080-1a77-b460-1d63-8b39baa4a844]
|
||||
|
||||
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
|
||||
```
|
||||
|
||||
🚀🎉 Congratulations! Your VM is now deployed via Terraform on XO.
|
||||
|
||||

|
||||
|
||||
|
||||
Any future modifications to this VM can now be easily **reviewed** and **version-controlled**.
|
||||
|
||||
To demonstrate this, let’s imagine that this VM needs a second network interface. Let’s see how easily we can make that change.
|
||||
|
||||
### Updating an Existing Infrastructure
|
||||
|
||||
One of Terraform’s greatest advantages is its ability to manage changes throughout the entire lifecycle of your infrastructure.
|
||||
|
||||
Our goal is simple: to add a second network interface to the VM we just created.
|
||||
|
||||
To do this, simply modify the `resources.tf` file (or `vm.tf` if you combined everything) and add a second `network` block to your VM definition.
|
||||
|
||||
```tf
|
||||
resource "xenorchestra_vm" "vm" {
|
||||
memory_max = 2147467264
|
||||
cpus = 1
|
||||
name_label = "XO terraform tutorial"
|
||||
template = data.xenorchestra_template.vm_template.id
|
||||
|
||||
# First network interface
|
||||
network {
|
||||
network_id = data.xenorchestra_network.network.id
|
||||
}
|
||||
|
||||
# Second network interface
|
||||
network {
|
||||
network_id = data.xenorchestra_network.network.id
|
||||
}
|
||||
|
||||
disk {
|
||||
sr_id = data.xenorchestra_sr.sr.id
|
||||
name_label = "VM root volume"
|
||||
size = 50214207488
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Once the file is modified, the process of applying the change is exactly the same as for creation.
|
||||
|
||||
* Run `terraform plan`
|
||||
|
||||
This time, the output will be different. Terraform has detected that the resource already exists and needs to be **modified**, not created. You’ll be able to see exactly which `network` block is going to be added.
|
||||
|
||||
```bash
|
||||
william@william:~$ terraform plan
|
||||
data.xenorchestra_pool.pool: Reading...
|
||||
data.xenorchestra_template.vm_template: Reading...
|
||||
data.xenorchestra_pool.pool: Read complete after 0s [id=355ee47d-ff4c-4924-3db2-fd86ae629676]
|
||||
data.xenorchestra_network.network: Reading...
|
||||
data.xenorchestra_sr.sr: Reading...
|
||||
data.xenorchestra_template.vm_template: Read complete after 0s [id=d0b0869b-2503-0c17-1e5e-3725f6eba342]
|
||||
data.xenorchestra_network.network: Read complete after 0s [id=a12df741-f34f-7d05-f120-462f0ab39a48]
|
||||
data.xenorchestra_sr.sr: Read complete after 0s [id=86a9757d-9c05-9fe0-e79a-8243cb1f37f3]
|
||||
xenorchestra_vm.vm: Refreshing state... [id=66ec6080-1a77-b460-1d63-8b39baa4a844]
|
||||
|
||||
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following
|
||||
symbols:
|
||||
~ update in-place
|
||||
|
||||
Terraform will perform the following actions:
|
||||
|
||||
# xenorchestra_vm.vm will be updated in-place
|
||||
~ resource "xenorchestra_vm" "vm" {
|
||||
id = "66ec6080-1a77-b460-1d63-8b39baa4a844"
|
||||
tags = []
|
||||
# (24 unchanged attributes hidden)
|
||||
|
||||
disk {
|
||||
# (8 unchanged attributes hidden)
|
||||
}
|
||||
|
||||
+ network {
|
||||
+ attached = true
|
||||
+ ipv4_addresses = (known after apply)
|
||||
+ ipv6_addresses = (known after apply)
|
||||
+ network_id = "a12df741-f34f-7d05-f120-462f0ab39a48"
|
||||
}
|
||||
|
||||
# (1 unchanged block hidden)
|
||||
}
|
||||
|
||||
Plan: 0 to add, 1 to change, 0 to destroy.
|
||||
```
|
||||
|
||||
* Run `terraform apply`
|
||||
|
||||
Run the command to apply the change. After confirming with `yes`, Terraform will add the new network interface to your existing VM.
|
||||
|
||||
```bash
|
||||
william@william:~$ terraform apply
|
||||
data.xenorchestra_pool.pool: Reading...
|
||||
data.xenorchestra_template.vm_template: Reading...
|
||||
data.xenorchestra_pool.pool: Read complete after 0s [id=355ee47d-ff4c-4924-3db2-fd86ae629676]
|
||||
data.xenorchestra_network.network: Reading...
|
||||
data.xenorchestra_sr.sr: Reading...
|
||||
data.xenorchestra_template.vm_template: Read complete after 0s [id=d0b0869b-2503-0c17-1e5e-3725f6eba342]
|
||||
data.xenorchestra_network.network: Read complete after 0s [id=a12df741-f34f-7d05-f120-462f0ab39a48]
|
||||
data.xenorchestra_sr.sr: Read complete after 0s [id=86a9757d-9c05-9fe0-e79a-8243cb1f37f3]
|
||||
xenorchestra_vm.vm: Refreshing state... [id=66ec6080-1a77-b460-1d63-8b39baa4a844]
|
||||
|
||||
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following
|
||||
symbols:
|
||||
~ update in-place
|
||||
|
||||
Terraform will perform the following actions:
|
||||
|
||||
# xenorchestra_vm.vm will be updated in-place
|
||||
~ resource "xenorchestra_vm" "vm" {
|
||||
id = "66ec6080-1a77-b460-1d63-8b39baa4a844"
|
||||
tags = []
|
||||
# (24 unchanged attributes hidden)
|
||||
|
||||
# (3 unchanged blocks hidden)
|
||||
}
|
||||
|
||||
Plan: 0 to add, 1 to change, 0 to destroy.
|
||||
|
||||
Do you want to perform these actions?
|
||||
Terraform will perform the actions described above.
|
||||
Only 'yes' will be accepted to approve.
|
||||
|
||||
Enter a value: yes
|
||||
|
||||
xenorchestra_vm.vm: Modifying... [id=66ec6080-1a77-b460-1d63-8b39baa4a844]
|
||||
xenorchestra_vm.vm: Still modifying... [id=66ec6080-1a77-b460-1d63-8b39baa4a844, 00m10s elapsed]
|
||||
xenorchestra_vm.vm: Still modifying... [id=66ec6080-1a77-b460-1d63-8b39baa4a844, 00m20s elapsed]
|
||||
xenorchestra_vm.vm: Still modifying... [id=66ec6080-1a77-b460-1d63-8b39baa4a844, 00m30s elapsed]
|
||||
xenorchestra_vm.vm: Modifications complete after 36s [id=66ec6080-1a77-b460-1d63-8b39baa4a844]
|
||||
|
||||
Apply complete! Resources: 0 added, 1 changed, 0 destroyed.
|
||||
```
|
||||
|
||||
In just a few lines of code, you’ve modified your infrastructure in a controlled and reproducible way.
|
||||
|
||||
- ***Before the modification - Single network interface***
|
||||

|
||||
|
||||
- ***After adding the second network interface***
|
||||

|
||||
|
||||
## Debugging and Logs
|
||||
|
||||
The provider supports detailed logging for troubleshooting and debugging purposes.
|
||||
|
||||
- **Enable Provider Logs**
|
||||
|
||||
To enable debug logging, set the `TF_LOG_PROVIDER` environment variable:
|
||||
|
||||
```bash
|
||||
export TF_LOG_PROVIDER=DEBUG
|
||||
terraform plan
|
||||
```
|
||||
|
||||
- **Terraform Log Levels**
|
||||
|
||||
You can control the level of provider logging with the `TF_LOG_PROVIDER`environment variable:
|
||||
|
||||
```bash
|
||||
export TF_LOG_PROVIDER=DEBUG
|
||||
terraform apply
|
||||
```
|
||||
|
||||
Valid `TF_LOG_PROVIDER` levels are: `TRACE`, `DEBUG`, `INFO`, `WARN`, `ERROR`.
|
||||
|
||||
- **Log to File**
|
||||
|
||||
To save logs to a file for analysis:
|
||||
|
||||
```bash
|
||||
export TF_LOG_PROVIDER=DEBUG
|
||||
export TF_LOG_PATH=./terraform.log
|
||||
terraform apply
|
||||
```
|
||||
|
||||
:::note
|
||||
Only enable debug logging when troubleshooting, as it can significantly increase log verbosity and may impact performance.
|
||||
:::
|
||||
|
||||
## Conclusion
|
||||
|
||||
The Terraform provider for Xen Orchestra represents an important step toward **VirtOps** (the application of DevOps practices to virtualization). By adopting **Infrastructure as Code**, you gain reliability, reproducibility, and efficiency, as it transforms infrastructure management into a collaborative and auditable process.
|
||||
|
||||
:::note
|
||||
**Commercial Support**: For technical support, contact our support team through your customer portal.
|
||||
|
||||
**Community Support**:
|
||||
- [XCP-ng Forum](https://xcp-ng.org/forum/)
|
||||
- [Discord Community](https://discord.com/invite/ZpNq8ez)
|
||||
- [GitHub Issues](https://github.com/vatesfr/terraform-provider-xenorchestra/issues)
|
||||
|
||||
For detailed provider documentation, check the [official Terraform registry](https://registry.terraform.io/providers/vatesfr/xenorchestra/latest) which contains up-to-date information on all resources, data sources, and releases.
|
||||
:::
|
||||
|
||||
## Related links
|
||||
|
||||
* [Official Terraform Provider Documentation](https://docs.vates.tech/devops-tools/terraform-provider/)
|
||||
* [Official Terraform Documentation](https://developer.hashicorp.com/terraform/docs)
|
||||
* [Official Xen Orchestra Documentation](https://docs.xen-orchestra.com/)
|
||||
* [Official XCP-ng Documentation](https://docs.xcp-ng.org/)
|
||||
* [OpenTofu Documentation](https://opentofu.org/docs/)
|
||||
@@ -2,3 +2,26 @@
|
||||
id: whatsnew
|
||||
title: What's new
|
||||
---
|
||||
|
||||
# What's new in XO 6
|
||||
|
||||
XO 6 is a complete redesign of the Xen Orchestra interface, built as a modern web application on a dedicated design system. It is not a reskin of XO 5: the navigation, the information architecture and the visual language were rebuilt from scratch around how infrastructures are actually operated.
|
||||
|
||||
<UiShot dark="/img/xo6/lab-dashboard.webp" alt="XO 6: one dashboard for every pool, host and VM you manage" url="https://myxoa.domain.tld/v6/#/dashboard" />
|
||||
|
||||
## Highlights
|
||||
|
||||
- **A tree view of your whole infrastructure**: every pool, host and VM in one always-visible, searchable tree. No more jumping between list pages to find an object.
|
||||
- **Dashboards at every level**: Xen Orchestra, pool, host and VM each open on a dashboard that summarizes status, alarms, patches, resources and backup health at that scale.
|
||||
- **Consistent pages**: every object follows the same tab pattern, every table has the same query builder and details side panel. Learn one page, know them all.
|
||||
- **First-class consoles**: VM and host consoles in the browser, with fullscreen, a chrome-less dedicated tab mode and Ctrl+Alt+Del.
|
||||
- **Make it yours**: light and dark color modes, five interface themes, and 21 languages.
|
||||
- **Task visibility**: a Tasks tab at every level records operations, API calls and authentications with their outcomes.
|
||||
- **Backup awareness everywhere**: protection status is visible from the global dashboard down to each VM, including the VMs that no job protects.
|
||||
- **Side-by-side with XO 5**: both interfaces run on the same Xen Orchestra and the same data. Anything not yet in XO 6 is one clearly marked click away.
|
||||
|
||||
## An interface that grows release by release
|
||||
|
||||
XO 6 reached its first official release with a deliberately focused scope, and new capabilities are added continuously: more actions on objects, user management, backup features and more. The [XO 6 vs. XO 5](xo6vsxo5.md) page tracks what lives where today, and the best way to see what is new is simply to keep your Xen Orchestra up to date.
|
||||
|
||||
To explore the interface, start with [Getting started](gettingstarted.md).
|
||||
|
||||
@@ -2,3 +2,39 @@
|
||||
id: xo6vsxo5
|
||||
title: XO 6 vs. XO 5
|
||||
---
|
||||
|
||||
# XO 6 vs. XO 5
|
||||
|
||||
XO 6 and XO 5 are two interfaces to the same Xen Orchestra. They run side by side, on the same server, against the same data: a VM started in one is instantly running in the other, a backup job created in XO 5 immediately shows its health in XO 6. There is no migration step and nothing to synchronize.
|
||||
|
||||
- **XO 6** is the default interface and the future of Xen Orchestra.
|
||||
- **XO 5** remains fully available for everything XO 6 does not cover yet: use the **XO 5** link in the top-right corner, or the marked links that XO 6 shows contextually (they open the right XO 5 page for the object you are on).
|
||||
|
||||
## What lives where today
|
||||
|
||||
XO 6 is under active development, so this table evolves with every release. As a rule of thumb: observing and operating your infrastructure day to day happens in XO 6; deep configuration still happens in XO 5.
|
||||
|
||||
| Area | In XO 6 | Still in XO 5 |
|
||||
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
|
||||
| Navigation and search | Tree view of all pools, hosts, VMs, with live filtering and a query builder on every major table | Object list pages |
|
||||
| Dashboards | Global, pool, host and VM dashboards: status, alarms, patches, resources, usage charts, backup health | Global dashboard, health view |
|
||||
| VM lifecycle | Start (including on a specific host), pause, suspend, resume, reboot, shutdown (normal and forced), duplicate, export as XVA or OVA, delete | Migrate, copy between pools, convert to template, import, self-service |
|
||||
| VM creation | Full single-VM form: template, cloud-init or SSH key or ISO or PXE install, boot firmware, vTPM, Secure Boot, affinity, HA, vCPUs, RAM, VIFs, disks | Multiple VMs at once, tags at creation |
|
||||
| Consoles | VM and host consoles: fullscreen, chrome-less dedicated tab, Ctrl+Alt+Del | Console clipboard (coming soon in XO 6) |
|
||||
| Snapshots | List, take, revert, delete | Snapshot detail view |
|
||||
| Networks | Inspect pool, host and VM networking; create networks (bonded, host internal), create and manage VIFs, traffic rules | Edit existing networks, SDN controller |
|
||||
| Storage | Inspect SRs and VDIs; connect, disconnect and delete SRs; create, attach, export, delete VDIs and migrate them between SRs | SR creation, advanced disk operations |
|
||||
| Performance stats | Usage charts on every dashboard (last week) | Full stats views with granularity control, via the marked Stats link |
|
||||
| Backups | Job list with run history, per-job pages (runs, configuration, backed up VMs, targets), per-VM protection status, dashboard health panels | Job creation and editing, restore, remotes, mirrors, sequences, health checks |
|
||||
| Tasks | Full task history at every level, last-24-hours quick view | Task list |
|
||||
| Users and access | Users list with details, groups and authentication tokens | User creation and editing, groups, roles, LDAP and other auth providers, ACLs |
|
||||
| Settings | Color mode, five themes, 21 languages | Servers, plugins, proxies, licenses, everything under Settings |
|
||||
| Pool and host operations | Connect and disconnect pools, host start, shutdown, enable, disable, PIF scan, bug-tools archive | Patching and updates, rolling pool update, host maintenance and evacuation, HA |
|
||||
|
||||
One more current limitation to know: XO 6 requires an administrator account. Non-admin users are redirected to XO 5 until delegation lands in XO 6.
|
||||
|
||||
## Which one should I use?
|
||||
|
||||
Start every session in XO 6: navigation, monitoring, consoles, task forensics and backup oversight are simply better there. When you hit an operation XO 6 does not do yet, it will either show you the action marked with an external-link icon, or you switch to XO 5 manually and come right back.
|
||||
|
||||
If you prefer to keep XO 5 as your default interface for now, the welcome message of XO 6 links to the procedure to do so.
|
||||
|
||||
+125
-57
@@ -27,9 +27,14 @@ export default {
|
||||
defaultLocale: 'en',
|
||||
locales: ['en'],
|
||||
},
|
||||
themes: ['docusaurus-theme-search-typesense'],
|
||||
|
||||
plugins: [
|
||||
// Kept even though Typesense provides the search UI: this plugin
|
||||
// generates search-doc.json, which the federated search indexer
|
||||
// consumes (src/theme/SearchBar picks the Typesense bar).
|
||||
require.resolve('docusaurus-lunr-search'),
|
||||
[
|
||||
[
|
||||
'@docusaurus/plugin-client-redirects',
|
||||
{
|
||||
redirects: [
|
||||
@@ -37,6 +42,10 @@ export default {
|
||||
to: '/xo5/manage_infrastructure#vms',
|
||||
from: '/administration',
|
||||
},
|
||||
{
|
||||
to: '/rbac',
|
||||
from: '/xo6/acl-v2',
|
||||
},
|
||||
{
|
||||
to: '/xo5/advanced',
|
||||
from: '/advanced',
|
||||
@@ -50,16 +59,20 @@ export default {
|
||||
from: '/acls',
|
||||
},
|
||||
{
|
||||
to: '/xo5/architecture',
|
||||
from: '/architecture',
|
||||
from: '/xo5/architecture',
|
||||
to: '/architecture',
|
||||
},
|
||||
{
|
||||
to: '/xo5/architecture#plugins',
|
||||
to: '/architecture#plugins',
|
||||
from: '/plugins',
|
||||
},
|
||||
{
|
||||
to: '/xo5/backup_howto',
|
||||
from: '/backup_howto',
|
||||
to: '/backup_howto',
|
||||
from: '/xo5/backup_howto',
|
||||
},
|
||||
{
|
||||
to: '/calculator',
|
||||
from: '/xo5/calculator',
|
||||
},
|
||||
{
|
||||
to: '/xo5/backup_reports',
|
||||
@@ -74,28 +87,28 @@ export default {
|
||||
from: '/backups',
|
||||
},
|
||||
{
|
||||
to: '/xo6/community',
|
||||
from: '/community',
|
||||
to: '/community',
|
||||
from: '/xo6/community',
|
||||
},
|
||||
{
|
||||
to: '/xo5/configuration',
|
||||
from: '/configuration',
|
||||
from: '/xo5/configuration',
|
||||
to: '/configuration',
|
||||
},
|
||||
{
|
||||
to: '/xo5/credential-encryption',
|
||||
from: '/credential-encryption',
|
||||
to: '/credential-encryption',
|
||||
from: '/xo5/credential-encryption',
|
||||
},
|
||||
{
|
||||
to: '/xo5/full_backups',
|
||||
from: '/full_backups',
|
||||
to: '/full_backups',
|
||||
from: '/xo5/full_backups',
|
||||
},
|
||||
{
|
||||
to: '/xo5/full_replication',
|
||||
from: '/full_replication',
|
||||
to: '/full_replication',
|
||||
from: '/xo5/full_replication',
|
||||
},
|
||||
{
|
||||
to: '/xo5/immutability',
|
||||
from: '/immutability',
|
||||
to: '/immutability',
|
||||
from: '/xo5/immutability',
|
||||
},
|
||||
{
|
||||
to: '/xo5/incremental_backups',
|
||||
@@ -106,88 +119,112 @@ export default {
|
||||
from: '/incremental_replication',
|
||||
},
|
||||
{
|
||||
to: '/xo5/installation',
|
||||
from: '/installation',
|
||||
from: '/xo5/installation',
|
||||
to: '/installation',
|
||||
},
|
||||
{
|
||||
to: '/xo6/support',
|
||||
from: '/support',
|
||||
to: '/support',
|
||||
from: '/xo6/support',
|
||||
},
|
||||
{
|
||||
to: '/xo5/backup',
|
||||
from: '/backup',
|
||||
to: '/backup',
|
||||
from: '/xo5/backup',
|
||||
},
|
||||
{
|
||||
to: '/xo5/license_management',
|
||||
from: '/license_management',
|
||||
to: '/support',
|
||||
from: ['/license_management', '/xo5/license_management'],
|
||||
},
|
||||
{
|
||||
to: '/xo5/load_balancing',
|
||||
from: '/load_balancing',
|
||||
},
|
||||
{
|
||||
to: '/xo5/manage',
|
||||
from: '/manage',
|
||||
from: ['/manage', '/xo5/manage'],
|
||||
to: '/xo5/manage_infrastructure',
|
||||
},
|
||||
{
|
||||
to: '/xo5/manage_infrastructure',
|
||||
from: '/manage_infrastructure',
|
||||
},
|
||||
{
|
||||
to: '/xo5/mcp',
|
||||
from: '/mcp',
|
||||
to: '/automation/mcp',
|
||||
from: ['/mcp', '/xo5/mcp'],
|
||||
},
|
||||
{
|
||||
to: '/xo5/metadata_backup',
|
||||
from: '/metadata_backup',
|
||||
},
|
||||
{
|
||||
to: '/xo5/migrate_to_new_xoa',
|
||||
from: '/migrate_to_new_xoa',
|
||||
from: '/xo5/migrate_to_new_xoa',
|
||||
to: '/migrate_to_new_xoa',
|
||||
},
|
||||
{
|
||||
to: '/xo5/mirror_backup',
|
||||
from: '/mirror_backup',
|
||||
to: '/mirror_backup',
|
||||
from: '/xo5/mirror_backup',
|
||||
},
|
||||
{
|
||||
to: '/xo5/object-storage-support',
|
||||
from: '/object-storage-support',
|
||||
to: '/object-storage-support',
|
||||
from: '/xo5/object-storage-support',
|
||||
},
|
||||
{
|
||||
to: '/xo5/proxy',
|
||||
from: '/proxy',
|
||||
},
|
||||
{
|
||||
to: '/xo6/purchase',
|
||||
from: '/purchase',
|
||||
to: '/support',
|
||||
from: ['/purchase', '/xo6/purchase'],
|
||||
},
|
||||
{
|
||||
to: '/xo5/releases',
|
||||
from: '/releases',
|
||||
from: '/xo5/releases',
|
||||
to: '/releases',
|
||||
},
|
||||
{
|
||||
to: '/xo5/restapi',
|
||||
from: '/restapi',
|
||||
to: '/automation/restapi',
|
||||
from: ['/restapi', '/xo5/restapi'],
|
||||
},
|
||||
{
|
||||
to: '/xo5/rolling_snapshots',
|
||||
from: '/rolling_snapshots',
|
||||
to: '/automation/terraform-provider',
|
||||
from: '/xo6/terraform-provider',
|
||||
},
|
||||
{
|
||||
to: '/automation/ansible',
|
||||
from: '/xo6/ansible',
|
||||
},
|
||||
{
|
||||
to: '/automation/pulumi-provider',
|
||||
from: '/xo6/pulumi-provider',
|
||||
},
|
||||
{
|
||||
to: '/automation/packer-provider',
|
||||
from: '/xo6/packer-provider',
|
||||
},
|
||||
{
|
||||
to: '/automation/powershell-module',
|
||||
from: '/xo6/powershell-module',
|
||||
},
|
||||
{
|
||||
to: '/automation/kubernetes',
|
||||
from: '/xo6/kubernetes',
|
||||
},
|
||||
{
|
||||
to: '/rolling_snapshots',
|
||||
from: '/xo5/rolling_snapshots',
|
||||
},
|
||||
{
|
||||
to: '/xo5/sdn_controller',
|
||||
from: '/sdn_controller',
|
||||
},
|
||||
{
|
||||
to: '/xo5/supported_hosts',
|
||||
from: '/supported_hosts',
|
||||
from: '/xo5/supported_hosts',
|
||||
to: '/supported_hosts',
|
||||
},
|
||||
{
|
||||
to: '/xo5/troubleshooting',
|
||||
from: ['/general-troubleshooting', '/troubleshooting']
|
||||
from: ['/general-troubleshooting', '/xo5/troubleshooting'],
|
||||
to: '/troubleshooting',
|
||||
},
|
||||
{
|
||||
to: '/xo5/updater',
|
||||
from: '/updater',
|
||||
from: '/xo5/updater',
|
||||
to: '/updater',
|
||||
},
|
||||
{
|
||||
to: '/xo5/users',
|
||||
@@ -202,8 +239,8 @@ export default {
|
||||
from: '/vm-templates',
|
||||
},
|
||||
{
|
||||
to: '/xo5/xoa',
|
||||
from: '/xoa',
|
||||
to: '/installation',
|
||||
from: ['/xoa', '/xo5/xoa'],
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -226,7 +263,10 @@ export default {
|
||||
siteId: '23',
|
||||
},
|
||||
},
|
||||
clientModules: [require.resolve('./src/clientModules/matomo.ts')],
|
||||
clientModules: [
|
||||
require.resolve('./src/clientModules/matomo.ts'),
|
||||
require.resolve('./src/clientModules/movedAnchors.ts'),
|
||||
],
|
||||
presets: [
|
||||
[
|
||||
'classic',
|
||||
@@ -234,6 +274,9 @@ export default {
|
||||
docs: {
|
||||
routeBasePath: '/',
|
||||
sidebarPath: './sidebars.ts',
|
||||
// "Last updated on…" stamp at the bottom of every page, from
|
||||
// the git history of each file.
|
||||
showLastUpdateTime: true,
|
||||
// Please change this to your repo.
|
||||
// Remove this to remove the "edit this page" links.
|
||||
editUrl: 'https://github.com/vatesfr/xen-orchestra/tree/master/docs',
|
||||
@@ -247,14 +290,38 @@ export default {
|
||||
],
|
||||
|
||||
themeConfig: {
|
||||
// Federated search across docs.xen-orchestra.com, docs.vates.tech
|
||||
// and docs.xcp-ng.org. Results group by product; hits from the two
|
||||
// sibling sites keep their absolute URL (externalUrlRegex).
|
||||
// The API key is search-only and public by design.
|
||||
// Local dev against a local Typesense (prod only allows CORS from
|
||||
// the three doc domains):
|
||||
// TYPESENSE_HOST=localhost TYPESENSE_PORT=8108 \
|
||||
// TYPESENSE_PROTOCOL=http TYPESENSE_SEARCH_KEY=<key> yarn start
|
||||
typesense: {
|
||||
typesenseCollectionName: 'vates_federated',
|
||||
externalUrlRegex: 'docs\\.vates\\.tech|docs\\.xcp-ng\\.org',
|
||||
typesenseServerConfig: {
|
||||
nodes: [
|
||||
{
|
||||
host: process.env.TYPESENSE_HOST ?? 'typesense.vates.tech',
|
||||
port: Number(process.env.TYPESENSE_PORT ?? 443),
|
||||
protocol: process.env.TYPESENSE_PROTOCOL ?? 'https',
|
||||
},
|
||||
],
|
||||
apiKey: process.env.TYPESENSE_SEARCH_KEY ?? 'b2806f42e60429ceecb3808a2c6bb31cc9ca955cb1e4290c',
|
||||
},
|
||||
typesenseSearchParameters: {},
|
||||
contextualSearch: false,
|
||||
},
|
||||
// Replace with your project's social card
|
||||
image: 'img/vates-xo-logo-smol-new-baseline.png',
|
||||
navbar: {
|
||||
title: 'Xen Orchestra Documentation',
|
||||
logo: { alt: 'Xen Orchestra logo', src: 'img/logo.png', href: '/' },
|
||||
items: [
|
||||
{ to: 'https://docs.vates.tech/', label: 'Vates VMS', position: 'right', target: '_self'},
|
||||
{ to: 'https://docs.xcp-ng.org/', label: 'XCP-ng', position: 'right', target: '_self'},
|
||||
{ to: 'https://docs.vates.tech/', label: 'Vates VMS', position: 'right', target: '_self' },
|
||||
{ to: 'https://docs.xcp-ng.org/', label: 'XCP-ng', position: 'right', target: '_self' },
|
||||
{ href: '/', label: 'Xen Orchestra', position: 'right' },
|
||||
],
|
||||
},
|
||||
@@ -274,7 +341,7 @@ export default {
|
||||
},
|
||||
{
|
||||
label: 'Installation',
|
||||
href: '/xo5/installation',
|
||||
href: '/installation',
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -323,10 +390,11 @@ export default {
|
||||
prism: {
|
||||
theme: prismThemes.github,
|
||||
darkTheme: prismThemes.dracula,
|
||||
additionalLanguages: ['toml', 'ini', 'nginx', 'apacheconf'],
|
||||
},
|
||||
} satisfies Preset.ThemeConfig,
|
||||
|
||||
markdown:{
|
||||
markdown: {
|
||||
hooks: {
|
||||
onBrokenMarkdownLinks: 'warn',
|
||||
},
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
"@mdx-js/react": "^3.0.0",
|
||||
"clsx": "^2.0.0",
|
||||
"docusaurus-lunr-search": "^3.5.0",
|
||||
"docusaurus-theme-search-typesense": "^0.26.0",
|
||||
"prism-react-renderer": "^2.3.0",
|
||||
"react": "^18.0.0",
|
||||
"react-dom": "^18.0.0"
|
||||
|
||||
+103
-134
@@ -40,164 +40,128 @@ export default {
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'XO 6',
|
||||
label: 'Getting started',
|
||||
collapsible: true,
|
||||
collapsed: false,
|
||||
items: [
|
||||
{
|
||||
type: 'link',
|
||||
label: "What's new in XO6",
|
||||
href: 'https://xen-orchestra.com/blog/',
|
||||
},
|
||||
/* These categories are hidden until they no longer only contain blank pages
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Getting started',
|
||||
collapsible: true,
|
||||
collapsed: true,
|
||||
items:[
|
||||
'xo6/gettingstarted',
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Core concepts',
|
||||
collapsible: true,
|
||||
collapsed: true,
|
||||
items:[
|
||||
'xo6/coreconcepts',
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Management',
|
||||
collapsible: true,
|
||||
collapsed: true,
|
||||
items:[
|
||||
'xo6/management',
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Backups',
|
||||
collapsible: true,
|
||||
collapsed: true,
|
||||
items:[
|
||||
'xo6/backups',
|
||||
],
|
||||
},
|
||||
*/
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Security',
|
||||
collapsible: true,
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
type: 'category',
|
||||
label: 'User management',
|
||||
collapsible: true,
|
||||
collapsed: true,
|
||||
items: ['xo6/acl-v2'],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'DevOps tools',
|
||||
collapsible: true,
|
||||
collapsed: true,
|
||||
items: [
|
||||
'xo6/ansible',
|
||||
'xo6/kubernetes',
|
||||
'xo6/packer-provider',
|
||||
'xo6/powershell-module',
|
||||
'xo6/pulumi-provider',
|
||||
'xo6/terraform-provider',
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Support',
|
||||
collapsible: true,
|
||||
collapsed: true,
|
||||
items: ['xo6/intro_support', 'xo6/purchase', 'xo6/community'],
|
||||
},
|
||||
'releases',
|
||||
'supported_hosts',
|
||||
'installation',
|
||||
'configuration',
|
||||
'updater',
|
||||
'migrate_to_new_xoa',
|
||||
'architecture',
|
||||
'troubleshooting',
|
||||
'install-from-sources',
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'XO 5',
|
||||
label: 'The interfaces',
|
||||
collapsible: true,
|
||||
collapsed: false,
|
||||
items: ['xo6/whatsnew', 'xo6/xo6vsxo5', 'xo6/gettingstarted', 'xo6/coreconcepts'],
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Managing your infrastructure',
|
||||
collapsible: true,
|
||||
collapsed: true,
|
||||
items: [
|
||||
'xo6/management',
|
||||
'xo5/manage_infrastructure',
|
||||
'xo5/vm-templates',
|
||||
'xo5/advanced',
|
||||
'xo5/load_balancing',
|
||||
'xo5/sdn_controller',
|
||||
'xo5/ipmi-plugin',
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Backups and DR',
|
||||
collapsible: true,
|
||||
collapsed: true,
|
||||
items: [
|
||||
'intro_backup',
|
||||
'backup_howto',
|
||||
'xo6/backups',
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Xen Orchestra',
|
||||
label: 'Backup types',
|
||||
collapsible: true,
|
||||
collapsed: true,
|
||||
items: [
|
||||
'xo5/releases',
|
||||
'xo5/supported_hosts',
|
||||
'xo5/installation',
|
||||
'xo5/configuration',
|
||||
'xo5/credential-encryption',
|
||||
'xo5/migrate_to_new_xoa',
|
||||
'xo5/updater',
|
||||
'xo5/architecture',
|
||||
'xo5/troubleshooting',
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Management',
|
||||
collapsible: true,
|
||||
collapsed: true,
|
||||
items: [
|
||||
'xo5/manage',
|
||||
'xo5/manage_infrastructure',
|
||||
'xo5/object-storage-support',
|
||||
'xo5/v2v-migration-guide',
|
||||
'xo5/users',
|
||||
'xo5/vm-templates',
|
||||
'xo5/advanced',
|
||||
'xo5/load_balancing',
|
||||
'xo5/sdn_controller',
|
||||
'xo5/restapi',
|
||||
'xo5/mcp',
|
||||
'xo5/ipmi-plugin',
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Backups',
|
||||
collapsible: true,
|
||||
collapsed: true,
|
||||
items: [
|
||||
'xo5/intro_backup',
|
||||
'xo5/backups',
|
||||
'xo5/backup_howto',
|
||||
'xo5/proxy',
|
||||
'xo5/rolling_snapshots',
|
||||
'xo5/full_backups',
|
||||
'rolling_snapshots',
|
||||
'full_backups',
|
||||
'xo5/incremental_backups',
|
||||
'xo5/full_replication',
|
||||
'full_replication',
|
||||
'xo5/incremental_replication',
|
||||
'xo5/mirror_backup',
|
||||
'mirror_backup',
|
||||
'xo5/metadata_backup',
|
||||
'xo5/immutability',
|
||||
'xo5/backup_reports',
|
||||
'xo5/backup_troubleshooting',
|
||||
'xo5/calculator',
|
||||
],
|
||||
},
|
||||
'xo5/backups',
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Support',
|
||||
label: 'Scale and security',
|
||||
collapsible: true,
|
||||
collapsed: true,
|
||||
items: ['xo5/xoa', 'xo5/license_management'],
|
||||
items: ['xo5/proxy', 'distributed_backups', 'object-storage-support', 'immutability'],
|
||||
},
|
||||
'xo5/backup_reports',
|
||||
'xo5/backup_troubleshooting',
|
||||
'calculator',
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Users and access',
|
||||
collapsible: true,
|
||||
collapsed: true,
|
||||
items: ['xo5/users', 'rbac', 'credential-encryption'],
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Guides',
|
||||
collapsible: true,
|
||||
collapsed: true,
|
||||
items: ['xo5/v2v-migration-guide', 'windows-templates'],
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Automation',
|
||||
collapsible: true,
|
||||
collapsed: true,
|
||||
items: [
|
||||
'automation/restapi',
|
||||
'automation/mcp',
|
||||
'automation/terraform-provider',
|
||||
'automation/ansible',
|
||||
'automation/pulumi-provider',
|
||||
'automation/packer-provider',
|
||||
'automation/powershell-module',
|
||||
'automation/kubernetes',
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Support and licensing',
|
||||
collapsible: true,
|
||||
collapsed: true,
|
||||
items: [
|
||||
'intro_support',
|
||||
{
|
||||
type: 'link',
|
||||
label: 'Vates VMS bundles',
|
||||
href: 'https://docs.vates.tech/pricing-licencing/vms-bundle-overview/',
|
||||
},
|
||||
{
|
||||
type: 'link',
|
||||
label: 'Applying XO licenses',
|
||||
href: 'https://docs.vates.tech/pricing-licencing/applying-xo-licences/',
|
||||
},
|
||||
'community',
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -207,6 +171,11 @@ export default {
|
||||
collapsed: true,
|
||||
items: [
|
||||
'intro_project',
|
||||
{
|
||||
type: 'link',
|
||||
label: 'Blog',
|
||||
href: 'https://xen-orchestra.com/blog/',
|
||||
},
|
||||
{
|
||||
type: 'link',
|
||||
label: 'Changelog',
|
||||
@@ -217,7 +186,7 @@ export default {
|
||||
{
|
||||
type: 'link',
|
||||
label: 'Roadmap',
|
||||
href: 'https://docs.vates.tech/roadmap/',
|
||||
href: 'https://docs.vates.tech/product-roadmap/',
|
||||
},
|
||||
'glossary',
|
||||
],
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* Old deep links: /xo5/installation#<anchor> used to cover the whole
|
||||
* "from the sources" guide, which now lives on /install-from-sources.
|
||||
* The client-redirects plugin preserves the hash when forwarding
|
||||
* /xo5/installation to /installation; this module completes the trip
|
||||
* for the anchors that moved to the dedicated sources page.
|
||||
*/
|
||||
const MOVED_TO_SOURCES = new Set([
|
||||
'packages-and-prerequisites',
|
||||
'make-sure-redis-is-running',
|
||||
'fetching-the-code',
|
||||
'installing-dependencies',
|
||||
'running-xo',
|
||||
'updating',
|
||||
'always-running',
|
||||
'banner-and-warnings',
|
||||
'troubleshooting',
|
||||
'freebsd',
|
||||
'openbsd',
|
||||
'sudo',
|
||||
])
|
||||
|
||||
/**
|
||||
* The old /xo5/xoa page was split across three pages; its redirect
|
||||
* lands on /installation, and these anchors complete the trip for
|
||||
* the sections that went elsewhere.
|
||||
*/
|
||||
const MOVED_FROM_XOA: Record<string, string> = {
|
||||
firewall: '/configuration#firewall',
|
||||
timezone: '/configuration#timezone',
|
||||
'setting-a-custom-ntp-server': '/configuration#setting-a-custom-ntp-server',
|
||||
'restart-the-service': '/configuration#restart-the-service',
|
||||
'technical-support': '/troubleshooting#still-stuck',
|
||||
'xoa-check': '/troubleshooting#first-reflex-xoa-check',
|
||||
'support-tunnel': '/troubleshooting#support-tunnel',
|
||||
'ssh-pro-support': '/troubleshooting#support-tunnel',
|
||||
'migrate-from-an-older-xoa': '/migrate_to_new_xoa',
|
||||
}
|
||||
|
||||
/**
|
||||
* The old /xo6/purchase and /xo5/license_management pages moved to the
|
||||
* central Vates docs; their redirect lands on /support, and these
|
||||
* anchors complete the trip to the right page over there.
|
||||
*/
|
||||
const MOVED_TO_VATES_DOCS: Record<string, string> = {
|
||||
'direct-purchase': 'https://docs.vates.tech/pricing-licencing/vms-bundle-overview/',
|
||||
'via-your-purchase-departement': 'https://docs.vates.tech/pricing-licencing/contact-quote-requests/',
|
||||
invoices: 'https://docs.vates.tech/pricing-licencing/account-management/',
|
||||
'ask-for-a-quote': 'https://docs.vates.tech/pricing-licencing/contact-quote-requests/',
|
||||
'edit-your-card-information': 'https://docs.vates.tech/pricing-licencing/account-management/',
|
||||
'upgrade-your-plan': 'https://docs.vates.tech/pricing-licencing/vms-bundle-overview/',
|
||||
'activate-a-xen-orchestra-license': 'https://docs.vates.tech/pricing-licencing/applying-xo-licences/',
|
||||
'rebind-xo-license': 'https://docs.vates.tech/pricing-licencing/migrating-licences/',
|
||||
}
|
||||
|
||||
export function onRouteDidUpdate({ location }: { location: { pathname: string; hash: string } }): void {
|
||||
if (typeof window === 'undefined') {
|
||||
return
|
||||
}
|
||||
const path = location.pathname.replace(/\/+$/, '')
|
||||
const anchor = location.hash.replace(/^#/, '')
|
||||
if (path === '/installation' && MOVED_TO_SOURCES.has(anchor)) {
|
||||
window.location.replace(`/install-from-sources#${anchor}`)
|
||||
}
|
||||
if (path === '/installation' && MOVED_FROM_XOA[anchor] !== undefined) {
|
||||
window.location.replace(MOVED_FROM_XOA[anchor])
|
||||
}
|
||||
if (path === '/support' && MOVED_TO_VATES_DOCS[anchor] !== undefined) {
|
||||
window.location.replace(MOVED_TO_VATES_DOCS[anchor])
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import React from 'react'
|
||||
import Link from '@docusaurus/Link'
|
||||
import styles from './styles.module.css'
|
||||
|
||||
/**
|
||||
* Quiet link cards for landing pages, in the spirit of enterprise doc
|
||||
* portals: a title, one descriptive line, no decoration. Use CardGrid as
|
||||
* the container and LinkCard for each entry.
|
||||
*/
|
||||
export function CardGrid({ children }: { children: React.ReactNode }): JSX.Element {
|
||||
return <div className={styles.grid}>{children}</div>
|
||||
}
|
||||
|
||||
export function LinkCard({
|
||||
title,
|
||||
href,
|
||||
children,
|
||||
}: {
|
||||
title: string
|
||||
href: string
|
||||
children?: React.ReactNode
|
||||
}): JSX.Element {
|
||||
return (
|
||||
<Link to={href} className={styles.card}>
|
||||
<span className={styles.title}>{title}</span>
|
||||
{children ? <span className={styles.desc}>{children}</span> : null}
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
.grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
|
||||
gap: 0.9rem;
|
||||
margin: 1.2rem 0 1.8rem;
|
||||
}
|
||||
|
||||
.card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.35rem;
|
||||
padding: 0.95rem 1.05rem;
|
||||
border: 1px solid var(--ifm-color-emphasis-300);
|
||||
border-radius: 10px;
|
||||
color: var(--ifm-font-color-base);
|
||||
text-decoration: none;
|
||||
transition:
|
||||
border-color 0.15s,
|
||||
box-shadow 0.15s;
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
border-color: var(--ifm-color-primary);
|
||||
box-shadow: 0 6px 18px -12px rgba(0, 0, 0, 0.4);
|
||||
color: var(--ifm-font-color-base);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-weight: 600;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.desc {
|
||||
font-size: 0.84rem;
|
||||
line-height: 1.45;
|
||||
color: var(--ifm-color-emphasis-700);
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
import React, { useState } from 'react'
|
||||
import styles from './styles.module.css'
|
||||
|
||||
/**
|
||||
* Host compatibility table with end-of-life versions folded away by
|
||||
* default: readers come for "what should I run", not the graveyard.
|
||||
*/
|
||||
export interface HostRow {
|
||||
version: string
|
||||
status: string
|
||||
notes?: string
|
||||
/** End-of-life platform: hidden until the reader asks for it. */
|
||||
eol?: boolean
|
||||
/** Recommended row, rendered emphasized. */
|
||||
highlight?: boolean
|
||||
}
|
||||
|
||||
export function HostCompatTable({ rows }: { rows: HostRow[] }): JSX.Element {
|
||||
const [showEol, setShowEol] = useState(false)
|
||||
const eolCount = rows.filter(r => r.eol).length
|
||||
const visible = rows.filter(r => showEol || !r.eol)
|
||||
return (
|
||||
<div className={styles.wrap}>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Version</th>
|
||||
<th className={styles.status}>Status</th>
|
||||
<th>Notes</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{visible.map(r => (
|
||||
<tr key={r.version} className={r.eol ? styles.eol : undefined}>
|
||||
<td>{r.highlight ? <strong>{r.version}</strong> : r.version}</td>
|
||||
<td className={styles.status}>{r.status}</td>
|
||||
<td>{r.notes ?? ''}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
{eolCount > 0 ? (
|
||||
<button type='button' className={styles.toggle} onClick={() => setShowEol(v => !v)}>
|
||||
{showEol ? 'Hide end-of-life versions' : `Show ${eolCount} end-of-life version${eolCount > 1 ? 's' : ''} ☠️`}
|
||||
</button>
|
||||
) : null}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default HostCompatTable
|
||||
@@ -0,0 +1,34 @@
|
||||
.wrap {
|
||||
margin: 1rem 0 1.6rem;
|
||||
}
|
||||
|
||||
.wrap table {
|
||||
margin-bottom: 0.4rem;
|
||||
}
|
||||
|
||||
.status {
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* End-of-life rows, once revealed, stay visually quieter. */
|
||||
.eol {
|
||||
opacity: 0.62;
|
||||
}
|
||||
|
||||
.toggle {
|
||||
font-size: 0.82rem;
|
||||
color: var(--ifm-color-emphasis-600);
|
||||
background: transparent;
|
||||
border: 1px solid var(--ifm-color-emphasis-300);
|
||||
border-radius: 6px;
|
||||
padding: 0.25rem 0.7rem;
|
||||
cursor: pointer;
|
||||
transition:
|
||||
color 0.15s,
|
||||
border-color 0.15s;
|
||||
}
|
||||
.toggle:hover {
|
||||
color: var(--ifm-color-emphasis-900);
|
||||
border-color: var(--ifm-color-emphasis-600);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import React from 'react'
|
||||
import Link from '@docusaurus/Link'
|
||||
import styles from './styles.module.css'
|
||||
|
||||
/**
|
||||
* Standard header note for task pages whose screenshots and procedures
|
||||
* are (still) XO 5 based: states what XO 6 covers today and links the
|
||||
* comparison page. One component so the wording and look evolve in one
|
||||
* place as XO 6 grows.
|
||||
*/
|
||||
export default function InterfaceNote({ children }: { children?: React.ReactNode }): JSX.Element {
|
||||
return (
|
||||
<div className={styles.note}>
|
||||
<span className={styles.badge}>XO 5 · XO 6</span>
|
||||
<div className={styles.body}>
|
||||
{children ?? (
|
||||
<>
|
||||
This page describes the XO 5 interface. This area is not available in XO 6 yet: use the{' '}
|
||||
<strong>XO 5</strong> link in the top-right corner of XO 6.
|
||||
</>
|
||||
)}{' '}
|
||||
<Link to='/xo6/xo6vsxo5'>See what lives where</Link>.
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
.note {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 0.7rem;
|
||||
margin: 0 0 1.4rem;
|
||||
padding: 0.65rem 0.9rem;
|
||||
border-left: 4px solid var(--ifm-color-primary);
|
||||
border-radius: 6px;
|
||||
background: var(--ifm-color-emphasis-100);
|
||||
font-size: 0.88rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.badge {
|
||||
flex-shrink: 0;
|
||||
font-family: var(--ifm-font-family-monospace);
|
||||
font-size: 0.68rem;
|
||||
letter-spacing: 0.04em;
|
||||
color: var(--ifm-color-primary);
|
||||
border: 1px solid var(--ifm-color-primary);
|
||||
border-radius: 999px;
|
||||
padding: 0.08rem 0.5rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.body {
|
||||
color: var(--ifm-color-emphasis-800);
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
import React from 'react'
|
||||
import styles from './styles.module.css'
|
||||
|
||||
/**
|
||||
* A framed technical schematic. Renders hand-drawn SVG diagrams on the same
|
||||
* dark board in both themes, matching the <Terminal> component, with a faint
|
||||
* dot grid and an engineering-style caption.
|
||||
*
|
||||
* Wire color convention (keep it consistent across all diagrams):
|
||||
* green #56c288 replication / data safety
|
||||
* gray #7a8699 client traffic / neutral links
|
||||
* amber #e0a94a arbitration / tiebreaker paths
|
||||
* red #ef6a5f failure / fenced elements
|
||||
* Text: #c6d2e1 primary, #7a8699 dim. Boxes: fill rgba(255,255,255,0.04),
|
||||
* stroke rgba(255,255,255,0.28).
|
||||
*/
|
||||
export interface SchemaProps {
|
||||
/** Engineering-drawing caption, e.g. "Fate-shared topology". */
|
||||
label: string
|
||||
/** Optional legend entries, e.g. [["#56c288", "replication"], ...] */
|
||||
legend?: [string, string][]
|
||||
/** Max width of the drawing area, e.g. "520px". */
|
||||
maxWidth?: string
|
||||
/** The inline SVG. */
|
||||
children: React.ReactNode
|
||||
}
|
||||
|
||||
export default function Schema({ label, legend, maxWidth = '760px', children }: SchemaProps): JSX.Element {
|
||||
return (
|
||||
<figure className={styles.board}>
|
||||
<div className={styles.canvas}>
|
||||
<div className={styles.drawing} style={{ maxWidth }}>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
<figcaption className={styles.caption}>
|
||||
<span className={styles.label}>{label}</span>
|
||||
{legend && legend.length > 0 ? (
|
||||
<span className={styles.legend}>
|
||||
{legend.map(([color, text]) => (
|
||||
<span key={text} className={styles.legendItem}>
|
||||
<span className={styles.swatch} style={{ background: color }} />
|
||||
{text}
|
||||
</span>
|
||||
))}
|
||||
</span>
|
||||
) : null}
|
||||
</figcaption>
|
||||
</figure>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,309 @@
|
||||
/* A schematic board: always dark in both themes, like the <Terminal> frame,
|
||||
so consoles and diagrams read as one family of technical panels. */
|
||||
.board {
|
||||
margin: 1.4rem 0;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
background: #0c1119;
|
||||
border: 1px solid rgba(255, 255, 255, 0.09);
|
||||
box-shadow: 0 14px 34px -20px rgba(0, 0, 0, 0.55);
|
||||
}
|
||||
|
||||
/* The board fills the text column; the drawing inside is capped by its
|
||||
maxWidth prop and centered. No breakout: the doc layout has sidebars on
|
||||
both sides, so anything wider than the column collides with them. */
|
||||
|
||||
/* Faint blueprint dot grid behind the drawing. */
|
||||
.canvas {
|
||||
padding: 1.4rem 1.2rem 1.1rem;
|
||||
background-image: radial-gradient(rgba(255, 255, 255, 0.055) 1px, transparent 1px);
|
||||
background-size: 18px 18px;
|
||||
background-position: 9px 9px;
|
||||
}
|
||||
|
||||
.drawing {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.drawing svg {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
font-family: var(--ifm-font-family-monospace);
|
||||
}
|
||||
|
||||
/* Boxes wrapped in <a> are doc links: brighten on hover as affordance.
|
||||
The theme's global a:hover underline would stripe the SVG text - the
|
||||
brightness lift is the only hover cue we want. */
|
||||
.drawing svg a {
|
||||
transition: filter 0.15s ease;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.drawing svg a:hover {
|
||||
filter: brightness(1.35);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* Opt-in wire animation: add className="schema-flow" to a dashed <line>/<g>
|
||||
and the dashes crawl from the stroke's start point toward its end point,
|
||||
suggesting traffic direction. The travel distance must equal one dash
|
||||
period (dash + gap) for a seamless loop: strokeDasharray="5 4" → 9px (CSS
|
||||
px = SVG user units here). For a different pattern, override with
|
||||
style={{'--schema-dash-period': '11px'}}. */
|
||||
.drawing :global(.schema-flow) {
|
||||
animation: dashFlow 1.4s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes dashFlow {
|
||||
from {
|
||||
stroke-dashoffset: 0;
|
||||
}
|
||||
to {
|
||||
stroke-dashoffset: calc(-1 * var(--schema-dash-period, 9px));
|
||||
}
|
||||
}
|
||||
|
||||
/* Opt-in glow: add className="schema-glow" to a shape for a slow breathing
|
||||
halo. Color defaults to the XO blue; override with
|
||||
style={{'--schema-glow-color': '...'}}. Costly: the animated blur
|
||||
re-rasterizes every frame - use on at most one element per page, or
|
||||
prefer an opacity pulse on a pre-blurred shape. */
|
||||
.drawing :global(.schema-glow) {
|
||||
animation: glowPulse 3.2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes glowPulse {
|
||||
0%,
|
||||
100% {
|
||||
filter: drop-shadow(0 0 1px var(--schema-glow-color, rgba(106, 171, 240, 0.25)));
|
||||
}
|
||||
50% {
|
||||
filter: drop-shadow(0 0 6px var(--schema-glow-color, rgba(106, 171, 240, 0.55)));
|
||||
}
|
||||
}
|
||||
|
||||
/* Opt-in migration hop: wrap a VM box (rect + text) in a <g
|
||||
className="schema-hop"> and it periodically slides by --schema-hop-x
|
||||
user units, with a small lift arc, then returns: a live migration
|
||||
between two host slots. Long holds at each end keep it occasional.
|
||||
Tune per element: --schema-hop-x (travel), --schema-hop-dur (cycle
|
||||
length), --schema-hop-delay (stagger several hoppers). */
|
||||
.drawing :global(.schema-hop) {
|
||||
animation: hop var(--schema-hop-dur, 11s) ease-in-out infinite;
|
||||
animation-delay: var(--schema-hop-delay, 0s);
|
||||
}
|
||||
|
||||
@keyframes hop {
|
||||
0%,
|
||||
55% {
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
58.5% {
|
||||
transform: translate(calc(var(--schema-hop-x, 92px) / 2), -7px);
|
||||
}
|
||||
62%,
|
||||
90% {
|
||||
transform: translate(var(--schema-hop-x, 92px), 0);
|
||||
}
|
||||
93.5% {
|
||||
transform: translate(calc(var(--schema-hop-x, 92px) / 2), -7px);
|
||||
}
|
||||
97%,
|
||||
100% {
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Opt-in pop: the element (a pod, a spawning node VM) appears, lives,
|
||||
and is reaped on each cycle. Stagger several with --schema-pop-delay
|
||||
(negative to fast-forward); cycle length via --schema-pop-dur. */
|
||||
.drawing :global(.schema-pop) {
|
||||
animation: podPop var(--schema-pop-dur, 9s) ease-in-out infinite;
|
||||
animation-delay: var(--schema-pop-delay, 0s);
|
||||
opacity: 0;
|
||||
transform-box: fill-box;
|
||||
transform-origin: center;
|
||||
}
|
||||
|
||||
@keyframes podPop {
|
||||
0%,
|
||||
8% {
|
||||
opacity: 0;
|
||||
transform: scale(0.6);
|
||||
}
|
||||
14%,
|
||||
78% {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
86%,
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform: scale(0.6);
|
||||
}
|
||||
}
|
||||
|
||||
/* Same pop, but alive for only ~a third of the cycle: for elements whose
|
||||
short lifetime is the message (ephemeral k8s nodes, spot workloads). */
|
||||
.drawing :global(.schema-pop-quick) {
|
||||
animation: podPopQuick var(--schema-pop-dur, 9s) ease-in-out infinite;
|
||||
animation-delay: var(--schema-pop-delay, 0s);
|
||||
opacity: 0;
|
||||
transform-box: fill-box;
|
||||
transform-origin: center;
|
||||
}
|
||||
|
||||
@keyframes podPopQuick {
|
||||
0%,
|
||||
8% {
|
||||
opacity: 0;
|
||||
transform: scale(0.6);
|
||||
}
|
||||
13%,
|
||||
40% {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
46%,
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform: scale(0.6);
|
||||
}
|
||||
}
|
||||
|
||||
/* Opt-in data chunk: a small block that travels --schema-chunk-y along
|
||||
its wire and fades at both ends. Pair one up and one down (positive
|
||||
and negative travel, staggered delays) for two-way traffic. */
|
||||
.drawing :global(.schema-chunk) {
|
||||
animation: chunkFlow var(--schema-chunk-dur, 2.8s) linear infinite;
|
||||
animation-delay: var(--schema-chunk-delay, 0s);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
@keyframes chunkFlow {
|
||||
0% {
|
||||
transform: translate(0, 0);
|
||||
opacity: 0;
|
||||
}
|
||||
12% {
|
||||
opacity: 1;
|
||||
}
|
||||
88% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
transform: translate(0, var(--schema-chunk-y, -47px));
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Opt-in long-stay parking: the element appears when its delivery lands
|
||||
(align --schema-park-delay with the flight), stays for almost the whole
|
||||
cycle, and fades out just as the next delivery to its slot arrives:
|
||||
"a newer arrival displaces the oldest". */
|
||||
.drawing :global(.schema-park) {
|
||||
animation: parkCycle var(--schema-park-dur, 36s) linear infinite;
|
||||
animation-delay: var(--schema-park-delay, 0s);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
@keyframes parkCycle {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
4%,
|
||||
94% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.drawing :global(.schema-flow),
|
||||
.drawing :global(.schema-glow),
|
||||
.drawing :global(.schema-hop),
|
||||
.drawing :global(.schema-chunk),
|
||||
.drawing :global(.schema-pop),
|
||||
.drawing :global(.schema-pop-quick),
|
||||
.drawing :global(.schema-park) {
|
||||
animation: none;
|
||||
opacity: 1;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
/* Movers and transient wires are SMIL-driven, which CSS can't pause:
|
||||
hide them. */
|
||||
.drawing :global(.schema-packet),
|
||||
.drawing :global(.schema-transient) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* SMIL-faded structural elements (the VMware cluster and its VMs):
|
||||
the CSS property beats the animated attribute, pinning them
|
||||
visible. */
|
||||
.drawing :global(.schema-live) {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* Engineering-drawing title strip. */
|
||||
.caption {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
flex-wrap: wrap;
|
||||
padding: 0.5rem 1rem 0.55rem;
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.09);
|
||||
background: #171b26;
|
||||
}
|
||||
|
||||
/* Book-style caption: a mono "FIG. n" stamp, then the description in
|
||||
sentence-case italic body type. */
|
||||
.label {
|
||||
font-family: var(--ifm-font-family-base);
|
||||
font-size: 0.84rem;
|
||||
font-style: italic;
|
||||
line-height: 1.4;
|
||||
color: #8b96a8;
|
||||
}
|
||||
|
||||
/* Automatic figure numbering, per page. The counter is reset on <article>
|
||||
in src/css/custom.css. */
|
||||
.label::before {
|
||||
counter-increment: schema-fig;
|
||||
/* \2009 is a thin space: a full space gets stretched too wide by the
|
||||
letter-spacing below. */
|
||||
content: 'Fig.\2009' counter(schema-fig) ' ';
|
||||
font-family: var(--ifm-font-family-monospace);
|
||||
font-style: normal;
|
||||
font-size: 0.72rem;
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
color: #c6d2e1;
|
||||
}
|
||||
|
||||
.legend {
|
||||
margin-left: auto;
|
||||
display: flex;
|
||||
gap: 0.9rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.legendItem {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.35rem;
|
||||
font-family: var(--ifm-font-family-monospace);
|
||||
font-size: 0.78rem;
|
||||
color: #7a8699;
|
||||
}
|
||||
|
||||
.swatch {
|
||||
width: 14px;
|
||||
height: 3px;
|
||||
border-radius: 2px;
|
||||
display: inline-block;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user