Skip to content

Commit

Permalink
Merge pull request #35 from wizzomafizzo/custom-network
Browse files Browse the repository at this point in the history
Add support for persistent Linux config files
  • Loading branch information
theypsilon committed Jul 25, 2023
2 parents 49de791 + 592e269 commit 2c1511b
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 1 deletion.
9 changes: 9 additions & 0 deletions src/downloader/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,15 @@
# Linux Update files
FILE_MiSTer_version = '/MiSTer.version'
FILE_Linux_7z = '/media/fat/linux/7za'
FILE_Linux_user_files = [
# source -> destination
('/media/fat/linux/hostname', '/etc/hostname'),
('/media/fat/linux/hosts', '/etc/hosts'),
('/media/fat/linux/interfaces', '/etc/network/interfaces'),
('/media/fat/linux/resolv.conf', '/etc/resolv.conf'),
('/media/fat/linux/dhcpd.conf', '/etc/dhcpd.conf'),
('/media/fat/linux/fstab', '/etc/fstab'),
]

# Reboot files
FILE_downloader_needs_reboot_after_linux_update = '/tmp/downloader_needs_reboot_after_linux_update'
Expand Down
63 changes: 62 additions & 1 deletion src/downloader/linux_updater.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
import subprocess
import json
import sys
from downloader.constants import FILE_downloader_needs_reboot_after_linux_update, FILE_MiSTer_version, FILE_Linux_7z
import tempfile
import os.path
from downloader.constants import FILE_downloader_needs_reboot_after_linux_update, FILE_MiSTer_version, FILE_Linux_7z, FILE_Linux_user_files


class LinuxUpdater:
Expand All @@ -29,6 +31,7 @@ def __init__(self, config, file_system, file_downloader_factory, logger):
self._logger = logger
self._file_system = file_system
self._linux_descriptions = []
self._user_files = []

def update_linux(self, importer_command):
self._logger.bench('Update Linux start.')
Expand Down Expand Up @@ -68,6 +71,11 @@ def _update_linux_impl(self, importer_command):
self._logger.debug('current_linux_version "%s" matches db linux: %s' % (current_linux_version, linux['version']))
return

for source, destination in FILE_Linux_user_files:
if self._file_system.is_file(source):
self._logger.print('Custom "%s" file will be installed to the updated Linux system from the "linux" folder.' % (os.path.basename(source)))
self._user_files.append((source, destination))

self._logger.print('Linux will be updated from %s:' % description['id'])
self._logger.print('Current linux version -> %s' % current_linux_version)
self._logger.print('Latest linux version -> %s' % linux['version'][-6:])
Expand Down Expand Up @@ -148,6 +156,11 @@ def _run_subprocesses(self, linux, linux_path):
self._logger.print()
return

if len(self._user_files) > 0:
restore_error = self._restore_user_files()
if restore_error:
return

self._logger.print()
self._logger.print("======================================================================================")
self._logger.print("Hold your breath: updating the Kernel, the Linux filesystem, the bootloader and stuff.")
Expand Down Expand Up @@ -179,5 +192,53 @@ def _run_subprocesses(self, linux, linux_path):
self._logger.print('Error code: %d' % result.returncode)
self._logger.print()

def _restore_user_files(self) -> bool:
temp_dir = tempfile.mkdtemp()
self._logger.debug('Created temporary directory for image: %s' % temp_dir)

mount_cmd = 'mount -t ext4 /media/fat/linux.update/files/linux/linux.img {0}'.format(temp_dir)
self._logger.debug('Mounting temporary Linux image with command: %s' % mount_cmd)
result = subprocess.run(mount_cmd, shell=True, stderr=subprocess.STDOUT)

if result.returncode != 0:
self._logger.print('ERROR! Could not mount updated Linux image, try again later.')
self._logger.print('Error code: %d' % result.returncode)
self._logger.print()
return False

copy_error = False
self._logger.print('Restoring user Linux configuration files:')
for source, destination in self._user_files:
image_destination = temp_dir + destination
self._logger.debug('Copying "%s" to "%s"' % (source, image_destination))
self._logger.print(' - Installing "%s" to "%s"...' % (source, destination), end='')
try:
self._file_system.copy(source, image_destination)
except Exception as e:
self._logger.print('ERROR! Could not be installed.')
self._logger.debug('Could not copy "%s" to "%s": %s' % (source, destination, str(e)))
copy_error = True
break
else:
self._logger.print('OK!')
self._logger.print()

unmount_cmd = 'umount {0}'.format(temp_dir)
self._logger.debug('Unmounting Linux image with command: %s' % unmount_cmd)
result = subprocess.run(unmount_cmd, shell=True, stderr=subprocess.STDOUT)

if result.returncode != 0:
self._logger.print('ERROR! Could not unmount updated temporary Linux image.')
self._logger.print('Error code: %d' % result.returncode)
self._logger.print()
return False

if copy_error:
self._logger.print('ERROR! Could not restore user Linux configuration files.')
self._logger.print()
return False

return True

def needs_reboot(self):
return self._file_system.is_file(FILE_downloader_needs_reboot_after_linux_update)

0 comments on commit 2c1511b

Please sign in to comment.