summaryrefslogtreecommitdiff
path: root/src/system/grub_update.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/system/grub_update.py')
-rw-r--r--src/system/grub_update.py104
1 files changed, 104 insertions, 0 deletions
diff --git a/src/system/grub_update.py b/src/system/grub_update.py
new file mode 100644
index 000000000..366a85344
--- /dev/null
+++ b/src/system/grub_update.py
@@ -0,0 +1,104 @@
+#!/usr/bin/env python3
+#
+# Copyright 2023 VyOS maintainers and contributors <maintainers@vyos.io>
+#
+# This file is part of VyOS.
+#
+# VyOS is free software: you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation, either version 3 of the License, or (at your option) any later
+# version.
+#
+# VyOS is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# VyOS. If not, see <https://www.gnu.org/licenses/>.
+
+from pathlib import Path
+from sys import exit
+
+from vyos.system import disk, grub, image, compat, SYSTEM_CFG_VER
+from vyos.template import render
+
+
+def cfg_check_update() -> bool:
+ """Check if GRUB structure update is required
+
+ Returns:
+ bool: False if not required, True if required
+ """
+ current_ver = grub.get_cfg_ver()
+ if current_ver and current_ver >= SYSTEM_CFG_VER:
+ return False
+
+ return True
+
+
+if __name__ == '__main__':
+ if image.is_live_boot():
+ exit(0)
+
+ # Skip everything if update is not required
+ if not cfg_check_update():
+ exit(0)
+
+ # find root directory of persistent storage
+ root_dir = disk.find_persistence()
+
+ # read current GRUB config
+ grub_cfg_main = f'{root_dir}/{grub.GRUB_CFG_MAIN}'
+ vars = grub.vars_read(grub_cfg_main)
+ modules = grub.modules_read(grub_cfg_main)
+ vyos_menuentries = compat.parse_menuentries(grub_cfg_main)
+ vyos_versions = compat.find_versions(vyos_menuentries)
+ unparsed_items = compat.filter_unparsed(grub_cfg_main)
+ # compatibilty for raid installs
+ search_root = compat.get_search_root(unparsed_items)
+ common_dict = {}
+ common_dict['search_root'] = search_root
+ # find default values
+ default_entry = vyos_menuentries[int(vars['default'])]
+ default_settings = {
+ 'default': grub.gen_version_uuid(default_entry['version']),
+ 'bootmode': default_entry['bootmode'],
+ 'console_type': default_entry['console_type'],
+ 'console_num': default_entry['console_num']
+ }
+ vars.update(default_settings)
+
+ # create new files
+ grub_cfg_vars = f'{root_dir}/{grub.CFG_VYOS_VARS}'
+ grub_cfg_modules = f'{root_dir}/{grub.CFG_VYOS_MODULES}'
+ grub_cfg_platform = f'{root_dir}/{grub.CFG_VYOS_PLATFORM}'
+ grub_cfg_menu = f'{root_dir}/{grub.CFG_VYOS_MENU}'
+ grub_cfg_options = f'{root_dir}/{grub.CFG_VYOS_OPTIONS}'
+
+ Path(image.GRUB_DIR_VYOS).mkdir(exist_ok=True)
+ grub.vars_write(grub_cfg_vars, vars)
+ grub.modules_write(grub_cfg_modules, modules)
+ grub.common_write(grub_common=common_dict)
+ render(grub_cfg_menu, grub.TMPL_GRUB_MENU, {})
+ render(grub_cfg_options, grub.TMPL_GRUB_OPTS, {})
+
+ # create menu entries
+ for vyos_ver in vyos_versions:
+ boot_opts = None
+ for entry in vyos_menuentries:
+ if entry.get('version') == vyos_ver and entry.get(
+ 'bootmode') == 'normal':
+ boot_opts = entry.get('boot_opts')
+ grub.version_add(vyos_ver, root_dir, boot_opts)
+
+ # update structure version
+ cfg_ver = compat.update_cfg_ver(root_dir)
+ grub.write_cfg_ver(cfg_ver, root_dir)
+
+ if compat.mode():
+ compat.render_grub_cfg(root_dir)
+ else:
+ render(grub_cfg_main, grub.TMPL_GRUB_MAIN, {})
+
+ exit(0)