예제 #1
0
 def _runInitrdShell(self, initrd):
     with InitrdContext(initrd=initrd, log=self.log) as ctx:
         if self.command is not None:
             cmd = ('chroot', ctx.dir, '/bin/sh', '-c',
                    'IFS=;' + self.command)
         else:
             cmd = ('chroot', ctx.dir, '/bin/sh', '-i')
         try:
             self.check_call(cmd)
         except subprocess.CalledProcessError, what:
             pass
예제 #2
0
 def _runInitrdShell(self, initrd):
     with InitrdContext(initrd=initrd, log=self.log) as ctx:
         cmd = [
             'onie-sysinfo',
         ]
         cmd.extend(self.args)
         cmd = ('chroot', ctx.dir, '/bin/sh', '-c', 'IFS=;' + " ".join(cmd))
         try:
             self.output = self.check_output(cmd)
             ret = 0
         except subprocess.CalledProcessError, what:
             self.log.error("failed command: %s", " ".join(what.cmd))
             for line in (what.output or "").splitlines():
                 self.log.error(">>> %s", line)
             ret = what.returncode
예제 #3
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
예제 #4
0
    def runLocal(self):

        self.log.info("getting installer configuration")
        if os.path.exists(ConfUtils.MachineConf.PATH):
            self.machineConf = ConfUtils.MachineConf()
        else:
            self.log.warn("missing /etc/machine.conf from ONIE runtime")
            self.machineConf = ConfUtils.MachineConf(path='/dev/null')
        self.installerConf = ConfUtils.InstallerConf()

        ##self.log.info("using native GRUB")
        ##self.grubEnv = ConfUtils.GrubEnv(log=self.log.getChild("grub"))

        pat = "/mnt/onie-boot/onie/initrd.img*"
        l = glob.glob(pat)
        if l:
            initrd = l[0]
            self.log.info("using native ONIE initrd+chroot GRUB (%s)", initrd)
            initrdDir = InitrdContext.mkChroot(initrd, log=self.log)
            self.grubEnv = ConfUtils.ChrootGrubEnv(
                initrdDir,
                bootDir="/mnt/onie-boot",
                path="/grub/grubenv",
                log=self.log.getChild("grub"))
            # direct access using ONIE initrd as a chroot
            # (will need to fix up bootDir and bootPart later)
        else:
            self.log.info("using proxy GRUB")
            self.grubEnv = ConfUtils.ProxyGrubEnv(
                self.installerConf,
                bootDir="/mnt/onie-boot",
                path="/grub/grubenv",
                chroot=False,
                log=self.log.getChild("grub"))
            # indirect access through chroot host
            # (will need to fix up bootDir and bootPart later)

        if os.path.exists(ConfUtils.UbootEnv.SETENV):
            self.ubootEnv = ConfUtils.UbootEnv(log=self.log.getChild("u-boot"))
        else:
            self.ubootEnv = None

        self.log.info("ONL Installer %s", self.installerConf.onl_version)

        code = self.findPlatform()
        if code: return code

        try:
            import onl.platform.current
        except:
            self.log.exception("cannot find platform config")
            code = 1
            if self.log.level < logging.INFO:
                self.post_mortem()
        if code: return code

        self.onlPlatform = onl.platform.current.OnlPlatform()

        if 'grub' in self.onlPlatform.platform_config:
            self.log.info("trying a GRUB based installer")
            iklass = BaseInstall.GrubInstaller
        elif 'flat_image_tree' in self.onlPlatform.platform_config:
            self.log.info("trying a U-Boot based installer")
            iklass = BaseInstall.UbootInstaller
        else:
            self.log.error("cannot detect installer type")
            return 1

        # run the platform-specific installer
        self.installer = iklass(machineConf=self.machineConf,
                                installerConf=self.installerConf,
                                platformConf=self.onlPlatform.platform_config,
                                grubEnv=self.grubEnv,
                                ubootEnv=self.ubootEnv,
                                force=self.force,
                                log=self.log)
        try:
            code = self.installer.run()
        except:
            self.log.exception("installer failed")
            code = 1
            if self.log.level < logging.INFO:
                self.post_mortem()
        if code: return code

        if getattr(self.installer, 'grub', False):
            code = self.finalizeGrub()
            if code: return code
        if getattr(self.installer, 'uboot', False):
            code = self.finalizeUboot()
            if code: return code

        self.log.info("Install finished.")
        return 0
