示例#1
0
 def recoverUbootConfig(self):
     with MountContext(self.flashDev, log=self.log) as ctx:
         dst = os.path.join(ctx.dir, 'boot-config')
         with open(dst, "w") as fd:
             self.log.debug("+ cat > %s", dst)
             fd.write(self.platform.bootConfigEnv)
     return 0
示例#2
0
    def installBootConfig(self):

        try:
            dev = self.blkidParts['ONL-BOOT']
        except IndexError as ex:
            self.log.warn("cannot find ONL-BOOT partition (maybe raw?) : %s", str(ex))
            return 1

        self.log.info("Installing boot-config to %s", dev.device)

        basename = 'boot-config'
        with MountContext(dev.device, log=self.log) as ctx:
            dst = os.path.join(ctx.dir, basename)

            if not self.installerCopy(basename, dst, True):
                return

            with open(dst) as fd:
                buf = fd.read()

        ecf = buf.encode('base64', 'strict').strip()
        if self.im.grub and self.im.grubEnv is not None:
            setattr(self.im.grubEnv, 'boot_config_default', ecf)
        if self.im.uboot and self.im.ubootEnv is not None:
            setattr(self.im.ubootEnv, 'boot-config-default', ecf)

        return 0
示例#3
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

        if self.isUEFI:
            ctx['onie_boot_uuid'] = self.espFsUuid
        else:
            ctx['onie_boot_uuid'] = ""

        cf = GRUB_TPL % ctx

        with MountContext(dev.device, log=self.log) as ctx:
            d = os.path.join(ctx.dir, "grub")
            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)

        return 0
示例#4
0
    def installLoader(self):

        kernels = []
        for f in set(os.listdir(self.im.installerConf.installer_dir) + self.zf.namelist()):
            if 'kernel' in f:
                kernels.append(f)

        initrd = None
        for f in set(os.listdir(self.im.installerConf.installer_dir) + self.zf.namelist()):
            for i in sysconfig.installer.grub:
                if f == i:
                    initrd = i
                    break

        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:
                    dstname = b
                dst = os.path.join(ctx.dir, dstname)
                self.installerCopy(b, dst, optional=True)
            [_cp(e) for e in kernels]
            _cp(initrd, "%s.cpio.gz" % self.im.installerConf.installer_platform)

        return 0
示例#5
0
    def runGrub(self):

        try:
            dev = self.blkid['ONL-BOOT'].device
        except KeyError:
            pass
        if dev is None:
            self.log.error("cannot find GRUB partition %s", dev)
            return 1

        initrd = self.pc['grub']['initrd']
        if type(initrd) == dict: initrd = initrd['=']

        parts = [p for p in self.pm.mounts if p.device == dev]
        if parts:
            grubDir = parts[0]
            self.log.debug("found loader device %s mounted at %s", dev,
                           grubDir)
            p = os.path.join(grubDir, initrd)
            if not os.path.exists(p):
                self.log.error("cannot find initrd %s", p)
                return 1
            self.log.debug("found loader initrd at %s", p)
            return self._runInitrdShell(p)

        with MountContext(dev, log=self.log) as ctx:
            p = os.path.join(ctx.dir, initrd)
            if not os.path.exists(p):
                self.log.error("cannot find initrd %s:%s", dev, p)
                return 1
            self.log.debug("found loader initrd at %s:%s", dev, p)
            return self._runInitrdShell(p)
示例#6
0
    def installLoader(self):

        loaderBasename = None
        for c in sysconfig.installer.fit:
            if self.installerExists(c):
                loaderBasename = c
                break

        if not loaderBasename:
            self.log.error("The platform loader file is missing.")
            return 1

        self.log.info("Installing the ONL loader from %s...", loaderBasename)

        if self.rawLoaderDevice is not None:
            self.log.info("Installing ONL loader %s --> %s...",
                          loaderBasename, self.rawLoaderDevice)
            self.installerDd(loaderBasename, self.rawLoaderDevice)
            return 0

        dev = self.blkidParts['ONL-BOOT']
        self.log.info("Installing ONL loader %s --> %s:%s...",
                      loaderBasename, dev.device, loaderBasename)
        with MountContext(dev.device, log=self.log) as ctx:
            dst = os.path.join(ctx.dir, "%s.itb" % self.im.installerConf.installer_platform)
            self.installerCopy(loaderBasename, dst)

        return 0
