Skip to content

Commit f45e502

Browse files
image: T5455: Add migration of SSH known_hosts files during image upgrade
During upgrade, the script now checks if any `known_hosts` files exist. If so, it prompts the user to save these SSH fingerprints, and upon confirmation, copies the files to the new image persistence directory.
1 parent 9684092 commit f45e502

File tree

1 file changed

+55
-0
lines changed

1 file changed

+55
-0
lines changed

src/op_mode/image_installer.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
from argparse import ArgumentParser, Namespace
2121
from pathlib import Path
22+
from pwd import getpwall
2223
from shutil import copy, chown, rmtree, copytree, disk_usage
2324
from glob import glob
2425
from sys import exit
@@ -715,6 +716,20 @@ def copy_ssh_host_keys() -> bool:
715716
return False
716717

717718

719+
def copy_ssh_known_hosts() -> bool:
720+
"""Ask user to copy SSH `known_hosts` files
721+
722+
Returns:
723+
bool: user's decision
724+
"""
725+
known_hosts_files = get_known_hosts_files()
726+
msg = (
727+
'Would you like to save the SSH known hosts (fingerprints) '
728+
'from your current configuration?'
729+
)
730+
return known_hosts_files and ask_yes_no(msg, default=True)
731+
732+
718733
def console_hint() -> str:
719734
pid = getppid() if 'SUDO_USER' in environ else getpid()
720735
try:
@@ -1010,6 +1025,41 @@ def install_image() -> None:
10101025
exit(1)
10111026

10121027

1028+
def get_known_hosts_files() -> list:
1029+
"""Collect all existing `known_hosts` files for root and users under /home"""
1030+
1031+
files = []
1032+
1033+
# for root
1034+
base_files = ('/root/.ssh/known_hosts', '/etc/ssh/ssh_known_hosts')
1035+
for file_path in base_files:
1036+
root_known_hosts = Path(file_path)
1037+
if root_known_hosts.exists():
1038+
files.append(root_known_hosts)
1039+
1040+
# for each non-system user
1041+
for user in getpwall():
1042+
home_dir = Path(user.pw_dir)
1043+
# skip system users
1044+
if home_dir.exists() and home_dir.as_posix().startswith('/home'):
1045+
known_hosts = home_dir / '.ssh' / 'known_hosts'
1046+
if known_hosts.exists():
1047+
files.append(known_hosts)
1048+
1049+
return files
1050+
1051+
1052+
def migrate_known_hosts(target_dir: str):
1053+
"""Copy `known_hosts` for root and all users to the new image directory"""
1054+
1055+
known_hosts_files = get_known_hosts_files()
1056+
for known_hosts_file in known_hosts_files:
1057+
# copy file to target directory
1058+
target_known_hosts = Path(f'{target_dir}{known_hosts_file}')
1059+
target_known_hosts.parent.mkdir(parents=True, exist_ok=True)
1060+
copy(known_hosts_file, target_known_hosts)
1061+
1062+
10131063
@compat.grub_cfg_update
10141064
def add_image(image_path: str, vrf: str = None, username: str = '',
10151065
password: str = '', no_prompt: bool = False, force: bool = False) -> None:
@@ -1115,6 +1165,11 @@ def add_image(image_path: str, vrf: str = None, username: str = '',
11151165
for host_key in host_keys:
11161166
copy(host_key, target_ssh_dir)
11171167

1168+
target_ssh_known_hosts_dir: str = f'{root_dir}/boot/{image_name}/rw'
1169+
if no_prompt or copy_ssh_known_hosts():
1170+
print('Copying SSH known hosts')
1171+
migrate_known_hosts(target_ssh_known_hosts_dir)
1172+
11181173
# copy system image and kernel files
11191174
print('Copying system image files')
11201175
for file in Path(f'{DIR_ISO_MOUNT}/live').iterdir():

0 commit comments

Comments
 (0)