예제 #5
0
    def runLocal(self):

        self.log.info("getting installer configuration")
        if os.path.exists(ConfUtils.MachineConf.PATH):
            self.machineConf = ConfUtils.MachineConf()
        else:
            self.log.warn("missing /etc/machine.conf from ONIE runtime")
            self.machineConf = ConfUtils.MachineConf(path='/dev/null')
        self.installerConf = ConfUtils.InstallerConf()

        ##self.log.info("using native GRUB")
        ##self.grubEnv = ConfUtils.GrubEnv(log=self.log.getChild("grub"))

        pat = "/mnt/onie-boot/onie/initrd.img*"
        l = glob.glob(pat)
        if l:
            initrd = l[0]
            self.log.info("using native ONIE initrd+chroot GRUB (%s)", initrd)
            initrdDir = InitrdContext.mkChroot(initrd, log=self.log)
            self.grubEnv = ConfUtils.ChrootGrubEnv(initrdDir,
                                                   bootDir="/mnt/onie-boot",
                                                   path="/grub/grubenv",
                                                   log=self.log.getChild("grub"))
            # direct access using ONIE initrd as a chroot
            # (will need to fix up bootDir and bootPart later)
        else:
            self.log.info("using proxy GRUB")
            self.grubEnv = ConfUtils.ProxyGrubEnv(self.installerConf,
                                                  bootDir="/mnt/onie-boot",
                                                  path="/grub/grubenv",
                                                  chroot=False,
                                                  log=self.log.getChild("grub"))
            # indirect access through chroot host
            # (will need to fix up bootDir and bootPart later)

        if os.path.exists(ConfUtils.UbootEnv.SETENV):
            self.ubootEnv = ConfUtils.UbootEnv(log=self.log.getChild("u-boot"))
        else:
            self.ubootEnv = None

        self.log.info("ONL Installer %s", self.installerConf.onl_version)

        code = self.findPlatform()
        if code: return code

        try:
            import onl.platform.current
        except:
            self.log.exception("cannot find platform config")
            code = 1
            if self.log.level < logging.INFO:
                self.post_mortem()
        if code: return code

        self.onlPlatform = onl.platform.current.OnlPlatform()

        if 'grub' in self.onlPlatform.platform_config:
            self.log.info("trying a GRUB based installer")
            iklass = BaseInstall.GrubInstaller
        elif 'flat_image_tree' in self.onlPlatform.platform_config:
            self.log.info("trying a U-Boot based installer")
            iklass = BaseInstall.UbootInstaller
        else:
            self.log.error("cannot detect installer type")
            return 1

        # run the platform-specific installer
        self.installer = iklass(machineConf=self.machineConf,
                                installerConf=self.installerConf,
                                platformConf=self.onlPlatform.platform_config,
                                grubEnv=self.grubEnv,
                                ubootEnv=self.ubootEnv,
                                force=self.force,
                                log=self.log)
        try:
            code = self.installer.run()
        except:
            self.log.exception("installer failed")
            code = 1
            if self.log.level < logging.INFO:
                self.post_mortem()
        if code: return code

        if getattr(self.installer, 'grub', False):
            code = self.finalizeGrub()
            if code: return code
        if getattr(self.installer, 'uboot', False):
            code = self.finalizeUboot()
            if code: return code

        self.log.info("Install finished.")
        return 0
예제 #6
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")