feat(ip-pool): pre-assign static IPs to build VMs via VMX guestinfo
Eliminates VMware-Tools IP-detect polling (observed: 39–177 s variance on
Linux host B7 benchmark). When [ip_pool] is configured the orchestrator:
1. Allocates a slot IP from a JSON-backed pool (fcntl-locked on Linux)
2. Injects guestinfo.ip-assignment / netmask / gateway into the cloned VMX
before vmrun start
3. Skips _wait_for_ip entirely — uses the pre-assigned IP immediately
4. Releases the slot in _destroy_clone (all paths: success/failure/interrupt)
New modules / changes:
src/ci_orchestrator/ip_pool.py IpSlotPool + _file_lock context manager
src/ci_orchestrator/config.py IpPoolConfig dataclass; [ip_pool] TOML
src/ci_orchestrator/commands/job.py _inject_guestinfo_ip helper; pool wiring
tests/python/test_ip_pool.py 12 unit tests (acquire/release/persist)
tests/python/test_config.py ip_pool config parsing tests
tests/python/test_commands_job.py pool path + _inject_guestinfo_ip tests
config.example.toml [ip_pool] section (commented example)
Coverage 90.02%; mypy --strict clean.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -107,3 +107,41 @@ def test_toml_provides_ssh_key_path_and_guest_cred_target(tmp_path: Path) -> Non
|
||||
cfg = load_config(config_path=toml, env={})
|
||||
assert cfg.ssh_key_path == key
|
||||
assert cfg.guest_cred_target == "MyTarget"
|
||||
|
||||
|
||||
def test_toml_ip_pool_parsed(tmp_path: Path) -> None:
|
||||
lease = tmp_path / "ip-pool.json"
|
||||
toml = tmp_path / "config.toml"
|
||||
toml.write_text(
|
||||
"[ip_pool]\n"
|
||||
'addresses = ["192.168.79.201", "192.168.79.202"]\n'
|
||||
'netmask = "255.255.255.0"\n'
|
||||
'gateway = "192.168.79.2"\n'
|
||||
f'lease_file = "{lease.as_posix()}"\n',
|
||||
encoding="utf-8",
|
||||
)
|
||||
cfg = load_config(config_path=toml, env={})
|
||||
assert cfg.ip_pool is not None
|
||||
assert cfg.ip_pool.addresses == ["192.168.79.201", "192.168.79.202"]
|
||||
assert cfg.ip_pool.netmask == "255.255.255.0"
|
||||
assert cfg.ip_pool.gateway == "192.168.79.2"
|
||||
assert cfg.ip_pool.lease_file == lease
|
||||
|
||||
|
||||
def test_toml_ip_pool_default_lease_file(tmp_path: Path) -> None:
|
||||
toml = tmp_path / "config.toml"
|
||||
toml.write_text(
|
||||
"[ip_pool]\n"
|
||||
'addresses = ["192.168.79.201"]\n',
|
||||
encoding="utf-8",
|
||||
)
|
||||
cfg = load_config(config_path=toml, env={})
|
||||
assert cfg.ip_pool is not None
|
||||
assert cfg.ip_pool.lease_file.name == "ip-pool.json"
|
||||
|
||||
|
||||
def test_ip_pool_absent_when_not_configured(tmp_path: Path) -> None:
|
||||
toml = tmp_path / "config.toml"
|
||||
toml.write_text("[backend]\ntype = \"workstation\"\n", encoding="utf-8")
|
||||
cfg = load_config(config_path=toml, env={})
|
||||
assert cfg.ip_pool is None
|
||||
|
||||
Reference in New Issue
Block a user