Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions ansible/requirements.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,11 @@ collections:
# Required by the molecule docker driver, not by any role.
- name: community.docker
version: ">=5.0.0"

# tests/proxmox/create.yml and reset.yml. The proxmox_* modules left
# community.general for this collection and are removed from it at 15.0.0,
# which the floor above will reach.
- name: community.proxmox
version: ">=1.0.0"
- name: ansible.posix
version: ">=2.0.0"
58 changes: 55 additions & 3 deletions ansible/tests/.env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,18 @@
# =============================================================================
# Your Proxmox server connection details
PROXMOX_HOST=proxmox.example.com
PROXMOX_USER=root@pam
PROXMOX_PASSWORD= # Optional - leave empty if using SSH keys
PROXMOX_NODE=pve
PROXMOX_API_VERIFY_SSL=false
PROXMOX_API_VERIFY_SSL=true

# An API token, the same one hyperi-infra's tools use: user@realm!name plus
# its secret, made under Datacenter > Permissions > API Tokens. The playbooks
# in tests/proxmox/ authenticate with these two and nothing else.
PROXMOX_TOKEN_ID=hyperi-vm@pve!cli-token
PROXMOX_TOKEN_SECRET=

# root@pam password. Only the older provision.yml still reads these.
PROXMOX_USER=root@pam
PROXMOX_PASSWORD=

# Fedora Test VM
PROXMOX_FEDORA_VMID=2005
Expand All @@ -28,6 +36,50 @@ PROXMOX_UBUNTU_USER=dfe
PROXMOX_UBUNTU_PASSWORD=dfe # Optional - omit from inventory if using SSH keys
PROXMOX_UBUNTU_SSH_PORT=22

# -----------------------------------------------------------------------------
# TEST VMS (tests/proxmox/create.yml and reset.yml)
# -----------------------------------------------------------------------------
# Snapshot-reset testing: create.yml clones a base template into the range
# below, sizes it, brings it current, stops it and snapshots it. reset.yml
# rolls any VM in the range back to that snapshot. delete.yml removes one.
# All three refuse a vmid outside the range, so a typo cannot roll back,
# overwrite or delete a real machine.
PROXMOX_TEST_VMID_MIN=8100
PROXMOX_TEST_VMID_MAX=8199

# The base (not desktop) template: a clean cloud image with cloud-init and
# nothing else. The desktop template bakes hyperi-developer in, which is the
# thing under test.
PROXMOX_TEST_TEMPLATE_VMID=9041

# Size and placement of a VM create.yml makes, matched to the lab's other test
# machines. STORAGE is where the full clone lands; the disk is grown to DISK
# and cloud-init grows the root filesystem at boot. Leave one empty to keep
# the template's value.
PROXMOX_TEST_CORES=8
PROXMOX_TEST_MEMORY=16384
PROXMOX_TEST_DISK=100G
PROXMOX_TEST_STORAGE=

# The cloud-init search domain. The lab DNS registers <vm name>.<domain> for
# every DHCP lease, which is how a VM made without -e ip is reached.
PROXMOX_TEST_DOMAIN=example.com

# Static addressing, used when create.yml is given -e ip=<addr>/<prefix>.
PROXMOX_TEST_GATEWAY=192.0.2.1
PROXMOX_TEST_NAMESERVER=

# Login that create.yml sets through cloud-init, and that reset.yml writes
# into the inventory. A VM made some other way passes its own with
# -e test_user= -e test_password= -e snapshot=.
PROXMOX_TEST_USER=hyperi
PROXMOX_TEST_PASSWORD=

# The private key Ansible connects with; its .pub is what cloud-init installs
# for that user. Cloud images ship sshd with password login off, so the
# password above serves the console and sudo only. An absolute path.
PROXMOX_TEST_SSH_KEY=/home/you/.ssh/devex-ssh

