From 6a97f85532f074032290ce6fba8448df39f825e8 Mon Sep 17 00:00:00 2001 From: Jeffrey Townsend Date: Wed, 19 Oct 2016 21:34:54 +0000 Subject: [PATCH] Onie and Loader infrastructure improvements - Loader and ONIE moved to importable classes for tool usage - OnieUpgradeBase updated. --- .../src/python/onl/upgrade/loader.py | 121 ++++++++++++++++++ .../src/python/onl/upgrade/onie.py | 59 +++++++++ .../src/python/onl/upgrade/ubase.py | 47 +++---- 3 files changed, 204 insertions(+), 23 deletions(-) create mode 100755 packages/base/all/vendor-config-onl/src/python/onl/upgrade/loader.py create mode 100755 packages/base/all/vendor-config-onl/src/python/onl/upgrade/onie.py diff --git a/packages/base/all/vendor-config-onl/src/python/onl/upgrade/loader.py b/packages/base/all/vendor-config-onl/src/python/onl/upgrade/loader.py new file mode 100755 index 00000000..10df045e --- /dev/null +++ b/packages/base/all/vendor-config-onl/src/python/onl/upgrade/loader.py @@ -0,0 +1,121 @@ +#!/usr/bin/python +############################################################ +# +# ONL Loader Upgrade +# +############################################################ +import os +import sys +import fnmatch + +from onl.upgrade import ubase +from onl.sysconfig import sysconfig +from onl.mounts import OnlMountManager, OnlMountContextReadOnly, OnlMountContextReadWrite + +class LoaderUpgradeBase(ubase.BaseUpgrade): + name="loader" + Name="Loader" + title="Loader Upgrade Check" + atype="A Loader" + + current_version_key="Current Loader Version" + next_version_key="Next Loader Version" + + def auto_upgrade_default(self): + return sysconfig.upgrade.loader.auto + + def init_versions(self): + + # + # Current Loader version file. + # If this file doesn't exist then in-place upgrade is not supported. + # + ETC_LOADER_VERSIONS_JSON = sysconfig.upgrade.loader.versions + + # Upgrade Loader Version file. + NEXT_LOADER_VERSIONS_JSON = os.path.join(sysconfig.upgrade.loader.package.dir, "manifest.json") + + + self.current_version = self.load_json(ETC_LOADER_VERSIONS_JSON, + "RELEASE_ID", + None) + + self.next_version = self.load_json(NEXT_LOADER_VERSIONS_JSON, + "version", {}).get('RELEASE_ID', None) + + def summarize(self): + self.logger.info("Current Loader Version: %s" % self.current_version) + self.logger.info(" Next Loader Version: %s" % self.next_version) + self.logger.info("") + + + def upgrade_notes(self): + return """ + * A single reboot will be required to complete this upgrade. +""" + + +class LoaderUpgrade_Fit(LoaderUpgradeBase): + + def do_upgrade(self, forced=False): + + fit_image = None + for f in sysconfig.upgrade.loader.package.fit: + fp = os.path.join(sysconfig.upgrade.loader.package.dir, f) + if os.path.exists(fp): + fit_image = fp; + break + + if fit_image is None: + self.abort("The FIT upgrade image is missing. Upgrade cannot continue.") + + with OnlMountContextReadWrite("ONL-BOOT", self.logger) as d: + self.copyfile(fit_image, os.path.join(d.directory, "%s.itb" % (self.platform.platform()))) + + self.reboot() + + +class LoaderUpgrade_x86_64(LoaderUpgradeBase): + + def do_upgrade(self, forced=False): + + X86_64_UPGRADE_DIR=sysconfig.upgrade.loader.package.dir + X86_64_UPGRADE_KERNEL_PATTERNS = [ "kernel-*" ] + + with OnlMountContextReadWrite("ONL-BOOT", self.logger) as d: + for f in os.listdir(X86_64_UPGRADE_DIR): + for pattern in X86_64_UPGRADE_KERNEL_PATTERNS: + if fnmatch.fnmatch(f, pattern): + self.copyfile(os.path.join(X86_64_UPGRADE_DIR, f), os.path.join(d.directory, f)) + + initrd = None + for c in sysconfig.upgrade.loader.package.grub: + initrd = os.path.join(X86_64_UPGRADE_DIR, c) + if os.path.exists(initrd): + break + else: + initrd = None + + if initrd: + self.copyfile(initrd, os.path.join(d.directory, "%s.cpio.gz" % self.platform.platform())) + else: + self.abort("Initrd is missing. Upgrade cannot continue.") + + # Disabled until it can be resolved with the new installer. + #src = "/lib/platform-config/current/onl/boot/grub.cfg" + #dst = os.path.join(d.directory, "grub/grub.cfg") + #if os.path.exists(src): + # self.copyfile(src, dst) + + self.reboot() + + +import platform +arch = platform.machine() +LoaderUpgrade = None + +if arch in [ 'ppc', 'armv7l', 'aarch64', 'arm64' ]: + LoaderUpgrade = LoaderUpgrade_Fit +elif arch == 'x86_64': + LoaderUpgrade = LoaderUpgrade_x86_64 + diff --git a/packages/base/all/vendor-config-onl/src/python/onl/upgrade/onie.py b/packages/base/all/vendor-config-onl/src/python/onl/upgrade/onie.py new file mode 100755 index 00000000..a4f6beb2 --- /dev/null +++ b/packages/base/all/vendor-config-onl/src/python/onl/upgrade/onie.py @@ -0,0 +1,59 @@ +#!/usr/bin/python -u + +import os +import sys + +from onl.upgrade import ubase +from onl.sysconfig import sysconfig +from onl.mounts import OnlMountManager, OnlMountContextReadOnly, OnlMountContextReadWrite + +class OnieUpgrade(ubase.BaseOnieUpgrade): + + name="onie" + Name="ONIE" + title="ONIE Upgrade Check" + atype="An ONIE" + + current_version_key="Current ONIE Version" + next_version_key="Next ONIE Version" + + def init_versions(self): + + # Get the current platform ONIE version + self.current_version = self.platform.onie_version() + self.next_version = None + self.updater = None + + self.manifest = self.load_json(os.path.join(sysconfig.upgrade.onie.package.dir, "manifest.json")) + + if self.manifest is None: + self.finish("No ONIE updater available for the current platform.") + + if 'onie-version' not in self.manifest: + self.finish("No ONIE version in the upgrade manifest.") + else: + self.next_version = self.manifest['onie-version'] + + if 'onie-updater' not in self.manifest: + self.finish("No ONIE updater in the upgrade manifest.") + + + def summarize(self): + self.logger.info("Current ONIE Version: %s" % self.current_version) + self.logger.info(" Next ONIE Version: %s" % self.manifest.get('onie-version')) + self.logger.info(" Updater: %s" % self.manifest.get('onie-updater')) + self.logger.info("") + + def upgrade_notes(self): + return """ + * The system will reboot into ONIE to complete the update, and then reboot to return to Switch Light +""" + + def do_upgrade(self, forced=False): + self.install_onie_updater(sysconfig.upgrade.onie.package.dir, + self.manifest['onie-updater']) + self.initiate_onie_update() + + def do_no_upgrade(self): + self.clean_onie_updater() + diff --git a/packages/base/all/vendor-config-onl/src/python/onl/upgrade/ubase.py b/packages/base/all/vendor-config-onl/src/python/onl/upgrade/ubase.py index 68f3828f..af2b677d 100644 --- a/packages/base/all/vendor-config-onl/src/python/onl/upgrade/ubase.py +++ b/packages/base/all/vendor-config-onl/src/python/onl/upgrade/ubase.py @@ -15,7 +15,9 @@ import string import argparse import yaml from time import sleep + from onl.platform.current import OnlPlatform +from onl.mounts import OnlMountManager, OnlMountContextReadOnly, OnlMountContextReadWrite class BaseUpgrade(object): @@ -365,19 +367,19 @@ If you choose not to perform this upgrade booting cannot continue.""" % self.aty class BaseOnieUpgrade(BaseUpgrade): - ONIE_UPDATER_PATH = "/mnt/flash2/onie-updater" + ONIE_UPDATER_CONTEXT = "ONL-IMAGES" + ONIE_UPDATER_PATH = "/mnt/onl/images" def install_onie_updater(self, src_dir, updater): - if type(updater) is list: - # Copy all files in the list to /mnt/flash2 + with OnlMountContextReadWrite(self.ONIE_UPDATER_CONTEXT, logger=None): + if type(updater) is not list: + updater = [ updater ] + + # Copy all files in the list to ONIE_UPDATER_PATH for f in updater: src = os.path.join(src_dir, f) - dst = os.path.join("/mnt/flash2", f) + dst = os.path.join(self.ONIE_UPDATER_PATH, f) self.copyfile(src, dst) - else: - # Copy single updater to /mnt/flash2/onie-updater - src = os.path.join(src_dir, updater) - self.copyfile(src, self.ONIE_UPDATER_PATH) def initiate_onie_update(self): @@ -394,27 +396,26 @@ class BaseOnieUpgrade(BaseUpgrade): self.abort("Could not set ONIE Boot Mode to Update. Upgrade cannot continue.") self.umount(OB) - SL = "/mnt/sl-boot" - self.mount(SL, label="SL-BOOT") - with open("/mnt/sl-boot/grub/grub.cfg", "a") as f: - f.write("set default=ONIE\n") - self.umount(SL) + with OnlMountContextReadWrite("ONL-BOOT", logger=None): + with open("/mnt/onl/boot/grub/grub.cfg", "a") as f: + f.write("set default=ONIE\n") self.reboot() else: self.abort("Architecture %s unhandled." % self.arch) def clean_onie_updater(self): - if os.path.exists(self.ONIE_UPDATER_PATH): - self.logger.info("Removing previous onie-updater.") - os.remove(self.ONIE_UPDATER_PATH) + with OnlMountContextReadWrite(self.ONIE_UPDATER_CONTEXT, logger=None): + updater = os.path.join(self.ONIE_UPDATER_PATH, "onie-updater") + if os.path.exists(updater): + self.logger.info("Removing previous onie-updater.") + os.remove(updater) - -def upgrade_status(): - data = {} - if os.path.exists(BaseUpgrade.UPGRADE_STATUS_JSON): - with open(BaseUpgrade.UPGRADE_STATUS_JSON) as f: - data = json.load(f) - return data +# def upgrade_status(): +# data = {} +# if os.path.exists(BaseUpgrade.UPGRADE_STATUS_JSON): +# with open(BaseUpgrade.UPGRADE_STATUS_JSON) as f: +# data = json.load(f) +# return data