示例#7
0
    def recoverGrubConfig(self):

        with MountContext(label='ONIE-BOOT', log=self.log) as octx:

            pat = "%s/onie/initrd.img*" % octx.dir
            l = glob.glob(pat)
            if not l:
                raise ValueError("cannot find ONIE initrd")
            initrd = l[0]

            with InitrdContext(initrd=initrd, log=self.log) as ictx:

                # copy the Switch Light grubenv out of its GRUB directory
                dst = os.path.join(ictx.dir, "tmp/grubenv")
                with MountContext(label='SL-BOOT', log=self.log) as sctx:
                    src = os.path.join(sctx.dir, "grub/grubenv")
                    self.copy2(src, dst)

                # use the ONIE runtime's GRUB tools to read it
                grubEnv = ChrootGrubEnv(ictx.dir, mounted=True,
                                        bootDir="/",
                                        path="/tmp/grubenv",
                                        log=self.log)
                buf = getattr(grubEnv, 'boot_config_default', None)

        if buf is None:
            raise ValueError("Cannot recover filesystem(s) -- missing boot_config_default.")
        if buf == "":
            raise ValueError("Cannot recover filesystem(s) -- empty boot_config_default.")
        try:
            buf = buf.decode('base64', 'strict')
        except binascii.Error:
            raise ValueError("Cannot recover filesystem(s) -- corrupted boot_config_default.")
        if "SWI=flash" in buf:
            raise ValueError("Cannot recover filesystem(s) -- local SWI cannot be recovered.")

        with MountContext(label='FLASH', log=self.log) as ctx:
            dst = os.path.join(ctx.dir, 'boot-config')
            with open(dst, "w") as fd:
                self.log.debug("+ cat > %s", dst)
                fd.write(buf)

        return 0
示例#8
0
 def restoreConfig(self, dev):
     """Restore the saved ONL-CONFIG."""
     archive, self.configArchive = self.configArchive, None
     self.log.info("restoring ONL-CONFIG archive %s to %s",
                   archive, dev)
     with MountContext(dev, log=self.log) as ctx:
         self.log.debug("+ tar -zxf %s -C %s",
                        archive, ctx.dir)
         pipe = subprocess.Popen(["tar", "-zxf", archive,],
                                 cwd=ctx.dir)
         pipe.communicate()
         code = pipe.wait()
     if code:
         raise SystemExit("backup of ONL-CONFIG failed")
     self.unlink(archive)
示例#9
0
 def backupConfig(self, dev):
     """Back up the ONL-CONFIG partition for later restore."""
     self.configArchive = tempfile.mktemp(prefix="onl-config-",
                                          suffix=".tar.gz")
     self.log.info("backing up ONL-CONFIG partition %s to %s",
                   dev, self.configArchive)
     with MountContext(dev, log=self.log) as ctx:
         self.log.debug("+ tar -zcf %s -C %s .",
                        self.configArchive, ctx.dir)
         pipe = subprocess.Popen(["tar", "-zcf", self.configArchive, ".",],
                                 cwd=ctx.dir)
         pipe.communicate()
         code = pipe.wait()
     if code:
         raise SystemExit("backup of ONL-CONFIG failed")
示例#10
0
    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)

        initrd = None
        for f in set(os.listdir(self.im.installerConf.installer_dir) + self.zf.namelist()):
            for i in sysconfig.installer.grub:
                if f == i:
                    initrd = i
                    break

        cf = GRUB_TPL % ctx

        self.log.info("Installing kernel")
        dev = self.blkidParts['ONL-BOOT']

        with MountContext(dev.device, log=self.log) as ctx:
            def _cp(b, dstname=None):
                if dstname is None:
                    dstname = b
                dst = os.path.join(ctx.dir, dstname)
                self.installerCopy(b, dst, optional=True)
            [_cp(e) for e in kernels]
            _cp(initrd, "%s.cpio.gz" % self.im.installerConf.installer_platform)
            d = os.path.join(ctx.dir, "grub")
            self.makedirs(d)
            dst = os.path.join(ctx.dir, 'grub/grub.cfg')
            with open(dst, "w") as fd:
                fd.write(cf)

        return 0
