Onie and Loader infrastructure improvements

- Loader and ONIE moved to importable classes for tool usage
- OnieUpgradeBase updated.
This commit is contained in:
Jeffrey Townsend
2016-10-19 21:34:54 +00:00
parent a6aba0a15f
commit 6a97f85532
3 changed files with 204 additions and 23 deletions

View File

@@ -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

View File

@@ -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()

View File

@@ -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