package proxmox import ( "net/netip" "gitea.home.hrajfrisbee.cz/kacerr/egress-proxies-operator/internal/provider" ) // mapState turns status/current's status and qmpstatus plus the discovered // address into the contract's state (spec entry 9). A VM is Running only // with an address; prelaunch is still starting; any other qmpstatus of a // running VM (paused, suspended, io-error, …) and any status not recognised // is Stopped, which the reconciler answers by replacing the VM. An empty // qmpstatus is taken as running: the field is missing, not a state. func mapState(status, qmpStatus, ip string) provider.InstanceState { if status != "running" { return provider.StateStopped } switch qmpStatus { case "running", "": if ip == "" { return provider.StateProvisioning } return provider.StateRunning case "prelaunch": return provider.StateProvisioning default: return provider.StateStopped } } // firstIPv4 picks the first usable IPv4 from the guest agent's interfaces, // in the agent's order: not on the loopback interface, not loopback, // link-local or unspecified. Empty means no address yet. func firstIPv4(ifaces []agentInterface) string { for _, iface := range ifaces { if iface.Name == "lo" { continue } for _, a := range iface.IPAddresses { if a.Type != "ipv4" { continue } addr, err := netip.ParseAddr(a.Address) if err != nil || !addr.Is4() || addr.IsLoopback() || addr.IsLinkLocalUnicast() || addr.IsUnspecified() { continue } return addr.String() } } return "" }