示例#11
0
    def installOnlConfig(self):

        try:
            dev = self.blkidParts['ONL-CONFIG']
        except IndexError as ex:
            self.log.warn("cannot find ONL-CONFIG partition : %s", str(ex))
            return 1

        with MountContext(dev.device, log=self.log) as ctx:
            for f in self.zf.namelist():
                d = 'config/'
                if f.startswith(d) and f != d:
                    dst = os.path.join(ctx.dir, os.path.basename(f))
                    if not os.path.exists(dst):
                        self.installerCopy(f, dst)

        return 0
示例#12
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

        if self.isUEFI:
            ctx['set_root_para'] = "set root='(hd0,gpt1)'"
            ctx['set_search_para2'] = "--fs-uuid"
            ctx['set_save_entry_para'] = ""
            ctx['set_save_env_para'] = ""
            dev_UEFI = self.blkidParts['EFI System']
            ctx['onie_boot'] = dev_UEFI.uuid
            ctx['set_chainloader_para'] = "/EFI/onie/grubx64.efi"
        else:
            ctx['set_root_para'] = ""
            ctx['set_search_para2'] = "--label"
            ctx['set_save_entry_para'] = "set saved_entry=\"0\""
            ctx['set_save_env_para'] = "save_env saved_entry"
            ctx['onie_boot'] = "ONIE-BOOT"
            ctx['set_chainloader_para'] = "+1"

        cf = GRUB_TPL % ctx

        with MountContext(dev.device, log=self.log) as ctx:
            d = os.path.join(ctx.dir, "grub")
            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)

        return 0
示例#13
0
    def installSwi(self):

        files = os.listdir(self.im.installerConf.installer_dir) + self.zf.namelist()
        swis = [x for x in files if x.endswith('.swi')]
        if not swis:
            self.log.info("No ONL Software Image available for installation.")
            self.log.info("Post-install ZTN installation will be required.")
            return
        if len(swis) > 1:
            self.log.warn("Multiple SWIs found in installer: %s", " ".join(swis))
            return

        base = swis[0]

        self.log.info("Installing ONL Software Image (%s)...", base)
        dev = self.blkidParts['ONL-IMAGES']
        with MountContext(dev.device, log=self.log) as ctx:
            dst = os.path.join(ctx.dir, base)
            self.installerCopy(base, dst)

        return 0
示例#14
0
 def mountCtx(self, device):
     return MountContext(device,
                         chroot=self.chrootDir, fsType='ext4',
                         log=self.log)
