mirror of
https://github.com/Telecominfraproject/OpenNetworkLinux.git
synced 2025-12-25 17:27:01 +00:00
Merge pull request #127 from carlroth/roth_swl_3426
Restore boot loader config on loader upgrade, see SWL-3426
This commit is contained in:
@@ -17,31 +17,9 @@ import time
|
||||
from InstallUtils import InitrdContext
|
||||
from InstallUtils import SubprocessMixin
|
||||
from InstallUtils import ProcMountsParser
|
||||
from ShellApp import Onie
|
||||
from ShellApp import OnieBootContext
|
||||
import ConfUtils, BaseInstall
|
||||
|
||||
class OnieHelper(Onie):
|
||||
"""Unpack the initrd, but keep it around."""
|
||||
|
||||
UMOUNT = False
|
||||
# leave self.onieDir mounted
|
||||
|
||||
ictx = None
|
||||
|
||||
def _runInitrdShell(self, initrd):
|
||||
with InitrdContext(initrd, log=self.log) as self.ictx:
|
||||
self.initrdDir = self.ictx.dir
|
||||
self.ictx.detach()
|
||||
|
||||
def shutdown(self):
|
||||
|
||||
self.ictx.attach()
|
||||
self.ictx.shutdown()
|
||||
|
||||
if self.dctx is not None:
|
||||
self.dctx.attach()
|
||||
self.dctx.shutdown()
|
||||
|
||||
class App(SubprocessMixin, object):
|
||||
|
||||
def __init__(self, url=None,
|
||||
@@ -66,7 +44,7 @@ class App(SubprocessMixin, object):
|
||||
|
||||
self.nextUpdate = None
|
||||
|
||||
self.onieHelper = None
|
||||
self.octx = None
|
||||
|
||||
def run(self):
|
||||
|
||||
@@ -160,15 +138,13 @@ class App(SubprocessMixin, object):
|
||||
##self.log.info("using native GRUB")
|
||||
##self.grubEnv = ConfUtils.GrubEnv(log=self.log.getChild("grub"))
|
||||
|
||||
self.onieHelper = OnieHelper(log=self.log)
|
||||
code = self.onieHelper.run()
|
||||
if code:
|
||||
self.log.warn("cannot find ONIE initrd")
|
||||
with OnieBootContext(log=self.log) as self.octx:
|
||||
self.octx.detach()
|
||||
|
||||
if self.onieHelper.onieDir is not None:
|
||||
self.log.info("using native ONIE initrd+chroot GRUB (%s)", self.onieHelper.onieDir)
|
||||
self.grubEnv = ConfUtils.ChrootGrubEnv(self.onieHelper.initrdDir,
|
||||
bootDir=self.onieHelper.onieDir,
|
||||
if self.octx.onieDir is not None:
|
||||
self.log.info("using native ONIE initrd+chroot GRUB (%s)", self.octx.onieDir)
|
||||
self.grubEnv = ConfUtils.ChrootGrubEnv(self.octx.initrdDir,
|
||||
bootDir=self.octx.onieDir,
|
||||
path="/grub/grubenv",
|
||||
log=self.log.getChild("grub"))
|
||||
# direct access using ONIE initrd as a chroot
|
||||
@@ -340,9 +316,10 @@ class App(SubprocessMixin, object):
|
||||
if installer is not None:
|
||||
installer.shutdown()
|
||||
|
||||
h, self.onieHelper = self.onieHelper, None
|
||||
if h is not None:
|
||||
h.shutdown()
|
||||
ctx, self.octx = self.octx, None
|
||||
if ctx:
|
||||
ctx.attach()
|
||||
ctx.shutdown()
|
||||
|
||||
def post_mortem(self):
|
||||
self.log.info("re-attaching to tty")
|
||||
|
||||
@@ -92,6 +92,10 @@ class Base:
|
||||
self.log.error("not implemented")
|
||||
return 1
|
||||
|
||||
def upgradeBootLoader(self):
|
||||
self.log.error("not implemented")
|
||||
return 1
|
||||
|
||||
def shutdown(self):
|
||||
zf, self.zf = self.zf, None
|
||||
if zf: zf.close()
|
||||
@@ -524,19 +528,7 @@ class GrubInstaller(SubprocessMixin, Base):
|
||||
|
||||
def installLoader(self):
|
||||
|
||||
ctx = {}
|
||||
|
||||
kernel = self.im.platformConf['grub']['kernel']
|
||||
ctx['kernel'] = kernel['='] if type(kernel) == dict else kernel
|
||||
ctx['args'] = self.im.platformConf['grub']['args']
|
||||
ctx['platform'] = self.im.installerConf.installer_platform
|
||||
ctx['serial'] = self.im.platformConf['grub']['serial']
|
||||
|
||||
ctx['boot_menu_entry'] = sysconfig.installer.menu_name
|
||||
ctx['boot_loading_name'] = sysconfig.installer.os_name
|
||||
|
||||
kernels = []
|
||||
|
||||
for f in set(os.listdir(self.im.installerConf.installer_dir) + self.zf.namelist()):
|
||||
if 'kernel' in f:
|
||||
kernels.append(f)
|
||||
@@ -548,11 +540,10 @@ class GrubInstaller(SubprocessMixin, Base):
|
||||
initrd = i
|
||||
break
|
||||
|
||||
cf = GRUB_TPL % ctx
|
||||
|
||||
self.log.info("Installing kernel")
|
||||
dev = self.blkidParts['ONL-BOOT']
|
||||
|
||||
self.log.info("Installing kernel to %s", dev.device)
|
||||
|
||||
with MountContext(dev.device, log=self.log) as ctx:
|
||||
def _cp(b, dstname=None):
|
||||
if dstname is None:
|
||||
@@ -561,8 +552,32 @@ class GrubInstaller(SubprocessMixin, Base):
|
||||
self.installerCopy(b, dst, optional=True)
|
||||
[_cp(e) for e in kernels]
|
||||
_cp(initrd, "%s.cpio.gz" % self.im.installerConf.installer_platform)
|
||||
|
||||
return 0
|
||||
|
||||
def installGrubCfg(self):
|
||||
|
||||
dev = self.blkidParts['ONL-BOOT']
|
||||
|
||||
self.log.info("Installing grub.cfg to %s", dev.device)
|
||||
|
||||
ctx = {}
|
||||
|
||||
kernel = self.im.platformConf['grub']['kernel']
|
||||
ctx['kernel'] = kernel['='] if type(kernel) == dict else kernel
|
||||
ctx['args'] = self.im.platformConf['grub']['args']
|
||||
ctx['platform'] = self.im.installerConf.installer_platform
|
||||
ctx['serial'] = self.im.platformConf['grub']['serial']
|
||||
|
||||
ctx['boot_menu_entry'] = sysconfig.installer.menu_name
|
||||
ctx['boot_loading_name'] = sysconfig.installer.os_name
|
||||
|
||||
cf = GRUB_TPL % ctx
|
||||
|
||||
with MountContext(dev.device, log=self.log) as ctx:
|
||||
d = os.path.join(ctx.dir, "grub")
|
||||
self.makedirs(d)
|
||||
if not os.path.exists(d):
|
||||
self.makedirs(d)
|
||||
dst = os.path.join(ctx.dir, 'grub/grub.cfg')
|
||||
with open(dst, "w") as fd:
|
||||
fd.write(cf)
|
||||
@@ -624,6 +639,9 @@ class GrubInstaller(SubprocessMixin, Base):
|
||||
code = self.installLoader()
|
||||
if code: return code
|
||||
|
||||
code = self.installGrubCfg()
|
||||
if code: return code
|
||||
|
||||
code = self.installBootConfig()
|
||||
if code: return code
|
||||
|
||||
@@ -648,6 +666,16 @@ class GrubInstaller(SubprocessMixin, Base):
|
||||
return 1
|
||||
return self.installGpt()
|
||||
|
||||
def upgradeBootLoader(self):
|
||||
"""Upgrade the boot loader settings."""
|
||||
|
||||
self.blkidParts = BlkidParser(log=self.log.getChild("blkid"))
|
||||
|
||||
code = self.installGrubCfg()
|
||||
if code: return code
|
||||
|
||||
return 0
|
||||
|
||||
def shutdown(self):
|
||||
Base.shutdown(self)
|
||||
|
||||
@@ -883,5 +911,17 @@ class UbootInstaller(SubprocessMixin, Base):
|
||||
|
||||
return self.installUboot()
|
||||
|
||||
def upgradeBootLoader(self):
|
||||
"""Upgrade the boot loader settings as part of a loader upgrade."""
|
||||
|
||||
self.blkidParts = BlkidParser(log=self.log.getChild("blkid"))
|
||||
|
||||
# XXX boot-config (and saved boot-config) should be unchanged during loader upgrade
|
||||
|
||||
code = self.installUbootEnv()
|
||||
if code: return code
|
||||
|
||||
return 0
|
||||
|
||||
def shutdown(self):
|
||||
Base.shutdown(self)
|
||||
|
||||
@@ -10,6 +10,8 @@ import tempfile
|
||||
import string
|
||||
import shutil
|
||||
|
||||
import Fit
|
||||
|
||||
class SubprocessMixin:
|
||||
|
||||
V1 = "V1"
|
||||
@@ -229,8 +231,8 @@ class MountContext(SubprocessMixin):
|
||||
self.label = label
|
||||
self.fsType = fsType
|
||||
self.dir = None
|
||||
self.hostDir = None
|
||||
self.mounted = False
|
||||
self.hostDir = self.__hostDir = None
|
||||
self.mounted = self.__mounted = False
|
||||
self.log = log or logging.getLogger("mount")
|
||||
|
||||
if self.device and self.label:
|
||||
@@ -238,9 +240,6 @@ class MountContext(SubprocessMixin):
|
||||
if not self.device and not self.label:
|
||||
raise ValueError("no device or label specified")
|
||||
|
||||
self._detachMounted = False
|
||||
self._detachHostDir = None
|
||||
|
||||
def __enter__(self):
|
||||
dev = self.device
|
||||
if dev is None:
|
||||
@@ -290,12 +289,12 @@ class MountContext(SubprocessMixin):
|
||||
return False
|
||||
|
||||
def detach(self):
|
||||
self.mounted, self._detachMounted = False, self.mounted
|
||||
self.hostDir, self._detachHostdir = None, self.hostDir
|
||||
self.__mounted, self.mounted = self.mounted, False
|
||||
self.__hostDir, self.hostDir = self.hostDir, None
|
||||
|
||||
def attach(self):
|
||||
self.mounted = self._detachMounted
|
||||
self.hostDir = self._detachHostdir
|
||||
self.mounted = self.__mounted
|
||||
self.hostDir = self.__hostDir
|
||||
|
||||
class BlkidEntry:
|
||||
|
||||
@@ -697,8 +696,9 @@ class InitrdContext(SubprocessMixin):
|
||||
self.ilog.setLevel(logging.INFO)
|
||||
self.log = self.hlog
|
||||
|
||||
self.__initrd = None
|
||||
self.__dir = None
|
||||
self._hasDevTmpfs = False
|
||||
self._detachInitrd = None
|
||||
|
||||
def _unpack(self):
|
||||
self.dir = self.mkdtemp(prefix="chroot-",
|
||||
@@ -837,21 +837,25 @@ class InitrdContext(SubprocessMixin):
|
||||
def shutdown(self):
|
||||
|
||||
p = ProcMountsParser()
|
||||
dirs = [e.dir for e in p.mounts if e.dir.startswith(self.dir)]
|
||||
if self.dir is not None:
|
||||
dirs = [e.dir for e in p.mounts if e.dir.startswith(self.dir)]
|
||||
else:
|
||||
dirs = []
|
||||
|
||||
# XXX probabaly also kill files here
|
||||
|
||||
# umount any nested mounts
|
||||
self.log.debug("un-mounting mounts points in chroot %s", self.dir)
|
||||
dirs.sort(reverse=True)
|
||||
for p in dirs:
|
||||
cmd = ('umount', p,)
|
||||
self.check_call(cmd, vmode=self.V1)
|
||||
if dirs:
|
||||
self.log.debug("un-mounting mounts points in chroot %s", self.dir)
|
||||
dirs.sort(reverse=True)
|
||||
for p in dirs:
|
||||
cmd = ('umount', p,)
|
||||
self.check_call(cmd, vmode=self.V1)
|
||||
|
||||
if self.initrd is not None:
|
||||
if self.initrd and self.dir:
|
||||
self.log.debug("cleaning up chroot in %s", self.dir)
|
||||
self.rmtree(self.dir)
|
||||
else:
|
||||
elif self.dir:
|
||||
self.log.debug("saving chroot in %s", self.dir)
|
||||
|
||||
def __exit__(self, type, value, tb):
|
||||
@@ -859,10 +863,12 @@ class InitrdContext(SubprocessMixin):
|
||||
return False
|
||||
|
||||
def detach(self):
|
||||
self.initrd, self._detachInitrd = None, self.initrd
|
||||
self.__initrd, self.initrd = self.initrd, None
|
||||
self.__dir, self.dir = self.dir, None
|
||||
|
||||
def attach(self):
|
||||
self.initrd = self._detachInitrd
|
||||
self.initrd = self.__initrd
|
||||
self.dir = self.__dir
|
||||
|
||||
@classmethod
|
||||
def mkChroot(cls, initrd, log=None):
|
||||
@@ -873,6 +879,51 @@ class InitrdContext(SubprocessMixin):
|
||||
# (it's inside this chroot anyway)
|
||||
return initrdDir
|
||||
|
||||
class FitInitrdContext(SubprocessMixin):
|
||||
|
||||
def __init__(self, path, log=None):
|
||||
self.fitPath = path
|
||||
self.log = log or logging.getLogger(self.__class__.__name__)
|
||||
self.initrd = self.__initrd = None
|
||||
|
||||
def __enter__(self):
|
||||
self.log.debug("parsing FIT image in %s", self.fitPath)
|
||||
p = Fit.Parser(path=self.fitPath, log=self.log)
|
||||
node = p.getInitrdNode()
|
||||
if node is None:
|
||||
raise ValueError("cannot find initrd node in FDT")
|
||||
prop = node.properties.get('data', None)
|
||||
if prop is None:
|
||||
raise ValueError("cannot find initrd data property in FDT")
|
||||
|
||||
with open(self.fitPath) as fd:
|
||||
self.log.debug("reading initrd at [%x:%x]",
|
||||
prop.offset, prop.offset+prop.sz)
|
||||
fd.seek(prop.offset, 0)
|
||||
buf = fd.read(prop.sz)
|
||||
|
||||
fno, self.initrd = tempfile.mkstemp(prefix="initrd-",
|
||||
suffix=".img")
|
||||
self.log.debug("+ cat > %s", self.initrd)
|
||||
with os.fdopen(fno, "w") as fd:
|
||||
fd.write(buf)
|
||||
return self
|
||||
|
||||
def shutdown(self):
|
||||
initrd, self.initrd = self.initrd, None
|
||||
if initrd and os.path.exists(initrd):
|
||||
self.unlink(initrd)
|
||||
|
||||
def __exit__(self, eType, eValue, eTrace):
|
||||
self.shutdown()
|
||||
return False
|
||||
|
||||
def detach(self):
|
||||
self.__initrd, self.initrd = self.initrd, None
|
||||
|
||||
def attach(self):
|
||||
self.initrd = self.__initrd
|
||||
|
||||
class ChrootSubprocessMixin:
|
||||
|
||||
chrootDir = None
|
||||
|
||||
@@ -13,7 +13,7 @@ from InstallUtils import InitrdContext, MountContext
|
||||
from InstallUtils import SubprocessMixin
|
||||
from InstallUtils import ProcMountsParser, ProcMtdParser
|
||||
from InstallUtils import BlkidParser
|
||||
import Fit
|
||||
from InstallUtils import FitInitrdContext
|
||||
|
||||
import onl.platform.current
|
||||
from onl.sysconfig import sysconfig
|
||||
@@ -47,30 +47,8 @@ class AppBase(SubprocessMixin, object):
|
||||
return 0
|
||||
|
||||
def _runFitShell(self, device):
|
||||
self.log.debug("parsing FIT image in %s", device)
|
||||
p = Fit.Parser(path=device, log=self.log)
|
||||
node = p.getInitrdNode()
|
||||
if node is None:
|
||||
self.log.error("cannot find initrd node in FDT")
|
||||
return 1
|
||||
prop = node.properties.get('data', None)
|
||||
if prop is None:
|
||||
self.log.error("cannot find initrd data property in FDT")
|
||||
return 1
|
||||
with open(device) as fd:
|
||||
self.log.debug("reading initrd at [%x:%x]",
|
||||
prop.offset, prop.offset+prop.sz)
|
||||
fd.seek(prop.offset, 0)
|
||||
buf = fd.read(prop.sz)
|
||||
try:
|
||||
fno, initrd = tempfile.mkstemp(prefix="initrd-",
|
||||
suffix=".img")
|
||||
self.log.debug("+ cat > %s", initrd)
|
||||
with os.fdopen(fno, "w") as fd:
|
||||
fd.write(buf)
|
||||
return self._runInitrdShell(initrd)
|
||||
finally:
|
||||
self.unlink(initrd)
|
||||
with FitInitrdContext(path=device, log=self.log) as ctx:
|
||||
return self._runInitrdShell(ctx.initrd)
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
@@ -109,21 +87,26 @@ class AppBase(SubprocessMixin, object):
|
||||
app.shutdown()
|
||||
sys.exit(code)
|
||||
|
||||
class Onie(AppBase):
|
||||
"""Application shell that uses the ONIE runtime."""
|
||||
class OnieBootContext:
|
||||
"""Find the ONIE initrd and umpack/mount it."""
|
||||
|
||||
PROG = "onie-shell"
|
||||
def __init__(self, log=None):
|
||||
self.log = log or logging.getLogger(self.__class__.__name__)
|
||||
|
||||
UNMOUNT = True
|
||||
# default, unmount directories once the initrd is extracted
|
||||
self.initrd = None
|
||||
|
||||
def run(self):
|
||||
self.pm = self.blkid = self.mtd = None
|
||||
self.ictx = self.dctx = self.fctx = None
|
||||
self.onieDir = None
|
||||
self.initrdDir = None
|
||||
|
||||
self.__ictx = self.__dctx = self.__fctx = None
|
||||
|
||||
def __enter__(self):
|
||||
|
||||
self.pm = ProcMountsParser()
|
||||
self.blkid = BlkidParser(log=self.log.getChild("blkid"))
|
||||
self.mtd = ProcMtdParser(log=self.log.getChild("mtd"))
|
||||
self.dctx = None
|
||||
self.onieDir = None
|
||||
|
||||
def _g(d):
|
||||
pat = os.path.join(d, "onie/initrd.img*")
|
||||
@@ -144,28 +127,29 @@ class Onie(AppBase):
|
||||
self.log.debug("found ONIE boot mounted at %s", parts[0].dir)
|
||||
initrd = _g(parts[0].dir)
|
||||
if initrd is None:
|
||||
self.log.warn("cannot find ONIE initrd on %s", parts[0].dir)
|
||||
else:
|
||||
self.onieDir = parts[0].dir
|
||||
self.log.debug("found ONIE initrd at %s", initrd)
|
||||
return self._runInitrdShell(initrd)
|
||||
raise ValueError("cannot find ONIE initrd on %s" % parts[0].dir)
|
||||
self.log.debug("found ONIE initrd at %s", initrd)
|
||||
with InitrdContext(initrd=initrd, log=self.log) as self.ictx:
|
||||
self.initrd = initrd
|
||||
self.initrdDir = self.ictx.dir
|
||||
self.ictx.detach()
|
||||
return self
|
||||
|
||||
# else, try to mount the directory containing the initrd
|
||||
with MountContext(dev, log=self.log) as self.dctx:
|
||||
initrd = _g(self.dctx.dir)
|
||||
if initrd is None:
|
||||
self.log.warn("cannot find ONIE initrd on %s", dev)
|
||||
else:
|
||||
self.log.debug("found ONIE initrd at %s", initrd)
|
||||
try:
|
||||
return self._runInitrdShell(initrd)
|
||||
finally:
|
||||
if not self.UMOUNT:
|
||||
self.onieDir = self.dctx.hostDir
|
||||
self.dctx.detach()
|
||||
raise ValueError("cannot find ONIE initrd on %s" % dev)
|
||||
self.onieDir = self.dctx.dir
|
||||
self.dctx.detach()
|
||||
self.log.debug("found ONIE initrd at %s", initrd)
|
||||
with InitrdContext(initrd=initrd, log=self.log) as self.ictx:
|
||||
self.initrd = initrd
|
||||
self.initrdDir = self.ictx.dir
|
||||
self.ictx.detach()
|
||||
return self
|
||||
|
||||
self.log.warn("cannot find an ONIE initrd")
|
||||
return 1
|
||||
raise ValueError("cannot find an ONIE initrd")
|
||||
|
||||
# try to find onie initrd on a mounted fs (GRUB);
|
||||
# for ONIE images this is usually /mnt/onie-boot
|
||||
@@ -178,7 +162,11 @@ class Onie(AppBase):
|
||||
else:
|
||||
self.onieDir = part.dir
|
||||
self.log.debug("found ONIE initrd at %s", initrd)
|
||||
return self._runInitrdShell(initrd)
|
||||
with InitrdContext(initrd=initrd, log=self.log) as self.ictx:
|
||||
self.initrd = initrd
|
||||
self.initrdDir = self.ictx.dir
|
||||
self.ictx.detach()
|
||||
return self
|
||||
|
||||
# grovel through MTD devices (u-boot)
|
||||
parts = [p for p in self.mtd.parts if p.label == "onie"]
|
||||
@@ -186,13 +174,49 @@ class Onie(AppBase):
|
||||
part = parts[0]
|
||||
self.log.debug("found ONIE MTD device %s",
|
||||
part.charDevice or part.blockDevice)
|
||||
return self._runFitShell(part.blockDevice)
|
||||
elif self.mtd.mounts:
|
||||
self.log.error("cannot find ONIE MTD device")
|
||||
return 1
|
||||
with FitInitrdContext(part.blockDevice, log=self.log) as self.fctx:
|
||||
with InitrdContext(initrd=self.fctx.initrd, log=self.log) as self.ictx:
|
||||
self.initrd = self.fctx.initrd
|
||||
self.fctx.detach()
|
||||
self.initrdDir = self.ictx.dir
|
||||
self.ictx.detach()
|
||||
return self
|
||||
|
||||
self.log.error("cannot find ONIE initrd")
|
||||
return 1
|
||||
if self.mtd.mounts:
|
||||
raise ValueError("cannot find ONIE MTD device")
|
||||
|
||||
raise ValueError("cannot find ONIE initrd")
|
||||
|
||||
def shutdown(self):
|
||||
ctx, self.fctx = self.fctx, None
|
||||
if ctx is not None: ctx.shutdown()
|
||||
ctx, self.ictx = self.ictx, None
|
||||
if ctx is not None: ctx.shutdown()
|
||||
ctx, self.dctx = self.dctx, None
|
||||
if ctx is not None: ctx.shutdown()
|
||||
|
||||
def __exit__(self, eType, eValue, eTrace):
|
||||
self.shutdown()
|
||||
return False
|
||||
|
||||
def detach(self):
|
||||
self.__fctx, self.fctx = self.fctx, None
|
||||
self.__ictx, self.ictx = self.ictx, None
|
||||
self.__dctx, self.dctx = self.dctx, None
|
||||
|
||||
def attach(self):
|
||||
self.fctx = self.__fctx
|
||||
self.ictx = self.__ictx
|
||||
self.dctx = self.__dctx
|
||||
|
||||
class Onie(AppBase):
|
||||
"""XXX roth -- refactor in from loader.py code."""
|
||||
|
||||
PROG = "onie-shell"
|
||||
|
||||
def run(self):
|
||||
with OnieBootContext(log=self.log) as ctx:
|
||||
return self._runInitrdShell(ctx.initrd)
|
||||
|
||||
class Loader(AppBase):
|
||||
"""Application shell that uses the (installed) loader runtime."""
|
||||
|
||||
@@ -16,7 +16,7 @@ import subprocess
|
||||
from onl.install.InstallUtils import InitrdContext
|
||||
from onl.install.InstallUtils import ProcMountsParser
|
||||
from onl.install.ConfUtils import MachineConf, InstallerConf
|
||||
from onl.install.ShellApp import Onie, Upgrader
|
||||
from onl.install.ShellApp import OnieBootContext, Upgrader
|
||||
from onl.install.InstallUtils import SubprocessMixin
|
||||
import onl.install.App
|
||||
|
||||
@@ -45,8 +45,6 @@ class App(SubprocessMixin):
|
||||
|
||||
self.force = force
|
||||
|
||||
self.onieHelper = None
|
||||
|
||||
def _runInitrd(self, helper, path):
|
||||
with InitrdContext(initrd=path, log=self.log) as ctx:
|
||||
|
||||
@@ -55,22 +53,14 @@ class App(SubprocessMixin):
|
||||
prefix="installer-", suffix=".d")
|
||||
chroot_idir = abs_idir[len(ctx.dir):]
|
||||
|
||||
self.onieHelper = onl.install.App.OnieHelper(log=self.log)
|
||||
code = self.onieHelper.run()
|
||||
if code:
|
||||
self.log.error("cannot find/unpack ONIE initrd")
|
||||
return code
|
||||
self.log.info("onie directory is %s", self.onieHelper.onieDir)
|
||||
self.log.info("initrd directory is %s", self.onieHelper.initrdDir)
|
||||
with OnieBootContext(log=self.log) as octx:
|
||||
self.log.info("onie directory is %s", octx.onieDir)
|
||||
self.log.info("initrd directory is %s", octx.initrdDir)
|
||||
|
||||
src = os.path.join(self.onieHelper.initrdDir, "etc/machine.conf")
|
||||
dst = os.path.join(ctx.dir, "etc/machine.conf")
|
||||
self.log.debug("+ /bin/cp %s %s", src, dst)
|
||||
shutil.copy2(src, dst)
|
||||
|
||||
h, self.onieHelper = self.onieHelper, None
|
||||
if h is not None:
|
||||
h.shutdown()
|
||||
src = os.path.join(octx.initrdDir, "etc/machine.conf")
|
||||
dst = os.path.join(ctx.dir, "etc/machine.conf")
|
||||
self.log.debug("+ /bin/cp %s %s", src, dst)
|
||||
shutil.copy2(src, dst)
|
||||
|
||||
src = "/etc/fw_env.config"
|
||||
if os.path.exists(src):
|
||||
@@ -221,10 +211,7 @@ class App(SubprocessMixin):
|
||||
return code
|
||||
|
||||
def shutdown(self):
|
||||
|
||||
h, self.onieHelper = self.onieHelper, None
|
||||
if h is not None:
|
||||
h.shutdown()
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def main(cls):
|
||||
|
||||
@@ -11,6 +11,10 @@ import fnmatch
|
||||
from onl.upgrade import ubase
|
||||
from onl.sysconfig import sysconfig
|
||||
from onl.mounts import OnlMountManager, OnlMountContextReadOnly, OnlMountContextReadWrite
|
||||
from onl.install import BaseInstall, ConfUtils, InstallUtils
|
||||
from onl.install.ShellApp import OnieBootContext
|
||||
import onl.platform.current
|
||||
import onl.versions
|
||||
|
||||
class LoaderUpgradeBase(ubase.BaseUpgrade):
|
||||
name="loader"
|
||||
@@ -57,9 +61,10 @@ class LoaderUpgradeBase(ubase.BaseUpgrade):
|
||||
* A single reboot will be required to complete this upgrade.
|
||||
"""
|
||||
|
||||
|
||||
class LoaderUpgrade_Fit(LoaderUpgradeBase):
|
||||
|
||||
installer_klass = BaseInstall.UbootInstaller
|
||||
|
||||
def do_upgrade(self, forced=False):
|
||||
|
||||
fit_image = None
|
||||
@@ -75,10 +80,49 @@ class LoaderUpgrade_Fit(LoaderUpgradeBase):
|
||||
with OnlMountContextReadWrite("ONL-BOOT", self.logger) as d:
|
||||
self.copyfile(fit_image, os.path.join(d.directory, "%s.itb" % (self.platform.platform())))
|
||||
|
||||
onlPlatform = onl.platform.current.OnlPlatform()
|
||||
|
||||
with OnieBootContext(log=self.logger) as octx:
|
||||
path = os.path.join(octx.initrdDir, "etc/machine.conf")
|
||||
machineConf = ConfUtils.MachineConf(path=path)
|
||||
|
||||
installerConf = ConfUtils.InstallerConf(path="/dev/null")
|
||||
# start with an empty installerConf, fill it in piece by piece
|
||||
|
||||
installerConf.installer_platform = onlPlatform.platform()
|
||||
installerConf.installer_arch = machineConf.onie_arch
|
||||
installerConf.installer_platform_dir = os.path.join("/lib/platform-config",
|
||||
onlPlatform.platform())
|
||||
|
||||
mfPath = os.path.join(sysconfig.upgrade.loader.package.dir, "manifest.json")
|
||||
mf = onl.versions.OnlVersionManifest(mfPath)
|
||||
installerConf.onl_version = mf.RELEASE_ID
|
||||
|
||||
grubEnv = ConfUtils.ProxyGrubEnv(installerConf,
|
||||
bootDir="/mnt/onie-boot",
|
||||
path="/grub/grubenv",
|
||||
chroot=False,
|
||||
log=self.logger.getChild("grub"))
|
||||
|
||||
ubootEnv = ConfUtils.UbootEnv(log=self.logger.getChild("u-boot"))
|
||||
|
||||
installer = self.installer_klass(machineConf=machineConf,
|
||||
installerConf=installerConf,
|
||||
platformConf=onlPlatform.platform_config,
|
||||
grubEnv=grubEnv,
|
||||
ubootEnv=ubootEnv,
|
||||
force=True,
|
||||
log=self.logger)
|
||||
|
||||
installer.upgradeBootLoader()
|
||||
installer.shutdown()
|
||||
|
||||
self.reboot()
|
||||
|
||||
|
||||
class LoaderUpgrade_x86_64(LoaderUpgradeBase):
|
||||
class LoaderUpgrade_x86_64(LoaderUpgradeBase, InstallUtils.SubprocessMixin):
|
||||
|
||||
installer_klass = BaseInstall.GrubInstaller
|
||||
|
||||
def do_upgrade(self, forced=False):
|
||||
|
||||
@@ -110,6 +154,55 @@ class LoaderUpgrade_x86_64(LoaderUpgradeBase):
|
||||
#if os.path.exists(src):
|
||||
# self.copyfile(src, dst)
|
||||
|
||||
# installer assumes that partitions are unmounted
|
||||
|
||||
self.log = self.logger
|
||||
# ha ha, SubprocessMixin api is different
|
||||
|
||||
pm = InstallUtils.ProcMountsParser()
|
||||
for m in pm.mounts:
|
||||
if m.dir.startswith('/mnt/onl'):
|
||||
self.logger.warn("unmounting %s (--force)", m.dir)
|
||||
self.check_call(('umount', m.dir,))
|
||||
|
||||
onlPlatform = onl.platform.current.OnlPlatform()
|
||||
|
||||
with OnieBootContext(log=self.logger) as octx:
|
||||
path = os.path.join(octx.initrdDir, "etc/machine.conf")
|
||||
machineConf = ConfUtils.MachineConf(path=path)
|
||||
|
||||
# hold on to the ONIE boot context for grub access
|
||||
|
||||
installerConf = ConfUtils.InstallerConf(path="/dev/null")
|
||||
|
||||
# XXX fill in installerConf fields
|
||||
installerConf.installer_platform = onlPlatform.platform()
|
||||
installerConf.installer_arch = machineConf.onie_arch
|
||||
installerConf.installer_platform_dir = os.path.join("/lib/platform-config",
|
||||
onlPlatform.platform())
|
||||
|
||||
mfPath = os.path.join(sysconfig.upgrade.loader.package.dir, "manifest.json")
|
||||
mf = onl.versions.OnlVersionManifest(mfPath)
|
||||
installerConf.onl_version = mf.RELEASE_ID
|
||||
|
||||
grubEnv = ConfUtils.ChrootGrubEnv(octx.initrdDir,
|
||||
bootDir=octx.onieDir,
|
||||
path="/grub/grubenv",
|
||||
log=self.logger.getChild("grub"))
|
||||
|
||||
ubootEnv = None
|
||||
|
||||
installer = self.installer_klass(machineConf=machineConf,
|
||||
installerConf=installerConf,
|
||||
platformConf=onlPlatform.platform_config,
|
||||
grubEnv=grubEnv,
|
||||
ubootEnv=ubootEnv,
|
||||
force=True,
|
||||
log=self.logger)
|
||||
|
||||
installer.upgradeBootLoader()
|
||||
installer.shutdown()
|
||||
|
||||
self.reboot()
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user