feat: implement automated VMID discovery for LXC creation

This commit is contained in:
Fredrick Amnehagen 2026-02-06 08:36:38 +01:00
parent 1536974fcc
commit b5814e9e61
4 changed files with 35 additions and 4 deletions

View file

@ -37,7 +37,7 @@ export INFRA_CONFIG=$(pwd)/config.yaml
### Official Recommended Flow
1. **Find an IP:** `infra ip next-free`
2. **Create Database:** `infra db provision "my-project"`
3. **Provision LXC:** `infra proxmox create-lxc 12xxx debian-13 "my-host" "10.32.70.x/16" "10.32.0.1" --node la-vmh-12`
3. **Provision LXC:** `infra proxmox create-lxc debian-13 "my-host" "10.32.70.x/16" "10.32.0.1" --node la-vmh-12`
4. **Setup DNS:** `infra dns add-host <MAC> 10.32.70.x "my-host"`
5. **Update SSL:** `infra cert renew`
6. **Expose Ingress:** `infra ingress add "my-project.loopaware.com" 10.32.70.x 80`

View file

@ -156,7 +156,7 @@ def proxmox_list_lxcs(config, node):
click.echo(mgr.list_lxcs())
@proxmox.command(name='create-lxc')
@click.argument('vmid')
@click.option('--vmid', help='VMID for the container (auto-discovered if omitted)')
@click.argument('template')
@click.argument('hostname')
@click.argument('ip')
@ -166,8 +166,18 @@ def proxmox_list_lxcs(config, node):
@click.pass_obj
def proxmox_create_lxc(config, vmid, template, hostname, ip, gateway, node, password):
mgr = ProxmoxManager(config, node)
mgr.create_lxc(vmid, template, hostname, ip, gateway, password=password)
click.echo(f"LXC {vmid} ({hostname}) created on {mgr.node_name or 'default node'}")
target_vmid = vmid
if not target_vmid:
click.echo("Discovering next available VMID...")
target_vmid = mgr.get_next_vmid()
if not target_vmid:
click.echo("Error: Could not automatically discover next VMID. Please provide one with --vmid", err=True)
sys.exit(1)
click.echo(f"Using VMID: {target_vmid}")
mgr.create_lxc(target_vmid, template, hostname, ip, gateway, password=password)
click.echo(f"LXC {target_vmid} ({hostname}) created on {mgr.node_name or 'default node'}")
@cli.group()
def samba():

View file

@ -22,6 +22,14 @@ class ProxmoxManager:
res = self.client.run(f"pct status {vmid}")
return res.stdout
def get_next_vmid(self):
"""Retrieves the next available cluster-wide VMID from Proxmox"""
res = self.client.run("pvesh get /cluster/nextid")
if res.returncode == 0 and res.stdout.strip():
return res.stdout.strip()
# Fallback if pvesh fails (highly unlikely on PVE)
return None
def resolve_template(self, alias):
"""Resolves a template alias (e.g. 'debian-13') to the latest full path on the node"""
if alias == "debian-13":

View file

@ -31,3 +31,16 @@ def test_storage_discovery(mock_ssh):
storage = mgr.discover_storage()
assert storage == "local-zfs"
@patch('infra_cli.proxmox.SSHClient')
def test_vmid_discovery(mock_ssh):
mock_instance = mock_ssh.return_value
mock_instance.run.return_value.returncode = 0
mock_instance.run.return_value.stdout = "105"
mgr = ProxmoxManager(MockConfig())
vmid = mgr.get_next_vmid()
assert vmid == "105"
mock_instance.run.assert_called_with("pvesh get /cluster/nextid")