diff options
| author | Christian Breunig <christian@breunig.cc> | 2026-10-07 19:56:47 +0200 |
|---|---|---|
| committer | Christian Breunig <christian@breunig.cc> | 2026-10-31 09:58:29 +0000 |
| commit | 0b9903a85ccbef75b653a4d4349db5710ee9638d (patch) | |
| tree | fe853124478847d772207e316a3bb0eb086d65d7 /python | |
| parent | 724c38de924caab6cb3e2c0b57173ef0742ffa40 (diff) | |
| download | vyos-1x-0b9903a85ccbef75b653a4d4349db5710ee9638d.tar.gz vyos-1x-0b9903a85ccbef75b653a4d4349db5710ee9638d.zip | |
interfaces: T3871: persist interface names on the first boot of a pre-built image
The check guarding that write looked for a marker which an activation
script creates only after interface naming has already run. On a deployed
qcow2 the marker is absent on the first boot, so nothing was recorded and
the next boot named the hardware from scratch. Removing a card then moved
every name below it onto the neighbouring port, taking that interface's
address with it.
Only an encrypted configuration has a volume which may still be locked, so
ask about that instead - everywhere else the directory is already the
persistent one.
Diffstat (limited to 'python')
| -rw-r--r-- | python/vyos/ifconfig/ifname_store.py | 44 |
1 files changed, 38 insertions, 6 deletions
diff --git a/python/vyos/ifconfig/ifname_store.py b/python/vyos/ifconfig/ifname_store.py index e6a0876fd..9c00810db 100644 --- a/python/vyos/ifconfig/ifname_store.py +++ b/python/vyos/ifconfig/ifname_store.py @@ -218,15 +218,47 @@ def load_store(path: Path = None) -> dict: 'hardware': hardware} -def config_dir_is_mounted(path: Path = None) -> bool: - """Is the config directory the real one, or a bare rootfs overlay? +def encrypted_config_volume() -> bool: + """Does this image keep its configuration on a LUKS volume? + + Mirrors mount_encrypted_config() in src/init/vyos-router - a container + named after the running image, below the persistence path. Anything that + cannot be determined (no persistence, no version file, not a VyOS system + at all) means there is no volume waiting to be mounted over the config + directory. + """ + try: + from vyos.system.image import get_running_image + + code, out = rc_cmd('/opt/vyatta/sbin/vyos-persistpath') + if code != 0 or not out.strip(): + return False + image = get_running_image() + return bool(image) and (Path(out.strip()) / 'luks' / image).is_file() + except Exception: + return False - A failed TPM/LUKS unlock does not stop the boot. Writing to the overlay - underneath would be masked once the real volume mounts, leaving two - stores which silently diverge. + +def config_dir_is_mounted(path: Path = None) -> bool: + """Will a store written here still be there on the next boot? + + Only an encrypted configuration has a volume which may still be locked: + a failed TPM/LUKS unlock does not stop the boot, and writing to the + directory underneath would be masked once the real volume mounts, + leaving two stores which silently diverge. Everywhere else the directory + is already the persistent one. + + Deliberately not keyed on '.vyatta_config'. That marker is an + install-time hint, written by an activation script which runs *after* + interface naming - so on the first boot of a pre-built image it does not + exist yet, no store is ever written, and the next boot names the + hardware from scratch. Removing a card then shifts every name below it + onto the wrong port (T3871). """ path = path or store_path - return (path.parent / '.vyatta_config').exists() + if not encrypted_config_volume(): + return True + return os.path.ismount(path.parent) def save_store(store: dict, path: Path = None) -> bool: |