# -----------------------------------------------------------------------------
# CLONE-TEST (emulates the auto desktop image cycle: clone -> test -> delete)
# -----------------------------------------------------------------------------
Expand Down
8 changes: 8 additions & 0 deletions ansible/tests/common/setup_env.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,20 @@
Press Enter when done editing...
when: not env_file_stat.stat.exists

# bash, not /bin/sh: on Debian and Ubuntu /bin/sh is dash, which has no
# `source`. The failure was silent -- the pipeline's exit status is jq's -- so
# `env` returned whatever PROXMOX_* the ambient shell already carried, and a
# token from the operator's environment quietly stood in for the file's.
# `set -e` and pipefail make a missing or unreadable .env fail the task.
- name: Load environment variables from .env (shell format)
ansible.builtin.shell: |
set -euo pipefail
set -a
source "{{ tests_dir }}/.env"
set +a
env | grep -E '^(PROXMOX|ANSIBLE)_' | jq -R 'split("=") | {(.[0]): .[1:] | join("=")}' | jq -s 'add'
args:
executable: /bin/bash
register: env_raw
changed_when: false

Expand Down
61 changes: 61 additions & 0 deletions ansible/tests/proxmox/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Snapshot-reset testing against Proxmox VMs

Run hyperi-developer against a real VM from a known clean state, as many times
as needed, by hand. Not CI: it needs a Proxmox endpoint and credentials.

Configuration is the `TEST VMS` block in `tests/.env` (copy
`tests/.env.sample`). Authentication is the same Proxmox API token
hyperi-infra's tools use -- `PROXMOX_TOKEN_ID` and `PROXMOX_TOKEN_SECRET`,
never a root password. Login to the VM itself is by key: cloud-init installs
the `.pub` of `PROXMOX_TEST_SSH_KEY` for the test user, because cloud images
ship sshd with password login off. Everything here runs from `ansible/`.

The modules need `proxmoxer` on the machine running the playbook, for the
Python that Ansible uses: `sudo apt install python3-proxmoxer` on Debian and
Ubuntu, or pip inside whatever venv runs Ansible. Then
`ansible-galaxy collection install -r requirements.yml` for `community.proxmox`.

## Make a clean VM once

ansible-playbook tests/proxmox/create.yml -e vm_name=ubuntu-test.example.com \
-e vmid=8101 -e ip=192.0.2.51/24

Clones the base template, sizes it from `.env` (cores, memory, disk,
storage), gives it a static address or DHCP, boots it once to bring every
package current, **stops it**, and snapshots it as `clean`. hyperi-developer
never runs here: the snapshot is the state every test starts from.

The VM name is what Proxmox and the lab DNS see, so name a static VM by its
FQDN. Leave off `-e vmid` for the lowest free id in the range and `-e ip` for
DHCP, where the lab DNS names the VM `<vm_name>.<domain>`.

The base template, not the desktop one: the desktop template bakes
hyperi-developer in, which is the thing under test.

## Test

ansible-playbook tests/proxmox/reset.yml -e vmid=8101
ansible-playbook -i tests/proxmox/inventory_proxmox.yml playbooks/main.yml --tags developer-rust
ansible-playbook tests/proxmox/reset.yml -e vmid=8101 -e start=false

`reset.yml` stops the VM, rolls it back to `clean`, starts it, waits for sshd,
and writes `inventory_proxmox.yml` for it. The last line is the resting state:
a test VM is off except while a test runs, so finish by rolling it back again
and leaving it stopped.

A VM made some other way -- the Fedora box, say -- passes its own snapshot
name and login: `-e snapshot=initial_build -e test_user=dfe -e test_password=dfe`.

## Remove

ansible-playbook tests/proxmox/delete.yml -e vmid=8102

## Safety

All three playbooks refuse a vmid outside `PROXMOX_TEST_VMID_MIN..MAX`. A
rollback or delete discards everything on the machine, so that range is the
only place it can happen.

`provision.yml` and `test_all.yml` predate this and target a fixed
Fedora+Ubuntu pair; `test_all.yml` also installs from a branch that no longer
exists. Prefer the playbooks above.
Loading
Loading