vagrant-xapi 0.0.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +83 -0
- data/LICENSE +21 -0
- data/README.md +460 -4
- data/docs/architecture.md +1420 -0
- data/docs/operations.md +531 -0
- data/lib/vagrant-xapi/action/base.rb +103 -0
- data/lib/vagrant-xapi/action/cloud_init.rb +130 -0
- data/lib/vagrant-xapi/action/create.rb +127 -0
- data/lib/vagrant-xapi/action/destroy.rb +68 -0
- data/lib/vagrant-xapi/action/network.rb +229 -0
- data/lib/vagrant-xapi/action/package.rb +103 -0
- data/lib/vagrant-xapi/action/power.rb +185 -0
- data/lib/vagrant-xapi/action/snapshots.rb +43 -0
- data/lib/vagrant-xapi/action.rb +317 -0
- data/lib/vagrant-xapi/api/client.rb +393 -0
- data/lib/vagrant-xapi/api/errors.rb +98 -0
- data/lib/vagrant-xapi/api/http_transfer.rb +332 -0
- data/lib/vagrant-xapi/api/redactor.rb +77 -0
- data/lib/vagrant-xapi/api/session_registry.rb +59 -0
- data/lib/vagrant-xapi/api/task.rb +156 -0
- data/lib/vagrant-xapi/api/transport.rb +249 -0
- data/lib/vagrant-xapi/cap.rb +90 -0
- data/lib/vagrant-xapi/command/adopt.rb +92 -0
- data/lib/vagrant-xapi/command/base.rb +79 -0
- data/lib/vagrant-xapi/command/console.rb +87 -0
- data/lib/vagrant-xapi/command/diff.rb +267 -0
- data/lib/vagrant-xapi/command/hosts.rb +63 -0
- data/lib/vagrant-xapi/command/info.rb +94 -0
- data/lib/vagrant-xapi/command/marked.rb +85 -0
- data/lib/vagrant-xapi/command/orphans.rb +96 -0
- data/lib/vagrant-xapi/command/root.rb +55 -0
- data/lib/vagrant-xapi/command/templates.rb +91 -0
- data/lib/vagrant-xapi/config.rb +333 -0
- data/lib/vagrant-xapi/errors.rb +113 -0
- data/lib/vagrant-xapi/extensions.rb +80 -0
- data/lib/vagrant-xapi/glue.rb +330 -0
- data/lib/vagrant-xapi/legacy/plugin.rb +61 -0
- data/lib/vagrant-xapi/legacy/xenapi.rb +129 -0
- data/lib/vagrant-xapi/plugin.rb +58 -0
- data/lib/vagrant-xapi/provider.rb +135 -0
- data/lib/vagrant-xapi/services/adoption.rb +73 -0
- data/lib/vagrant-xapi/services/base.rb +242 -0
- data/lib/vagrant-xapi/services/box_source.rb +218 -0
- data/lib/vagrant-xapi/services/console.rb +115 -0
- data/lib/vagrant-xapi/services/content_diff.rb +96 -0
- data/lib/vagrant-xapi/services/destroyer.rb +104 -0
- data/lib/vagrant-xapi/services/diff_disks.rb +346 -0
- data/lib/vagrant-xapi/services/differ.rb +382 -0
- data/lib/vagrant-xapi/services/disk_image.rb +122 -0
- data/lib/vagrant-xapi/services/disks.rb +281 -0
- data/lib/vagrant-xapi/services/exporter.rb +128 -0
- data/lib/vagrant-xapi/services/file_diff.rb +249 -0
- data/lib/vagrant-xapi/services/guest_files.rb +730 -0
- data/lib/vagrant-xapi/services/hosts.rb +55 -0
- data/lib/vagrant-xapi/services/image_upload.rb +172 -0
- data/lib/vagrant-xapi/services/inventory.rb +225 -0
- data/lib/vagrant-xapi/services/ip_detector.rb +107 -0
- data/lib/vagrant-xapi/services/lock.rb +293 -0
- data/lib/vagrant-xapi/services/lookup.rb +181 -0
- data/lib/vagrant-xapi/services/networks.rb +248 -0
- data/lib/vagrant-xapi/services/power.rb +108 -0
- data/lib/vagrant-xapi/services/rfb.rb +129 -0
- data/lib/vagrant-xapi/services/snapshots.rb +81 -0
- data/lib/vagrant-xapi/services/template_cache.rb +263 -0
- data/lib/vagrant-xapi/services/tunnels.rb +217 -0
- data/lib/vagrant-xapi/services/vm_builder.rb +215 -0
- data/lib/vagrant-xapi/version.rb +7 -0
- data/lib/vagrant-xapi/xenserver/config.rb +69 -0
- data/lib/vagrant-xapi/xenserver/migrate.rb +103 -0
- data/lib/vagrant-xapi/xenserver/plugin.rb +96 -0
- data/lib/vagrant-xapi/xenserver/provider.rb +22 -0
- data/lib/vagrant-xapi/xenserver/takeover.rb +79 -0
- data/lib/vagrant-xapi.rb +21 -2
- data/lib/xenapi.rb +22 -0
- data/locales/en.yml +517 -0
- data/locales/legacy.en.yml +6 -0
- metadata +86 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a2972d8295d44e74480cd9a521aaee0347efe2198c0bbaac979b6ef5dadd54a8
|
|
4
|
+
data.tar.gz: c67899b85bcee85063cac86e678bc53c7fdc73b18efd8fe2228b6e8cd78638dd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7eb3f9724b380016e93ced343b0ef11561ec7d934e8d45db2eaeba2632c8191f7cc083835359500c94e953a7127e786eb7ffc25e75efb86a5e68f56f00299f7e
|
|
7
|
+
data.tar.gz: 7559cf78e3888f431117ce29b0ec503a260e685554c2e29fcba2eda398f94c332dac18021755e6a4f38a45300babd5de977fda8b9aeb8e1a42a0f0b2b040af70
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 1.0.0 (2026-11-09)
|
|
4
|
+
|
|
5
|
+
First version, published on rubygems.org: `vagrant plugin install
|
|
6
|
+
vagrant-xapi`.
|
|
7
|
+
|
|
8
|
+
- XAPI client over JSON-RPC without runtime gems: TLS with CA or SHA-256
|
|
9
|
+
fingerprint pin, redirect to the pool master, one shared session per
|
|
10
|
+
process, long operations as tasks via `event.from`, streaming transfers with
|
|
11
|
+
the session as cookie, secrets filtered from logs and errors. Waiting for
|
|
12
|
+
a task survives a connection loss of up to a minute, and a transfer logs
|
|
13
|
+
in again when the session expired.
|
|
14
|
+
- Box templates imported once per box and SR, under a pool-wide lock; `xapi`,
|
|
15
|
+
`xenserver` and `libvirt` boxes (XVA, `xva_url`, VHD, qcow2, raw).
|
|
16
|
+
- All Vagrant actions: `up`, `halt`, `reload`, `suspend`, `resume`,
|
|
17
|
+
`destroy`, `provision`, `ssh`, `ssh_run`, `package` (XVA, VHD, qcow2) and
|
|
18
|
+
snapshots (including memory, push and pop). On a machine that was never
|
|
19
|
+
created they do not connect to the pool. `package` fails with bsdtar's
|
|
20
|
+
message when compressing the box fails, instead of leaving a truncated box,
|
|
21
|
+
and when the export fails on the host or its download ends early.
|
|
22
|
+
`resume` keeps a machine on an internal network on the host of its peers,
|
|
23
|
+
like `up`.
|
|
24
|
+
- CPUs, memory, BIOS/UEFI, Secure Boot, vTPM, SR choice, fast or full clones,
|
|
25
|
+
affinity host. Turning `vtpm` off, or moving to `:bios`, removes the vTPM
|
|
26
|
+
the plugin created and Secure Boot on the next `reload`.
|
|
27
|
+
- Networks on existing pool networks (by name, UUID or bridge; the default
|
|
28
|
+
network also from `VAGRANT_XAPI_DEFAULT_NETWORK`), internal networks for
|
|
29
|
+
`private_network`, static IPs, IP detection from guest metrics, cloud-init
|
|
30
|
+
or HIMN, SSH via dom0, port forwarding through SSH tunnels. A network that
|
|
31
|
+
does not resolve on `reload` leaves the VM's network interfaces and MACs
|
|
32
|
+
as they were.
|
|
33
|
+
- `config.vm.disk` (extra disks, growing the primary disk, images, ISOs),
|
|
34
|
+
ISOs from ISO SRs through the `isos` option, and `config.vm.cloud_init`
|
|
35
|
+
with `network-config`. CD drives only go in the device slots 0-3 that a
|
|
36
|
+
guest sees; an uploaded ISO without a free slot becomes a read-only disk.
|
|
37
|
+
- Synced folders with rsync, NFS or SMB; rsync is the default unless the
|
|
38
|
+
Vagrantfile sets `config.vm.allowed_synced_folder_types` (Vagrant would
|
|
39
|
+
otherwise pick SMB on macOS and Windows and ask for credentials).
|
|
40
|
+
- `vagrant xapi info`, `console`, `adopt`, `templates`, `orphans`,
|
|
41
|
+
`marked` (everything the plugin created, optionally only your own), and
|
|
42
|
+
`hosts` (the pool's hosts with their certificate fingerprints). `adopt`
|
|
43
|
+
without `--force` only takes VMs of the same Vagrant installation.
|
|
44
|
+
- `vagrant xapi diff`: which files were added, changed or removed since a
|
|
45
|
+
snapshot (`--from`), between two snapshots (`--to`) or between two running
|
|
46
|
+
machines (`--with`), with `--path`, `--exclude`, `--checksum`, `--plain` and
|
|
47
|
+
`--json`, and with `--content` what changed in them (unified diff, up to
|
|
48
|
+
`--content-limit` per file and 16 MiB per side, or the limit when that is
|
|
49
|
+
larger). By default `/tmp`, `/var/tmp`, `/var/cache`, `/var/log`, the
|
|
50
|
+
systemd random seed and `/usr/src` are left out (`--no-default-excludes`
|
|
51
|
+
compares them too); an `--exclude` without a leading `/` matches at any
|
|
52
|
+
depth, and `.` and `..` in a `--path` are resolved. Symlinks are compared
|
|
53
|
+
as links, also when a `--path` goes through one. Of two file systems on one
|
|
54
|
+
mount point only the visible one is compared. The roots of the file systems
|
|
55
|
+
are compared too; a file system that only one side has is named and not
|
|
56
|
+
compared, also a mount point that only one machine of `--with` has; a
|
|
57
|
+
listing that is cut off stops the run. Snapshot disks are read through
|
|
58
|
+
throwaway clones mounted read-only in the guest itself, while a temporary
|
|
59
|
+
udev rule keeps udev and systemd on the guest's own disks; disks left by an
|
|
60
|
+
interrupted run are removed by the next diff, before the VM boots, before
|
|
61
|
+
`package` (which stop when one cannot be removed) and on `destroy`, and its
|
|
62
|
+
mounts and directories in the guest by the next diff (only directories owned
|
|
63
|
+
by root or the SSH user). LVM works: the copy gets identifiers and a VG name
|
|
64
|
+
of its own (`vgimportclone`, limited to the copy's devices, without metadata
|
|
65
|
+
backups), so the guest's own volume groups are never touched.
|
|
66
|
+
- `tls_fingerprint` takes several pins (the certificates of all hosts), so
|
|
67
|
+
any host of the pool can be `host`, also after the master changed.
|
|
68
|
+
- `VAGRANT_XAPI_TLS_FINGERPRINT` and `VAGRANT_XAPI_TLS_CA_FILE` set the TLS
|
|
69
|
+
options from the environment.
|
|
70
|
+
- Vagrantfiles of vagrant-xenserver keep working: the provider `:xenserver`
|
|
71
|
+
with its `xs_*` options, takeover of machines it created, its `destroy`
|
|
72
|
+
that removes all of the VM's own disks, and `vagrant xapi migrate` to move
|
|
73
|
+
machines to `:xapi`.
|
|
74
|
+
- Templates made from a disk image (libvirt, qcow2, raw, VHD boxes) get 1 GiB
|
|
75
|
+
of memory instead of the 256 MiB of "Other install media"; under UEFI GRUB
|
|
76
|
+
could not load the initramfs with that.
|
|
77
|
+
- `vagrant xapi console` asks viewers for a one-time VNC password and puts
|
|
78
|
+
it in the URL it opens, so macOS Screen Sharing connects without asking
|
|
79
|
+
and other local users cannot connect to the forwarded console.
|
|
80
|
+
- Temporary: a stand-in for `XenApi::Client` of the `xenapi` gem, for
|
|
81
|
+
triggers in those Vagrantfiles that `require "xenapi"`. It says so when
|
|
82
|
+
used and will be removed in a later major release. With vagrant-xenserver
|
|
83
|
+
installed too, `require "xenapi"` loads the real gem.
|
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Exonet B.V.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
CHANGED
|
@@ -1,6 +1,462 @@
|
|
|
1
|
-
# vagrant-xapi
|
|
1
|
+
# vagrant-xapi
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
A [Vagrant](https://www.vagrantup.com) provider for **XenServer 8** and **XCP-ng 8.3**.
|
|
4
|
+
It talks to XAPI directly over JSON-RPC and has no runtime gem dependencies.
|
|
5
|
+
It needs no Xen Orchestra.
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
The provider is called `:xapi`. It replaces
|
|
8
|
+
[vagrant-xenserver](https://github.com/xapi-project/vagrant-xenserver) and
|
|
9
|
+
supports every action and provider capability Vagrant core asks for.
|
|
10
|
+
Vagrantfiles written for vagrant-xenserver keep working unchanged (see
|
|
11
|
+
[Migrating from vagrant-xenserver](#migrating-from-vagrant-xenserver)).
|
|
12
|
+
|
|
13
|
+
| Area | What works |
|
|
14
|
+
| --- | --- |
|
|
15
|
+
| Lifecycle | `up`, `halt` (graceful, then clean, then hard), `reload` (re-applies CPU, memory, firmware, VIFs, disks), `suspend`, `resume`, `destroy`, `provision`, `ssh`, `ssh_run` |
|
|
16
|
+
| Boxes | `xapi` boxes (XVA, VHD, qcow2, raw), boxes of vagrant-xenserver (XVA, VHD, `xva_url`), and `libvirt` boxes (qcow2) |
|
|
17
|
+
| VM | `cpus`, `cores_per_socket`, `memory`, `memory_dynamic_min`, BIOS/UEFI, Secure Boot, vTPM, `affinity_host`, tags |
|
|
18
|
+
| Storage | `sr`, `template_sr`, a different SR per disk, fast (copy-on-write) or full clones |
|
|
19
|
+
| Networks | `public_network` and `private_network` on existing networks (name, UUID or bridge), internal networks for `private_network`, static IPs, `forwarded_port` via SSH tunnels, `vagrant port` |
|
|
20
|
+
| Disks | `config.vm.disk`: extra disks, growing the primary disk, disk images, ISOs |
|
|
21
|
+
| cloud-init | `config.vm.cloud_init`, plus a `network-config` for a static IP on the first network |
|
|
22
|
+
| Snapshots | `save`, `restore`, `delete`, `list`, `push`, `pop`, optionally with memory |
|
|
23
|
+
| Package | `vagrant package` as XVA, VHD or qcow2 |
|
|
24
|
+
| Synced folders | rsync (the default), NFS and SMB |
|
|
25
|
+
| Extra | `vagrant xapi info`, `console`, `adopt`, `templates`, `orphans`, `marked`, `hosts`, `diff` |
|
|
26
|
+
|
|
27
|
+
## Requirements
|
|
28
|
+
|
|
29
|
+
- Vagrant 2.4.x (Ruby 3.0 to 3.4, as Vagrant's gemspec requires).
|
|
30
|
+
- XenServer 8 or XCP-ng 8.3. Only the current releases are supported.
|
|
31
|
+
- A box with a guest agent (xe-guest-utilities or xen-guest-agent), **or**
|
|
32
|
+
cloud-init and a static IP on the first network. XAPI has no DHCP of its own.
|
|
33
|
+
- On the machine that runs Vagrant ("local machine" below: a workstation,
|
|
34
|
+
a build server or a CI runner): `ssh`; `qemu-img` only for qcow2 boxes
|
|
35
|
+
that the host cannot import itself (no qcow2 support, or compressed
|
|
36
|
+
clusters, which most cloud images and many libvirt boxes use); `rsync` if
|
|
37
|
+
you use rsync synced folders.
|
|
38
|
+
|
|
39
|
+
## Install
|
|
40
|
+
|
|
41
|
+
From [rubygems.org](https://rubygems.org/gems/vagrant-xapi):
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
vagrant plugin install vagrant-xapi
|
|
45
|
+
vagrant plugin update vagrant-xapi # later, to update
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
From a checkout (the repository is private):
|
|
49
|
+
|
|
50
|
+
```sh
|
|
51
|
+
git clone https://github.com/exonet/vagrant-xapi.git
|
|
52
|
+
cd vagrant-xapi
|
|
53
|
+
gem build vagrant-xapi.gemspec
|
|
54
|
+
vagrant plugin install ./vagrant-xapi-1.0.0.gem
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Quick start
|
|
58
|
+
|
|
59
|
+
Only `host`, `username` and `password` are required. All three can come
|
|
60
|
+
from environment variables, so they never end up in a Vagrantfile in git:
|
|
61
|
+
|
|
62
|
+
```sh
|
|
63
|
+
export VAGRANT_XAPI_HOST=xcp-master.example.com
|
|
64
|
+
export VAGRANT_XAPI_USERNAME=root
|
|
65
|
+
export VAGRANT_XAPI_PASSWORD='...'
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
```ruby
|
|
69
|
+
Vagrant.configure("2") do |config|
|
|
70
|
+
config.vm.box = "acme/debian-12"
|
|
71
|
+
# XenServer and XCP-ng only run amd64 guests. Without this, Vagrant on an
|
|
72
|
+
# Mac with Apple silicon looks for an arm64 box.
|
|
73
|
+
config.vm.box_architecture = "amd64"
|
|
74
|
+
|
|
75
|
+
config.vm.provider :xapi do |xapi|
|
|
76
|
+
xapi.cpus = 2
|
|
77
|
+
xapi.memory = 2048
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
```sh
|
|
83
|
+
vagrant up --provider=xapi
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
The provider is never picked as the default by accident: Vagrant only
|
|
87
|
+
chooses it when the Vagrantfile has a `config.vm.provider :xapi` block or
|
|
88
|
+
you pass `--provider=xapi`.
|
|
89
|
+
|
|
90
|
+
## Provider options
|
|
91
|
+
|
|
92
|
+
| Option | Type | Default | Meaning |
|
|
93
|
+
| --- | --- | --- | --- |
|
|
94
|
+
| `host` | String | `VAGRANT_XAPI_HOST` | Pool master or standalone host. A pool member works too: the plugin follows `HOST_IS_SLAVE` to the master. |
|
|
95
|
+
| `port` | Integer | 443 | HTTPS port |
|
|
96
|
+
| `username` | String | `VAGRANT_XAPI_USERNAME` | XAPI user (root, local or AD with an RBAC role) |
|
|
97
|
+
| `password` | String | `VAGRANT_XAPI_PASSWORD` | Never logged or shown in errors |
|
|
98
|
+
| `tls_verify` | Boolean | true | Cannot be turned off; see TLS below |
|
|
99
|
+
| `tls_ca_file` | String | `VAGRANT_XAPI_TLS_CA_FILE` | Your own CA bundle |
|
|
100
|
+
| `tls_fingerprint` | String, Array | `VAGRANT_XAPI_TLS_FINGERPRINT` | SHA-256 pin of the host certificate, with or without colons; replaces the CA check for self-signed certificates. Several pins (a list, or separated by commas) for the certificates of all hosts of the pool, so any host can be `host`: `vagrant xapi hosts` shows them |
|
|
101
|
+
| `api_timeout` | Integer (s) | 60 | Timeout per API call |
|
|
102
|
+
| `task_timeout` | Integer (s) | 3600 | Timeout for imports, exports and copies |
|
|
103
|
+
| `name_label` | String | `<project dir>_<machine>` | VM name in XAPI |
|
|
104
|
+
| `cpus` | Integer | from template | `VCPUs_max` and `VCPUs_at_startup` |
|
|
105
|
+
| `cores_per_socket` | Integer | from template | Must divide `cpus` (or, without `cpus`, the template's vCPUs) |
|
|
106
|
+
| `memory` | Integer (MiB) | from template | Static and dynamic maximum. Templates the plugin makes from a disk image (libvirt, qcow2, raw, VHD) have 1024, instead of the 256 of XAPI's "Other install media" |
|
|
107
|
+
| `memory_dynamic_min` | Integer (MiB) | `memory` | Lower bound for ballooning |
|
|
108
|
+
| `firmware` | `:bios`, `:uefi` | from template | |
|
|
109
|
+
| `secure_boot` | Boolean | false | Only with `:uefi`; with `:bios` it is turned off |
|
|
110
|
+
| `vtpm` | Boolean | false | Only with `:uefi`, and when the pool supports vTPM. Turned off, `vagrant reload` removes the vTPM the plugin created, with its contents; a vTPM that came with the box or an adopted VM stays |
|
|
111
|
+
| `sr` | String | pool default SR | Name or UUID; target for VM disks |
|
|
112
|
+
| `template_sr` | String | `sr` | SR that holds the box template |
|
|
113
|
+
| `clone_mode` | `:fast`, `:full` | `:fast` | `VM.clone` (copy-on-write, same SR as the template) or `VM.copy` (full copy to `sr`) |
|
|
114
|
+
| `affinity_host` | String | nil | Name or UUID of the preferred host |
|
|
115
|
+
| `default_network` | String | `VAGRANT_XAPI_DEFAULT_NETWORK`, else the master's management network | Network (name, UUID or bridge) of the first VIF when the Vagrantfile names no `public_network` |
|
|
116
|
+
| `ip_detection` | Array | `[:guest_metrics, :static, :himn]` | Order of IP sources, see below |
|
|
117
|
+
| `ssh_via_host` | Boolean | false | SSH to the guest through dom0 (ProxyCommand) |
|
|
118
|
+
| `host_ssh_user` | String | `root` | dom0 user for `ssh_via_host` and `:himn` |
|
|
119
|
+
| `shutdown_timeout` | Integer (s) | 120 | After this, `hard_shutdown` |
|
|
120
|
+
| `xva_url` | String | nil | Let the host download the XVA itself (usually in a box's Vagrantfile) |
|
|
121
|
+
| `isos` | Array | `[]` | ISOs on an ISO SR (name or UUID) to attach as CD drives |
|
|
122
|
+
| `tags` | Array | `[]` | Extra XAPI tags |
|
|
123
|
+
| `platform` | Hash | `{}` | Extra `platform` keys, as an escape hatch |
|
|
124
|
+
| `other_config` | Hash | `{}` | Extra `other_config` keys; `vagrant-xapi.*` is reserved |
|
|
125
|
+
| `forward_ssh_port` | Boolean | false | Also tunnel Vagrant's default 2222 → 22 forward |
|
|
126
|
+
| `snapshot_memory` | Boolean | false | `snapshot save` of a running VM includes memory (checkpoint) |
|
|
127
|
+
| `package_format` | `:xva`, `:vhd`, `:qcow2` | `:xva` | Format of `vagrant package` |
|
|
128
|
+
|
|
129
|
+
Validation runs without a connection. Names of SRs, networks and hosts are
|
|
130
|
+
looked up at `vagrant up`.
|
|
131
|
+
|
|
132
|
+
## Boxes
|
|
133
|
+
|
|
134
|
+
The provider accepts three kinds of boxes and imports each box **once per
|
|
135
|
+
SR** as an XAPI template named `vagrant-xapi: <box> <version>`. Every VM is a
|
|
136
|
+
clone (or copy) of that template. Templates are shared by all users of a
|
|
137
|
+
pool; an import runs under a pool-wide lock, so two people running
|
|
138
|
+
`vagrant up` with the same new box get one template.
|
|
139
|
+
|
|
140
|
+
| Box provider | Content |
|
|
141
|
+
| --- | --- |
|
|
142
|
+
| `xapi` | `metadata.json` with `provider`, `format` (`xva`, `vhd`, `qcow2` or `raw`) and `architecture: "amd64"`; one file `box.<format>`; optionally a Vagrantfile with provider defaults such as `firmware` |
|
|
143
|
+
| `xenserver` | A box of vagrant-xenserver: `box.xva`, `box.vhd`, or only a Vagrantfile with `xva_url` |
|
|
144
|
+
| `libvirt` | `box.img` (qcow2), or several disks in the newer libvirt format |
|
|
145
|
+
|
|
146
|
+
qcow2 is imported directly when the host supports it and the image has no
|
|
147
|
+
compressed clusters (XAPI's qcow2 import cannot read those); otherwise the
|
|
148
|
+
plugin converts it with `qemu-img convert -f qcow2 -O vpc` on the local
|
|
149
|
+
machine. Files a box names must lie inside the box, and qcow2 images with a backing file are refused.
|
|
150
|
+
|
|
151
|
+
A minimal `xapi` box:
|
|
152
|
+
|
|
153
|
+
```sh
|
|
154
|
+
echo '{"provider":"xapi","format":"xva","architecture":"amd64"}' > metadata.json
|
|
155
|
+
cp my-vm.xva box.xva
|
|
156
|
+
tar czf my.box metadata.json box.xva
|
|
157
|
+
vagrant box add --architecture amd64 --name my/box my.box
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
`vagrant package` makes such a box from a VM: the VM is halted, a temporary
|
|
161
|
+
clone is stripped of everything that belongs to this pool (VIFs, our
|
|
162
|
+
markings, ISOs), exported, and removed again. Cleaning the guest for
|
|
163
|
+
publication (SSH host keys, machine-id) is up to you, as with other providers.
|
|
164
|
+
|
|
165
|
+
## Networks
|
|
166
|
+
|
|
167
|
+
XAPI has no NAT and no DHCP. Every VIF hangs on a real network of the pool,
|
|
168
|
+
the IP comes from the guest, and port forwarding runs over SSH tunnels.
|
|
169
|
+
|
|
170
|
+
- The first `public_network` becomes VIF device 0. Without one, device 0 is a
|
|
171
|
+
VIF on `default_network` (or `VAGRANT_XAPI_DEFAULT_NETWORK`). Then the
|
|
172
|
+
other networks follow in Vagrantfile order. `reload` rebuilds the VIFs (MAC
|
|
173
|
+
addresses are kept per device).
|
|
174
|
+
- `public_network` / `private_network` with `network:` (name, UUID or bridge)
|
|
175
|
+
or `bridge:` (e.g. `xenbr0`) use an existing network. Options: `mac:`, `mtu:`,
|
|
176
|
+
`ip:` (IPv4 or IPv6) with `netmask:` and `gateway:` for a static address,
|
|
177
|
+
`nameservers:` (for the first network), `xapi__locking_mode:`.
|
|
178
|
+
- `private_network` without `network:` becomes an **internal network** (no
|
|
179
|
+
PIF), created when missing, marked with the project, and removed with the
|
|
180
|
+
last VM that uses it. `ip:` is required. An internal network only exists
|
|
181
|
+
per host, so all VMs of a project on it run on the same host (the host of
|
|
182
|
+
a VM that already runs on it). A name that belongs to another project is
|
|
183
|
+
refused.
|
|
184
|
+
- Static addresses on device 0 are set through cloud-init (`network-config`
|
|
185
|
+
in the config drive); others through Vagrant's `configure_networks` guest
|
|
186
|
+
capability after boot.
|
|
187
|
+
|
|
188
|
+
### IP detection
|
|
189
|
+
|
|
190
|
+
`ip_detection` sets the order of sources; waiting stops after
|
|
191
|
+
`config.vm.boot_timeout`.
|
|
192
|
+
|
|
193
|
+
1. `:guest_metrics`: `<device>/ipv4/0` of VIF 0 from the guest agent.
|
|
194
|
+
2. `:static`: the `ip:` of the first network.
|
|
195
|
+
3. `:himn`: an extra VIF on the host internal management network. Only
|
|
196
|
+
reachable from dom0, so only together with `ssh_via_host = true`.
|
|
197
|
+
|
|
198
|
+
### SSH and port forwarding
|
|
199
|
+
|
|
200
|
+
SSH goes straight to the guest IP. With `ssh_via_host = true` it goes through
|
|
201
|
+
dom0 as a ProxyCommand (`ssh -W %h:%p`) with normal host key checking: add
|
|
202
|
+
the host's key to your `known_hosts` first.
|
|
203
|
+
|
|
204
|
+
Each `forwarded_port` starts a background `ssh -N -L` through the guest. The
|
|
205
|
+
default `22 → 2222` forward is skipped unless `forward_ssh_port = true`. Host
|
|
206
|
+
ports below 1024 and UDP are refused. Tunnels bind to `127.0.0.1` unless you
|
|
207
|
+
set `host_ip:`.
|
|
208
|
+
|
|
209
|
+
## Disks and cloud-init
|
|
210
|
+
|
|
211
|
+
```ruby
|
|
212
|
+
config.vm.disk :disk, primary: true, size: "40GB" # grow (never shrink)
|
|
213
|
+
config.vm.disk :disk, name: "data", size: "100GB", xapi__sr: "fast-ssd"
|
|
214
|
+
config.vm.disk :disk, name: "seed", file: "./seed.qcow2" # import an image
|
|
215
|
+
config.vm.disk :dvd, name: "tools", file: "./tools.iso" # upload an ISO
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
ISOs that already live on an ISO SR are not a `config.vm.disk` (Vagrant
|
|
219
|
+
requires a local file for every `:dvd`), but a provider option:
|
|
220
|
+
|
|
221
|
+
```ruby
|
|
222
|
+
config.vm.provider :xapi do |xapi|
|
|
223
|
+
xapi.isos = ["debian-12.iso"]
|
|
224
|
+
end
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
Disks are only resized while the VM is halted; the filesystem in the guest
|
|
228
|
+
does not grow by itself (cloud-init `growpart` usually takes care of it).
|
|
229
|
+
|
|
230
|
+
A guest only sees CD drives in the device slots 0-3. Slot 0 is the boot
|
|
231
|
+
disk, extra disks take the first free slots, and many boxes have an empty CD
|
|
232
|
+
drive of their own (usually slot 3); `vagrant xapi info` shows the slots. An
|
|
233
|
+
uploaded ISO that finds no free slot is attached as a read-only disk instead,
|
|
234
|
+
with a warning; in the guest it is a disk such as `/dev/xvde` that mounts
|
|
235
|
+
like the CD would. An ISO from `isos` gives an error.
|
|
236
|
+
Disks larger than 2 TiB give a warning, because VHD-based SRs cannot hold them.
|
|
237
|
+
|
|
238
|
+
`config.vm.cloud_init` works as in other providers: the plugin builds the
|
|
239
|
+
NoCloud ISO (volume `cidata`), uploads it and attaches it. When its content
|
|
240
|
+
changes, it is replaced.
|
|
241
|
+
|
|
242
|
+
## Snapshots
|
|
243
|
+
|
|
244
|
+
All `vagrant snapshot` subcommands work. `snapshot_memory = true` makes
|
|
245
|
+
`save` of a running VM a checkpoint including memory; restoring a checkpoint
|
|
246
|
+
resumes the VM.
|
|
247
|
+
|
|
248
|
+
## Comparing files
|
|
249
|
+
|
|
250
|
+
`vagrant xapi diff` lists the files that changed since a snapshot:
|
|
251
|
+
|
|
252
|
+
```sh
|
|
253
|
+
vagrant snapshot save before
|
|
254
|
+
vagrant provision
|
|
255
|
+
vagrant xapi diff --from before
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
```
|
|
259
|
+
A /etc/nginx/sites-enabled/app
|
|
260
|
+
M /etc/hosts (content)
|
|
261
|
+
m /etc/sudoers.d/app (mode 0440 -> 0640)
|
|
262
|
+
T /opt/app (directory -> symlink)
|
|
263
|
+
D /var/www/html/index.nginx-debian.html
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
`A` added, `D` removed, `M` other content, `m` other mode or owner only,
|
|
267
|
+
`T` another type (device nodes are compared by type, mode and owner, not by
|
|
268
|
+
their device numbers). `--to SNAPSHOT` compares two snapshots, `--with MACHINE`
|
|
269
|
+
two running machines of the Vagrantfile. `--path /etc` limits the
|
|
270
|
+
comparison (symlinks are compared as links, also in a `--path`: nothing
|
|
271
|
+
below a symlink matches), `--exclude '*.log'` leaves paths out (a pattern
|
|
272
|
+
without a leading `/` matches at any depth, so `--exclude node_modules`
|
|
273
|
+
leaves out every `node_modules`; by default `/tmp`, `/var/tmp`, `/var/cache`,
|
|
274
|
+
`/var/log`, the systemd random seed and `/usr/src` are left out, and
|
|
275
|
+
`--no-default-excludes` compares them too), `--checksum` compares the content
|
|
276
|
+
of every file instead of trusting size and modification time, and `--plain`
|
|
277
|
+
or `--json` are for scripts.
|
|
278
|
+
|
|
279
|
+
`--content` also shows what changed in each file, as a unified diff after
|
|
280
|
+
the list:
|
|
281
|
+
|
|
282
|
+
```sh
|
|
283
|
+
vagrant xapi diff --from before --content --path /etc
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
```
|
|
287
|
+
--- a/etc/hosts
|
|
288
|
+
+++ b/etc/hosts
|
|
289
|
+
@@ -1 +1,2 @@
|
|
290
|
+
127.0.0.1 localhost
|
|
291
|
+
+10.0.0.5 db
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
Added and removed files show their whole content. Binary files and files
|
|
295
|
+
larger than `--content-limit` (default `1M`) are named but not shown, also
|
|
296
|
+
when a file grew past it while the diff ran. Each side copies at most
|
|
297
|
+
16 MiB in all, or `--content-limit` when that is larger; after a large
|
|
298
|
+
upgrade the files beyond that are named too. The content appears in your
|
|
299
|
+
terminal, also of files
|
|
300
|
+
such as `/etc/shadow` when they changed; narrow it with `--path`. It needs
|
|
301
|
+
`diff` on the local machine.
|
|
302
|
+
With `--json` each change gets a `diff` field, or `diff_skipped` with the
|
|
303
|
+
reason; `--plain` does not take `--content`.
|
|
304
|
+
|
|
305
|
+
The machine must be running: the plugin attaches throwaway copies of the
|
|
306
|
+
snapshot's disks to the VM, mounts them read-only in the guest, compares
|
|
307
|
+
there and removes the copies again. It needs a Linux guest with GNU
|
|
308
|
+
findutils, coreutils and util-linux, a guest agent (XAPI only attaches disks
|
|
309
|
+
to a running VM with PV drivers), and ext4, XFS or vfat file systems, also on
|
|
310
|
+
LVM (with lvm2 in the guest: the copy gets LVM identifiers of its own, the
|
|
311
|
+
guest's own volume groups are not touched). Guests with LUKS, btrfs, ZFS or
|
|
312
|
+
RAID are refused; compare two machines with `--with` instead.
|
|
313
|
+
|
|
314
|
+
## `vagrant xapi`
|
|
315
|
+
|
|
316
|
+
| Command | Purpose |
|
|
317
|
+
| --- | --- |
|
|
318
|
+
| `vagrant xapi info [vm]` | UUID, host, SR, template, VIFs with IPs, snapshots |
|
|
319
|
+
| `vagrant xapi console [vm]` | VNC console through the XAPI console tunnel on a local port, with a one-time VNC password; opens the viewer (`open vnc://` on macOS with the password in the URL, so Screen Sharing connects without asking; `xdg-open` on Linux, where the viewer asks for the password the terminal shows) |
|
|
320
|
+
| `vagrant xapi adopt [vm] UUID` | Attach an existing VM to this machine (or re-adopt its own VM after moving the project); a VM without vagrant-xapi marking, or one that belongs to someone else, needs `--force` |
|
|
321
|
+
| `vagrant xapi templates list` | Templates with box, version, SR, size and number of clones |
|
|
322
|
+
| `vagrant xapi templates prune [--keep N]` | Keep only the newest N versions per box (default 1) |
|
|
323
|
+
| `vagrant xapi templates remove NAME\|UUID` | Remove one template |
|
|
324
|
+
| `vagrant xapi orphans [--destroy]` | VMs of this Vagrant installation whose Vagrant machine no longer exists |
|
|
325
|
+
| `vagrant xapi migrate` | Moves this project's machines of a vagrant-xenserver Vagrantfile from `:xenserver` to `:xapi`, after the Vagrantfile was changed (see Migrating) |
|
|
326
|
+
| `vagrant xapi hosts [--plain\|--json\|--pem]` | The pool's hosts with address, role and the SHA-256 fingerprint of their TLS certificate, as the master reports them; `--pem` prints the certificates, e.g. for `tls_ca_file` |
|
|
327
|
+
| `vagrant xapi diff [vm] --from SNAPSHOT [--to SNAPSHOT]` or `--with MACHINE` | Files that differ between a snapshot and the running machine, two snapshots, or two running machines (see above) |
|
|
328
|
+
| `vagrant xapi marked [--mine] [--project DIR] [--vm UUID] [--box NAME]` | Everything in the pool that vagrant-xapi created (all users); `--mine` for only your own VMs with their snapshots, disks and networks, or narrow it to a project, VM or box; `--plain` or `--json` for scripts |
|
|
329
|
+
|
|
330
|
+
Everything that deletes asks for confirmation unless `--force` is given.
|
|
331
|
+
`prune` and `remove` first show which other users still have clones.
|
|
332
|
+
Removing a template is safe while clones exist: the storage layer keeps the
|
|
333
|
+
shared base disk.
|
|
334
|
+
|
|
335
|
+
## Security
|
|
336
|
+
|
|
337
|
+
- **TLS** is always verified. For a self-signed certificate set
|
|
338
|
+
`tls_fingerprint` (SHA-256 of the host certificate) or `tls_ca_file`. There
|
|
339
|
+
is no "insecure" option. Get the fingerprint with:
|
|
340
|
+
|
|
341
|
+
```sh
|
|
342
|
+
openssl s_client -connect xcp-master:443 </dev/null 2>/dev/null \
|
|
343
|
+
| openssl x509 -noout -fingerprint -sha256
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
Each pool member has its own certificate. Pin the **master** and use it as
|
|
347
|
+
`host`; with a pin on a member the plugin stops and names the master.
|
|
348
|
+
Transfers and consoles that run on another pool member use the
|
|
349
|
+
certificate the master reports for that member.
|
|
350
|
+
- **Secrets**: the password and the session id never appear in logs
|
|
351
|
+
(also not with `VAGRANT_LOG=debug`), error messages, URLs or process
|
|
352
|
+
arguments. Uploads and downloads stream in Ruby with the session as a
|
|
353
|
+
cookie; there is no `curl`.
|
|
354
|
+
- **Subprocesses** (`ssh` for tunnels, `qemu-img`) always run with an argv
|
|
355
|
+
array, never through a shell.
|
|
356
|
+
- **Cleanup** only touches objects carrying the plugin's marking: the tag
|
|
357
|
+
`vagrant` and `other_config` keys `vagrant-xapi.*` (machine, project, user,
|
|
358
|
+
local hostname, installation id, version). `destroy` removes the VM, its snapshots, its own disks and
|
|
359
|
+
its cloud-init ISO; never a template's disks.
|
|
360
|
+
- **Downloads**: an `http://` `xva_url` gives a warning, because the host
|
|
361
|
+
then downloads the image unencrypted.
|
|
362
|
+
- **Supply chain**: no runtime gems.
|
|
363
|
+
|
|
364
|
+
### Which XAPI role is needed?
|
|
365
|
+
|
|
366
|
+
The plugin creates and destroys VMs, VDIs, VBDs and VIFs, uses
|
|
367
|
+
`pool.other_config` for its locks, and creates internal networks for
|
|
368
|
+
`private_network`. With `pool-admin` everything works.
|
|
369
|
+
|
|
370
|
+
`vm-admin` covers the VM lifecycle, but may not be allowed to write the
|
|
371
|
+
pool's `other_config` or to create networks. In that case the plugin stops
|
|
372
|
+
with a readable message (`lock_permission_denied`).
|
|
373
|
+
|
|
374
|
+
## Migrating from vagrant-xenserver
|
|
375
|
+
|
|
376
|
+
Vagrantfiles written for vagrant-xenserver keep working unchanged:
|
|
377
|
+
|
|
378
|
+
```sh
|
|
379
|
+
vagrant plugin uninstall vagrant-xenserver # both cannot be installed
|
|
380
|
+
# install vagrant-xapi as described under Install
|
|
381
|
+
export VAGRANT_XAPI_TLS_FINGERPRINT=AB:CD:...,12:34:... # once; see below
|
|
382
|
+
vagrant up
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
- `config.vm.provider "xenserver"` with `xs.xs_host`, `xs.name` and the
|
|
386
|
+
other `xs_*` options works, and so do boxes of vagrant-xenserver. Every run
|
|
387
|
+
says once that the compatibility with vagrant-xenserver is in use.
|
|
388
|
+
- Existing machines are taken over: vagrant-xapi finds their VMs by the
|
|
389
|
+
reference vagrant-xenserver stored, marks them and their own disks, and
|
|
390
|
+
carries on with them. No second VM is created.
|
|
391
|
+
- `vagrant destroy` removes all disks of the VM that no other VM uses, as
|
|
392
|
+
vagrant-xenserver did, including disks that triggers attached.
|
|
393
|
+
- The one new setting is TLS. vagrant-xenserver sent its API calls, the
|
|
394
|
+
login included, over plain HTTP on port 80 (also with `xs_use_ssl = true`);
|
|
395
|
+
vagrant-xapi always uses HTTPS and checks the certificate. Set
|
|
396
|
+
`VAGRANT_XAPI_TLS_FINGERPRINT` to the fingerprints of all hosts of the
|
|
397
|
+
pool, separated by commas, or `VAGRANT_XAPI_TLS_CA_FILE`, unless your
|
|
398
|
+
machine already trusts the pool's certificates. Once connected to the
|
|
399
|
+
master with one pin, `vagrant xapi hosts` shows the fingerprints of all
|
|
400
|
+
hosts.
|
|
401
|
+
|
|
402
|
+
**Triggers that call XAPI themselves** (`require "xenapi"` and
|
|
403
|
+
`XenApi::Client`, e.g. to add extra disks or set vCPUs) keep working in 1.x,
|
|
404
|
+
through a stand-in for that gem. The stand-in is **temporary** and says so
|
|
405
|
+
when a trigger uses it. Replace such triggers with the provider's own
|
|
406
|
+
options, which `xs` has as well: `xs.cpus` for vCPUs and `config.vm.disk`
|
|
407
|
+
for extra disks. The plugin chooses the disk slots itself, so check device
|
|
408
|
+
names such as `/dev/xvdi` that other tools rely on.
|
|
409
|
+
|
|
410
|
+
`:xapi` is the provider for new Vagrantfiles. To move a project to it,
|
|
411
|
+
change the provider block with the table below and run `vagrant xapi
|
|
412
|
+
migrate`: it moves the machines from `.vagrant/machines/<name>/xenserver` to
|
|
413
|
+
`xapi`, without which Vagrant would create new VMs.
|
|
414
|
+
|
|
415
|
+
| vagrant-xenserver | vagrant-xapi |
|
|
416
|
+
| --- | --- |
|
|
417
|
+
| `config.vm.provider :xenserver do \|xs\|` | `config.vm.provider :xapi do \|xapi\|` |
|
|
418
|
+
| `xs.xs_host` | `xapi.host` (or `VAGRANT_XAPI_HOST`) |
|
|
419
|
+
| `xs.xs_username` | `xapi.username` |
|
|
420
|
+
| `xs.xs_password` | `xapi.password` |
|
|
421
|
+
| `xs.xs_port` / `xs.xs_use_ssl` | `xapi.port`; always HTTPS (port 443) |
|
|
422
|
+
| `xs.name` | `xapi.name_label` |
|
|
423
|
+
| `xs.memory` | `xapi.memory` |
|
|
424
|
+
| `xs.api_timeout` | `xapi.api_timeout` |
|
|
425
|
+
| `xs.pv = true` | not supported; HVM only (PV boxes are switched to HVM) |
|
|
426
|
+
| `xs.use_himn = true` | `xapi.ip_detection = [:himn]` plus `xapi.ssh_via_host = true` |
|
|
427
|
+
| `xs.xva_url` | `xapi.xva_url` |
|
|
428
|
+
| `config.vm.network :public_network, bridge: "xenbr0"` | the same |
|
|
429
|
+
| Bridges from your own variables, e.g. `bridge: ENV["VAGRANT_XS_BRIDGE_EXTERNAL"]` | The same works; or set `VAGRANT_XAPI_DEFAULT_NETWORK=xenbr1` and leave the external `public_network` out |
|
|
430
|
+
|
|
431
|
+
New compared to vagrant-xenserver: CPUs, UEFI and vTPM, choice of SR,
|
|
432
|
+
private networks, port forwarding, disks, cloud-init, snapshots, package,
|
|
433
|
+
proper TLS, and the `vagrant xapi` commands.
|
|
434
|
+
|
|
435
|
+
## Development
|
|
436
|
+
|
|
437
|
+
```sh
|
|
438
|
+
bundle install
|
|
439
|
+
bundle exec rake # unit tests (rspec, against a fake XAPI)
|
|
440
|
+
bundle exec vagrant ... # run Vagrant with the plugin from this checkout
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
The unit tests run the real Vagrant action stacks against an in-memory XAPI
|
|
444
|
+
(`spec/support/fake_xapi.rb`). Acceptance tests against a real pool are in
|
|
445
|
+
`test/acceptance`; see the README there.
|
|
446
|
+
|
|
447
|
+
## Documentation
|
|
448
|
+
|
|
449
|
+
- [docs/architecture.md](docs/architecture.md): scope, design, how every
|
|
450
|
+
action and feature maps to XAPI, security, tests and decisions.
|
|
451
|
+
- [docs/operations.md](docs/operations.md): connecting, RBAC, boxes,
|
|
452
|
+
templates, finding and cleaning up objects, locks, troubleshooting,
|
|
453
|
+
development and releasing.
|
|
454
|
+
- [test/acceptance/README.md](test/acceptance/README.md): acceptance tests
|
|
455
|
+
against a real pool.
|
|
456
|
+
|
|
457
|
+
Both files under `docs/` are also in the gem, in
|
|
458
|
+
`~/.vagrant.d/gems/<ruby version>/gems/vagrant-xapi-<version>/docs/`.
|
|
459
|
+
|
|
460
|
+
## License
|
|
461
|
+
|
|
462
|
+
MIT, like vagrant-xenserver and Vagrant itself.
|