From 5305a7884dab4ef8e4ff6e7ce3402f90dd7fe7b6 Mon Sep 17 00:00:00 2001 From: Yann Dirson Date: Tue, 6 Aug 2024 17:44:49 +0200 Subject: [PATCH 1/3] squash! Preserve more stunnel certificates on upgrade buildRestoreList: include xapi-stunnel-ca-bundle.pem 9a09a4d9e8dd7a1e0f25c0cb2ebeb3a58ecd05de preserves the certs themselves, but for some reason the bundle is not necessarily regenerated from them, (especially when the dir was empty and is "thus" not preserved?) so preserve the bundle as well - as was done for the pool bundle. Signed-off-by: Yann Dirson (cherry picked from commit 117bde708f89cf532abe3175e68690674ed3ddbe) --- upgrade.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/upgrade.py b/upgrade.py index d290701c..4ea7c237 100644 --- a/upgrade.py +++ b/upgrade.py @@ -591,7 +591,7 @@ def buildRestoreList(self, src_base): # Preserve pool certificates across upgrades self.restore_list += ['etc/stunnel/xapi-pool-ca-bundle.pem', {'dir': 'etc/stunnel/certs-pool'}] - self.restore_list += [{'dir': 'etc/stunnel/certs'}] + self.restore_list += ['etc/stunnel/xapi-stunnel-ca-bundle.pem', {'dir': 'etc/stunnel/certs'}] completeUpgradeArgs = ['mounts', 'installation-to-overwrite', 'primary-disk', 'backup-partnum', 'logs-partnum', 'net-admin-interface', 'net-admin-bridge', 'net-admin-configuration'] def completeUpgrade(self, mounts, prev_install, target_disk, backup_partnum, logs_partnum, admin_iface, admin_bridge, admin_config): From 5b8ebd8fe52b8ffcc96535bb389bf6728b965b79 Mon Sep 17 00:00:00 2001 From: Yann Dirson Date: Tue, 6 Aug 2024 17:41:15 +0200 Subject: [PATCH 2/3] restore_file: make a single lookup of 're' in dict Signed-off-by: Yann Dirson --- upgrade.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/upgrade.py b/upgrade.py index 4ea7c237..fd870f12 100644 --- a/upgrade.py +++ b/upgrade.py @@ -182,7 +182,7 @@ def restore_file(src_base, f, d=None): assert 'dst' in f restore_file(tds.mount_point, f['src'], f['dst']) elif 'dir' in f: - pat = 're' in f and f['re'] or None + pat = f.get('re', None) src_dir = os.path.join(tds.mount_point, f['dir']) if os.path.exists(src_dir): for ff in os.listdir(src_dir): From 331c4392f85fe5fdab3b86c490d72099b2b2a2a0 Mon Sep 17 00:00:00 2001 From: Yann Dirson Date: Tue, 6 Aug 2024 17:51:20 +0200 Subject: [PATCH 3/3] restore_file: when no re is given for a dir, preserve whole dir in one go If the specified dir exists but is empty (as can happen for /etc/stunnel/certs), the current code would not restore it, as in fact it restores not the dir, but its immediate children matching the pattern. When no pattern is given, avoid complications by using the fact that restore_file perfectly works with directories too. Note this makes it prominent that the 're' handling is only ever applied to immediate children of the dir; we may simplify further by moving the pattern-matching code down to restore_file, but then do we want to keep the current behavior? Signed-off-by: Yann Dirson --- upgrade.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/upgrade.py b/upgrade.py index fd870f12..fa3e51d7 100644 --- a/upgrade.py +++ b/upgrade.py @@ -185,10 +185,14 @@ def restore_file(src_base, f, d=None): pat = f.get('re', None) src_dir = os.path.join(tds.mount_point, f['dir']) if os.path.exists(src_dir): - for ff in os.listdir(src_dir): - fn = os.path.join(f['dir'], ff) - if not pat or pat.match(fn): - restore_file(tds.mount_point, fn) + if pat is not None: + # filter here (though should ideally let restore_file do it) + for ff in os.listdir(src_dir): + fn = os.path.join(f['dir'], ff) + if pat.match(fn): + restore_file(tds.mount_point, fn) + else: + restore_file(tds.mount_point, f['dir']) finally: tds.unmount()