From e47d4fd385631236da6882233b09f6364cbb077b Mon Sep 17 00:00:00 2001
From: Christian Breunig <christian@breunig.cc>
Date: Wed, 26 Jun 2024 15:35:10 +0200
Subject: interfaces: T6519: harden config migration if ethernet interface is
 missing

During a corner case where the configuration is migrated to a different system
with fewer ethernet interfaces, migration will fail during an image upgrade.

vyos.ethtool.Ethtool() is instantiated with an invalid interface leading to an
exception that kills the migrator
---
 python/vyos/ethtool.py                    | 4 ++++
 src/migration-scripts/interfaces/20-to-21 | 7 ++++++-
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/python/vyos/ethtool.py b/python/vyos/ethtool.py
index d45c9c272..80bb56fa2 100644
--- a/python/vyos/ethtool.py
+++ b/python/vyos/ethtool.py
@@ -16,6 +16,7 @@
 import re
 
 from json import loads
+from vyos.utils.network import interface_exists
 from vyos.utils.process import popen
 
 # These drivers do not support using ethtool to change the speed, duplex, or
@@ -64,6 +65,9 @@ class Ethtool:
 
     def __init__(self, ifname):
         # Get driver used for interface
+        if not interface_exists(ifname):
+            raise ValueError(f'Interface "{ifname}" does not exist!')
+
         out, _ = popen(f'ethtool --driver {ifname}')
         driver = re.search(r'driver:\s(\w+)', out)
         if driver:
diff --git a/src/migration-scripts/interfaces/20-to-21 b/src/migration-scripts/interfaces/20-to-21
index 14ad0fe4d..05a0c7237 100755
--- a/src/migration-scripts/interfaces/20-to-21
+++ b/src/migration-scripts/interfaces/20-to-21
@@ -1,6 +1,6 @@
 #!/usr/bin/env python3
 #
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright (C) 2021-2024 VyOS maintainers and contributors
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License version 2 or later as
@@ -22,6 +22,7 @@ from sys import argv
 
 from vyos.ethtool import Ethtool
 from vyos.configtree import ConfigTree
+from vyos.utils.network import interface_exists
 
 if len(argv) < 2:
     print("Must specify file name!")
@@ -38,6 +39,10 @@ if not config.exists(base):
     exit(0)
 
 for ifname in config.list_nodes(base):
+    # Bail out early if interface vanished from system
+    if not interface_exists(ifname):
+        continue
+
     eth = Ethtool(ifname)
 
     # If GRO is enabled by the Kernel - we reflect this on the CLI. If GRO is
-- 
cgit v1.2.3