DataSourceCloudStack: get_vr_address() does not catch NoDHCPLeaseError, so the default-gateway fallback is never reached
I maintainer di solito rispondono entro 1 giorno
Valutazione
- Difficoltà
- 2/5
- Tempo stimato
- 1-3 ore
- Idoneità per principianti
- 88/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Stack tecnologico
- python
- Ambito
- networking
Direzione di ricerca
Inizia in cloudinit/sources/DataSourceCloudStack.py, in get_vr_address(), quindi confronta la relativa gestione dei lease DHCP con _get_domainname(). Esegui il comando di riproduzione Fedora riportato nell’issue per confermare il percorso NoDHCPLeaseError. Il lavoro è completato quando viene restituito il gateway predefinito se il client DHCP della distribuzione non dispone di alcun lease, mantenendo invariato l’ordine esistente di ricerca degli indirizzi.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Bug report
In cloudinit/sources/DataSourceCloudStack.py, get_vr_address() tries several
sources for the virtual router address, in order:
- the
data-serverDNS entry - systemd-networkd leases
- ISC dhclient leases
- the lease of the distro's DHCP client (
distro.dhcp_client.get_newest_lease()) - the default gateway
Step 4 is guarded only against FileNotFoundError:
with suppress(FileNotFoundError):
latest_lease = distro.dhcp_client.get_newest_lease(
distro.fallback_interface
)
On distributions where dhcpcd is installed but not running — because
NetworkManager handles DHCP with its internal client — dhcpcd --dumplease
exits 1 with dhcpcd is not running. Dhcpcd.get_newest_lease() catches the
resulting ProcessExecutionError and re-raises it as NoDHCPLeaseError. That
exception is not suppressed, so it escapes get_vr_address() and step 5 is
never reached. DataSourceCloudStack is then unable to determine the metadata
server address.
This is the default situation on Fedora 44 and on RHEL/Rocky Linux 10: the
cloud-init package depends on dhcpcd, but NetworkManager does not use it.
Related
The same pattern was fixed in _get_domainname(), which now uses
except (NoDHCPLeaseError, FileNotFoundError, AttributeError). RHEL
backported that fix as RHEL-159033 (cloud-init-24.4-7.el10_2.1).
get_vr_address() still uses the original suppress(FileNotFoundError),
both in 26.1 and in main.
When it is triggered
Step 4 is only reached when data-server does not resolve. On CloudStack that
name is served by dnsmasq on the virtual router, so this happens whenever the
guest does not use the router as its DNS server, for example:
- a network offering that does not provide the Dns service through the VirtualRouter
- the zone setting
use.external.dns = true - DNS servers configured manually in the guest
In CloudStack isolated networks the virtual router is also the default
gateway, so the step 5 fallback would return the correct address. Today it is
never reached.
Steps to reproduce
Fedora 44 with cloud-init 26.1, on a CloudStack guest in an isolated network
whose DNS servers do not include the virtual router
(getent hosts data-server returns nothing; default gateway 192.168.1.254
is the virtual router):
sudo python3 - <<'EOF'
from cloudinit import distros, helpers
from cloudinit.sources import DataSourceCloudStack as ds
d = distros.fetch('fedora')('fedora', {}, helpers.Paths({}))
print("VR:", ds.get_vr_address(d))
EOF
Expected: the default gateway (192.168.1.254) is returned.
Actual: NoDHCPLeaseError is raised:
Traceback (most recent call last):
File "/usr/lib/python3.14/site-packages/cloudinit/net/dhcp.py", line 864, in get_newest_lease
subp.subp(
~~~~~~~~~^
[
^
...<4 lines>...
],
^^
).stdout,
^
File "/usr/lib/python3.14/site-packages/cloudinit/subp.py", line 291, in subp
raise ProcessExecutionError(
stdout=out, stderr=err, exit_code=rc, cmd=args
)
cloudinit.subp.ProcessExecutionError: Unexpected error while running command.
Command: ['dhcpcd', '--dumplease', '--ipv4only', 'enp3s0']
Exit code: 1
Reason: -
Stdout:
Stderr: dhcpcd is not running
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
File "/usr/lib/python3.14/site-packages/cloudinit/sources/DataSourceCloudStack.py", line 342, in get_vr_address
latest_lease = distro.dhcp_client.get_newest_lease(
distro.fallback_interface
)
File "/usr/lib/python3.14/site-packages/cloudinit/net/dhcp.py", line 882, in get_newest_lease
raise NoDHCPLeaseError from error
cloudinit.net.dhcp.NoDHCPLeaseError
Proposed fix
- with suppress(FileNotFoundError):
+ with suppress(FileNotFoundError, NoDHCPLeaseError):
latest_lease = distro.dhcp_client.get_newest_lease(
distro.fallback_interface
)
or, for consistency with _get_domainname(),
suppress(NoDHCPLeaseError, FileNotFoundError, AttributeError).
NoDHCPLeaseError is already imported in the module.
Tested on the same guest by loading a patched copy of the module:
sudo python3 - <<'EOF'
import importlib.util
from cloudinit import distros, helpers
p = '/usr/lib/python3.14/site-packages/cloudinit/sources/DataSourceCloudStack.py'
src = open(p).read()
old = " with suppress(FileNotFoundError):\n latest_lease"
new = " with suppress(FileNotFoundError, NoDHCPLeaseError):\n latest_lease"
assert src.count(old) == 1
mod = importlib.util.module_from_spec(importlib.util.spec_from_loader("ds_patched", loader=None))
exec(compile(src.replace(old, new), "DataSourceCloudStack_patched.py", "exec"), mod.__dict__)
d = distros.fetch('fedora')('fedora', {}, helpers.Paths({}))
print("VR:", mod.get_vr_address(d))
EOF
Output:
VR: 192.168.1.254
With the fix, get_vr_address() falls back to the default gateway, which in
this isolated network is the virtual router.
Environment details
- cloud-init: 26.1 (cloud-init-26.1-1.fc44); same code in
mainas of 2026-09-30 - OS: Fedora 44 Cloud Base Generic; same code path on Rocky Linux 10
- Platform: Apache CloudStack 4.22, KVM, isolated guest network
- Networking: NetworkManager with its internal DHCP client; dhcpcd installed but not running
- Lingua principale
- Python
- Stelle
- 3.9k
- Fork
- 1.2k
- Merge medio
- 2g 26m
- PR unite (30g)
- 16
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di canonical/cloud-init
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
canonical/cloud-init#7232 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
canonical/cloud-init#7231 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
canonical/cloud-init#7230 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
canonical/cloud-init#7229 ·
I maintainer di solito rispondono entro 1 giorno
-
Should be wrapped in try...except in case of JSONDecodeErrorForse già presa @p-ramcharan-dev l’ha presa 1 giorno fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
canonical/cloud-init#7069 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di canonical/cloud-init
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 83/100
I maintainer di solito rispondono entro 1 giorno
-
comp/desktop P3 type/feature
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
NousResearch/hermes-agent#154285 ·
I maintainer di solito rispondono entro 1 giorno
-
docs: qualify copied and custom kubectl debug policy notesForse già presa @nym01 l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
kubescape/cel-admission-library#166 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
SACGF/variantgrid#2804 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
[BUG] HTTP lifecycle dispatch treats a NO_PROXY-only environment as corporate egress and skips the resolve-and-pinned sessionForse già presa @bodapatisaikrishna l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
I maintainer di solito rispondono entro 1 giorno