示例#15
0
    def __enter__(self):

        self.pm = ProcMountsParser()
        self.blkid = BlkidParser(log=self.log.getChild("blkid"))
        self.mtd = ProcMtdParser(log=self.log.getChild("mtd"))

        def _g(d):
            pat = os.path.join(d, "onie/initrd.img*")
            l = glob.glob(pat)
            if l: return l[0]
            return None

        # try to find a mounted, labeled partition
        try:
            dev = self.blkid['ONIE-BOOT'].device
        except IndexError:
            dev = None
        if dev is not None:
            self.log.debug("found ONIE boot device %s", dev)

            parts = [p for p in self.pm.mounts if p.device == dev]
            if parts:
                self.log.debug("found ONIE boot mounted at %s", parts[0].dir)
                initrd = _g(parts[0].dir)
                if initrd is None:
                    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:
                    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

            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
        for part in self.pm.mounts:
            if not part.device.startswith('/dev/'): continue
            initrd = _g(part.dir)
            if initrd is None:
                self.log.debug("cannot find ONIE initrd on %s (%s)",
                               part.device, part.dir)
            else:
                self.onieDir = part.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

        # grovel through MTD devices (u-boot)
        parts = [p for p in self.mtd.parts if p.label == "onie"]
        if parts:
            part = parts[0]
            self.log.debug("found ONIE MTD device %s", part.charDevice
                           or part.blockDevice)
            with UbootInitrdContext(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

        if self.mtd.mounts:
            raise ValueError("cannot find ONIE MTD device")

        raise ValueError("cannot find ONIE initrd")
示例#16
0
    def run(self):

        self.pm = ProcMountsParser()
        self.blkid = BlkidParser(log=self.log.getChild("blkid"))
        self.mtd = ProcMtdParser(log=self.log.getChild("mtd"))

        def _g(d):
            pat = os.path.join(d, "onie/initrd.img*")
            l = glob.glob(pat)
            if l: return l[0]
            return None

        # try to find a mounted, labeled partition
        try:
            dev = self.blkid['ONIE-BOOT'].device
        except IndexError:
            dev = None
        if dev is not None:
            self.log.debug("found ONIE boot device %s", dev)

            parts = [p for p in self.pm.mounts if p.device == dev]
            if parts:
                onieDir = parts[0]
                self.log.debug("found ONIE boot mounted at %s", onieDir)
                initrd = _g(onieDir)
                if initrd is None:
                    self.log.warn("cannot find ONIE initrd on %s", onieDir)
                else:
                    self.log.debug("found ONIE initrd at %s", initrd)
                    return _runInitrdShell(initrd)

            with MountContext(dev, log=self.log) as ctx:
                initrd = _g(ctx.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)
                    return self._runInitrdShell(initrd)

            self.log.warn("cannot find an ONIE initrd")
            return 1

        # try to find onie initrd on a mounted fs (GRUB);
        # for ONIE images this is usually /mnt/onie-boot
        for part in self.pm.mounts:
            if not part.device.startswith('/dev/'): continue
            initrd = _g(part.dir)
            if initrd is None:
                self.log.debug("cannot find ONIE initrd on %s (%s)",
                               part.device, part.dir)
            else:
                self.log.debug("found ONIE initrd at %s", initrd)
                return self._runInitrdShell(initrd)

        # grovel through MTD devices (u-boot)
        parts = [p for p in self.mtd.parts if p.label == "onie"]
        if parts:
            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

        self.log.error("cannot find ONIE initrd")
        return 1
示例#17
0
 def mountCtx(self, device, fsType='ext4'):
     return MountContext(device, fsType=fsType, log=self.log)
示例#18
0
    def runUboot(self):

        dev = self.pc['loader']['device']
        self.log.info("found loader device %s", dev)

        parts = self.pc['installer']
        bootPart = None
        bootPartno = None
        for idx, part in enumerate(self.pc['installer']):
            label, pdata = list(part.items())[0]
            if label == 'ONL-BOOT':
                bootPart = pdata
                bootPartno = idx + 1
                break
        if bootPart is None:
            self.log.info("cannot find ONL-BOOT declaration")
            return 1

        fmt = bootPart.get('format', 'ext2')
        if fmt == 'raw':
            bootDevice = dev + str(bootPartno)
        else:
            bootDevice = self.blkid['ONL-BOOT'].device

        # run from a raw partition
        if fmt == 'raw':
            self.log.info("found (raw) boot partition %s", bootDevice)
            return self._runFitShell(bootDevice)

        l = []

        p = self.pc['flat_image_tree']['itb']
        if type(p) == dict: p = p['=']
        if p not in l: l.append(p)

        p = self.platform.platform() + '.itb'
        if p not in l: l.append(p)

        p = 'onl-loader-fit.itb'
        if p not in l: l.append(p)

        self.log.info("looking for loader images %s", ", ".join(l))

        # run from a file in a mounted filesystem
        parts = [p for p in self.pm.mounts if p.device == bootDevice]
        if parts:
            loaderDir = parts[0]
            self.log.debug("found loader device mounted at %s", loaderDir)
            for e in l:
                p = os.path.join(loaderDir, e)
                if os.path.exists(p): return self._runFitShell(p)
            self.log.error("cannot find an ITB")
            return 1

        # run from a file in an umounted filesystem
        with MountContext(bootDevice, log=self.log) as ctx:
            self.log.info("found (%s) loader device %s", fmt, bootDevice)
            for e in l:
                p = os.path.join(ctx.dir, e)
                if os.path.exists(p): return self._runFitShell(p)
            self.log.error("cannot find an ITB")
            return 1