summaryrefslogtreecommitdiff
path: root/tests/pve/README.md
blob: f780475c88bed3cd2812e7b4c77cc368ed26c028 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# PVE end-to-end harness

This directory holds a small, opinionated harness to run pyvyos
against a real VyOS VM on a local Proxmox VE host.

It is intentionally **not** part of CI. The unit test suite under
`tests/modules/` is fast, mock-based, and runs on every PR. The
harness here exists for maintainers who want a periodic reality
check — the gap a mock cannot close.

> This harness creates confidence against real VyOS without turning
> the project into a CI of appliances.

## What it gives you

A reproducible flow:

```text
ensure-template.sh   # build a reusable VyOS template once
create-vm.sh         # clone the template into a fresh e2e VM
start-vm.sh          # power it on
run-e2e.sh           # run pytest tests/e2e against it
stop-vm.sh           # power it off
destroy-vm.sh        # purge it
```

The template carries an API key baked at build time via cloud-init.
Clones inherit it, so the e2e VM is reachable as soon as the API is
up.

## Requirements

- a Proxmox VE host you can `ssh` to (preferably via an alias in
  `~/.ssh/config`)
- a VyOS rolling install ISO already on the PVE host, under
  `/var/lib/vz/template/iso/` (download from
  https://github.com/vyos/vyos-nightly-build/releases; this harness
  does **not** download it for you)
- `genisoimage` (or `mkisofs`) installed on the PVE host —
  `apt install genisoimage` once
- Python 3.11+ and `uv` (or `pytest`) on your workstation to run the
  test suite itself

## First-time setup

```bash
cp tests/pve/.env.example tests/pve/.env
$EDITOR tests/pve/.env       # fill in your host, VMIDs, IP, API key
chmod +x tests/pve/*.sh

tests/pve/preflight.sh       # read-only sanity check
tests/pve/ensure-template.sh # phase 1: creates VM with installer
```

The first run of `ensure-template.sh` boots a VM with the VyOS
installer ISO attached and prints instructions:

```text
on the PVE host:
  qm terminal <VMID>           # Ctrl-] exits

inside VyOS:
  login: vyos / vyos
  install image                # accept defaults, set a password
  poweroff
```

Do that once. Then run it again:

```bash
tests/pve/ensure-template.sh  # phase 2: cloud-init applies API key,
                              #          shuts down, flips template flag
```

The script is a state machine on the VMID, so re-running it from any
point is safe.

### Alternative: prebuilt images with packer-vyos

If you would rather skip the interactive install entirely, you can
build a ready-to-clone VyOS image with
[`vyos-contrib/packer-vyos`](https://github.com/vyos-contrib/packer-vyos)
and import it on the PVE host instead of running phase 1 here. The
harness scripts still work — you just point `VYOS_TEMPLATE_VMID` at
the imported image. This harness keeps the install path because it
has no extra dependencies; `packer-vyos` is a more capable option if
you want repeatable image builds.

## Per-run workflow

```bash
tests/pve/create-vm.sh
tests/pve/start-vm.sh
tests/pve/run-e2e.sh
tests/pve/stop-vm.sh
tests/pve/destroy-vm.sh
```

`run-e2e.sh` exports the `VYDEVICE_*` variables from `.env` and runs
`pytest tests/e2e -v` with `PYVYOS_E2E=1`. Without that variable the
e2e tests are skipped automatically.

## Scope

The live suite is intentionally small:

| Test                                 | What it proves                |
| ------------------------------------ | ----------------------------- |
| `test_show_system_image`             | operational API responds      |
| `test_retrieve_show_config_system`   | config retrieval works        |
| `test_configure_set_read_delete...`  | set / read-back / delete loop |
| `test_configure_multiple_op_batch`   | the batch payload is correct  |

Out of scope on purpose: `reboot`, `poweroff`, `image_add`,
`image_delete`, `reset`, `config_file_load`. Those are destructive or
slow; they will get their own opt-in file if anyone needs them.

## Troubleshooting

### Cloud-init did not apply on first boot

VyOS cloud-init handling varies between rolling builds. If the API
key is not active after phase 2, boot the VM, configure the API
manually once, save, poweroff, and rerun `ensure-template.sh`:

```text
configure
set service https api rest
set service https api keys id pyvyos key 'pyvyos-e2e-please-change-me'
set service https listen-address '0.0.0.0'
commit
save
exit
poweroff
```

The `set service https api rest` line is essential. Without it the
HTTPS service only exposes `/info`, and every other endpoint
(`/retrieve`, `/configure`, `/show`, …) responds with `404`. See
the VyOS docs for HTTP API service.

### HTTP 400 "Dummy interface must be named dumN"

The live tests intentionally use interface names like `dum1234` to
match the VyOS naming policy for `dummy` interfaces. If you adapt
the tests, keep that pattern; arbitrary names are rejected by VyOS
config validation with a 400.

### "VMID already exists"

Each script checks before mutating. To start over from scratch:

```bash
tests/pve/destroy-vm.sh                 # clears the e2e VM
ssh $PVE_SSH_TARGET qm destroy $VYOS_TEMPLATE_VMID --purge
tests/pve/ensure-template.sh            # phase 1 again
```

### API key in the template

The key from `tests/pve/.env` is baked into the template. That is
fine for a private lab. **Do not** export this template to a shared
PVE or hand it to other people without rotating the key.

## What this harness is not

- Not Vagrant. `examples/vagrant/` already covers desktop labs.
- Not Docker. VyOS is an appliance OS; real KVM is the honest test.
- Not CI. GitHub Actions cannot run nested KVM cheaply, and a
  scheduled live job on someone else's hardware is not worth the
  operational cost for a thin SDK.
- Not a packaging story. The harness is for maintainers and brave
  users; nothing in `pyvyos/` depends on it.