コード例 #1
0
    def GenerateSections(
            self,
            boot_menu: BootLoaderMenu,
            sfunc: Callable[[BootLoaderMenu, str, str], bool],
            ofunc: Callable[[BootLoaderMenu, str],
                            bool] = None) -> BootLoaderMenu:
        """Generates sections using passed in extension-supplied functions"""
        try:
            timeout = int(self.boot_config["boot/timeout"])
        except ValueError:
            ok = False
            self.msgs.append(["fatal", "Invalid value for boot/timeout."])
            return boot_menu

        if timeout == 0:
            self.msgs.append([
                "warn",
                "boot/timeout value is zero - boot menu will not appear!"
            ])
        elif timeout < 3:
            self.msgs.append(
                ["norm", "boot/timeout value is below 3 seconds."])

        # Remove builtins from list of sections
        sections = self.boot_config.getSections()
        for sect in sections[:]:
            if sect in self.boot_config.builtins:
                sections.remove(sect)

        # If we have no boot entries, throw an error - force user to be
        # explicit.
        if len(sections) == 0:
            self.msgs.append(
                ["fatal", "No boot entries are defined in /etc/boot.conf."])
            boot_menu.success = False
            return boot_menu

        # Warn if there are no linux entries
        has_linux = False
        for sect in sections:
            if self.boot_config["{s}/{t}".format(s=sect, t="type")] == "linux":
                has_linux = True
                break
        if has_linux is False:
            self.msgs.append([
                "warn",
                "No Linux boot entries are defined. You may not be able to re-enter Linux."
            ])

        # Generate sections
        for sect in sections:
            if self.boot_config["{s}/type".format(s=sect)] in ["linux", "xen"]:
                ok = self._GenerateLinuxSection(boot_menu, sect, sfunc)
            elif ofunc:
                ok = self._GenerateOtherSection(boot_menu, sect, ofunc)

        if self._pos == 0:
            # this means we processed no kernels -- so we have nothing to boot!
            self.msgs.append([
                "fatal",
                "No matching kernels or boot entries found in /etc/boot.conf."
            ])
            boot_menu.success = False
            return boot_menu
        elif boot_menu.default_position is None:
            # this means we didn't pick a default kernel to boot!
            self.msgs.append([
                "warn",
                "Had difficulty finding a default kernel -- using first one."
            ])
            # If we didn't find a specified default, use the first one
            boot_menu.default_position = 0
        else:
            self.msgs.append([
                "note",
                "Default kernel selected via: %s." % self._default_mode
            ])
            # Tag the boot menu as being default for display:
            boot_menu.boot_entries[boot_menu.default_position]["flags"].append(
                BootMenuFlag.DEFAULT)
        if self._default_mode == "autopick: mtime" and self.boot_config.item(
                "boot", "autopick") == "last-booted":
            self.msgs.append([
                "warn",
                "Falling back to last modification time booting due to lack of last-booted info."
            ])

        return boot_menu
コード例 #2
0
ファイル: grub.py プロジェクト: palica/ego
    def generateConfigFile(self, boot_menu: BootLoaderMenu):
        if self.uefiboot:
            self.msgs.append(
                ["note", "Detected UEFI boot. Configuring for UEFI booting."])
        else:
            self.msgs.append([
                "note",
                "Detected MBR boot. Configuring for Legacy MBR booting."
            ])
        boot_menu.lines.append(
            self.boot_config.condFormatSubItem("boot/timeout",
                                               "set timeout={s}"))
        # pass our boot entry generator function to GenerateSections,
        # and everything is taken care of for our boot entries

        boot_menu.lines += [
            "", "if [ -s $prefix/grubenv ]; then", "    load_env", "fi", "",
            "function savedefault {", "    if [ -z \"{boot_once}\" ]; then",
            "        saved_entry=\"${chosen}\"",
            "        save_env saved_entry", "    fi", "}"
        ]

        if self.boot_config.hasItem("boot/terminal") and self.boot_config[
                "boot/terminal"] == "serial":
            self.msgs.append(["warn", "Configured for SERIAL input/output."])
            boot_menu.lines += [
                "serial --unit=%s --speed=%s --word=%s --parity=%s --stop=%s" %
                (self.boot_config["serial/unit"],
                 self.boot_config["serial/speed"],
                 self.boot_config["serial/word"],
                 self.boot_config["serial/parity"],
                 self.boot_config["serial/stop"]), "terminal_input serial",
                "terminal_output serial"
            ]
        elif self.boot_config.hasItem("display/gfxmode"):
            boot_menu.lines.append("")
            self.PrepareGRUBForFilesystem(
                os.path.join(self.config.root_path,
                             self.boot_config["boot/path"].lstrip('/')),
                boot_menu.lines)
            if self.boot_config.hasItem("display/font"):
                font = self.boot_config["display/font"]
            else:
                font = None

            dst_font = None

            if font is None:
                fonts = ["unicode.pf2", "unifont.pf2"]
            else:
                fonts = [font]

            for fontpath in [self.grubpath, self.grubpath + "/fonts"]:
                if dst_font is not None:
                    break
                for font in fonts:
                    path_to_font = fontpath + "/" + font
                    full_path_to_font = os.path.join(self.config.root_path,
                                                     path_to_font.lstrip("/"))
                    if os.path.exists(full_path_to_font):
                        dst_font = path_to_font
                        break

            if dst_font is None:
                # font does not exist at destination... so we will need to find it somewhere and copy into /boot/grub
                for fontpath in self.boot_config["grub/font_src"].split():
                    if dst_font is not None:
                        break
                    for font in fonts:
                        path_to_font = fontpath + "/" + font
                        if os.path.exists(path_to_font):
                            src_font = path_to_font
                            dst_font = self.grubpath + '/fonts/' + font
                            dst_font = os.path.join(self.config.root_path,
                                                    dst_font.lstrip("/"))
                            if not os.path.exists(dst_font):
                                import shutil
                                shutil.copy(src_font, dst_font)
                            break

            if dst_font is None:
                if font:
                    self.msgs.append([
                        "fatal",
                        "specified font \"{ft}\" not found at {dst}; aborting."
                        .format(ft=font, dst=dst_font)
                    ])
                else:
                    self.msgs.append([
                        "fatal",
                        "Could not find one of %s to copy into boot directory; aborting."
                        % ",".join(fonts)
                    ])
                boot_menu.success = False

            boot_menu.lines += [
                "if loadfont {dst}; then".format(
                    dst=self.resolver.RelativePathTo(
                        dst_font, self.boot_config["boot/path"])),
                "   set gfxmode={gfx}".format(gfx=self.sanitizeDisplayMode(
                    self.boot_config["display/gfxmode"])),
                "   insmod all_video", "   terminal_output gfxterm"
            ]
            bg = self.boot_config.item("display", "background").split()
            if len(bg):
                bgimg = None
                bgext = None
                if len(bg) == 1:
                    # get extension from file:
                    bgimg = bg[0]
                    bgext = bg[0].rsplit(".")[-1].lower()
                elif len(bg) == 2:
                    # extension specified as second argument:
                    bgimg, bgext = bg
                else:
                    self.msgs.append([
                        "warn",
                        "Unexpected number of arguments for background image - skipping."
                    ])
                if bgimg is not None:
                    if bgext == "jpg":
                        bgext = "jpeg"
                    if bgext in ["jpeg", "png", "tga"]:
                        rel_cfgpath = "{path}/{img}".format(
                            path=self.boot_config["boot/path"], img=bgimg)

                        # first, look for absolute path, because our relative path
                        # can eval to "/boot/boot/foo.png" which
                        # due to the /boot/boot symlink will "exist".

                        if bgimg[0] == "/" and os.path.exists(bgimg):
                            # user specified absolute path to file on disk:
                            boot_menu.lines += [
                                "   insmod {bg}".format(bg=bgext),
                                "   background_image {img}".format(
                                    img=self.resolver.RelativePathTo(
                                        bgimg, self.boot_config["boot/path"]))
                            ]
                        elif os.path.exists(rel_cfgpath):
                            # user specified path relative to /boot:
                            boot_menu.lines += [
                                "   insmod {ext}".format(ext=bgext),
                                "   background_image {img}".format(
                                    img=self.resolver.RelativePathTo(
                                        rel_cfgpath,
                                        self.boot_config["boot/path"]))
                            ]
                        else:
                            self.msgs.append([
                                "warn",
                                "background image \"{img}\" does not exist - skipping."
                                .format(img=bgimg)
                            ])
                    else:
                        self.msgs.append([
                            "warn",
                            "background image \"{img}\" (format \"{ext}\") not recognized - skipping."
                            .format(img=bgimg, ext=bgext)
                        ])
            boot_menu.lines += [
                "fi",
                "",
                self.boot_config.condFormatSubItem(
                    "color/normal", "set menu_color_normal={s}"),
                self.boot_config.condFormatSubItem(
                    "color/highlight", "set menu_color_highlight={s}"),
            ]
        else:
            if self.boot_config.hasItem("display/background"):
                self.msgs.append([
                    "warn",
                    "display/gfxmode not provided - display/background \"{bg}\" will not be displayed."
                    .format(bg=self.boot_config["display/background"])
                ])
        self.resolver.GenerateSections(boot_menu, self.generateBootEntry,
                                       self.generateOtherBootEntry)

        if boot_menu.user_specified_attempt_identifier:
            if boot_menu.attempt_kname is not None and boot_menu.attempt_position is not None:
                boot_menu.lines += []
                # This condition indicates that we successfully found the boot entry in the boot menu:
                # Record entry on-disk as a kernel to promote to default if we succeed booting...
                self.boot_config.idmapper.update_promote_kname(
                    boot_menu._attempt_kname)
                self._attempt_kernel(boot_menu)
            else:
                self.msgs.append([
                    "error",
                    "Unable to find a matching boot entry for attempted kernel you specified."
                ])
        else:
            # make sure the *default* kernel is attempted, to wipe out any existing attempt settings.
            self._attempt_kernel(boot_menu, set_default=True)

        # The following lines load the GRUB env data. Then we see if "$next_entry" is set, which specifies a to-be-attempted kernel.
        # If so, it becomes the default (for one boot.) Otherwise, we look and see if "$saved_entry" is set, which is the grub env
        # variable set by "grub-set-default". If this specifies a default kernel, we'll use it. Otherwise, fall back to a hard-
        # coded value from boot-update config itself, pointing to the default kernel.

        boot_menu.lines += [
            "", "if [ ! \"${next_entry}\" = \"\" ] ; then",
            "    set default=\"${next_entry}\"", "    set next_entry=",
            "    save_env next_entry", "    set boot_once=true",
            "elif [ ! \"${saved_entry}\" = \"\" ]; then",
            "    set default=\"${saved_entry}\"", "else",
            "    set default={pos}".format(pos=boot_menu.default_position),
            "fi"
        ]
コード例 #3
0
ファイル: grub.py プロジェクト: funtoo/ego
	def generateConfigFile(self, boot_menu: BootLoaderMenu):
		if self.uefiboot:
			self.msgs.append(["note", "Detected UEFI boot. Configuring for UEFI booting."])
		else:
			self.msgs.append(["note", "Detected MBR boot. Configuring for Legacy MBR booting."])
		boot_menu.lines.append(self.boot_config.condFormatSubItem("boot/timeout", "set timeout={s}"))
		# pass our boot entry generator function to GenerateSections,
		# and everything is taken care of for our boot entries
		
		boot_menu.lines += [
			"",
			"if [ -s $prefix/grubenv ]; then",
			"    load_env",
			"fi",
			"",
			"function savedefault {",
			"    if [ -z \"{boot_once}\" ]; then",
			"        saved_entry=\"${chosen}\"",
			"        save_env saved_entry",
			"    fi",
			"}"
		]
		
		if self.boot_config.hasItem("boot/terminal") and self.boot_config["boot/terminal"] == "serial":
			self.msgs.append(["warn", "Configured for SERIAL input/output."])
			boot_menu.lines += [
				"serial --unit=%s --speed=%s --word=%s --parity=%s --stop=%s" % (
					self.boot_config["serial/unit"],
					self.boot_config["serial/speed"],
					self.boot_config["serial/word"],
					self.boot_config["serial/parity"],
					self.boot_config["serial/stop"]),
				"terminal_input serial",
				"terminal_output serial"
			]
		elif self.boot_config.hasItem("display/gfxmode"):
			boot_menu.lines.append("")
			self.PrepareGRUBForFilesystem(os.path.join(self.config.root_path, self.boot_config["boot/path"].lstrip('/')), boot_menu.lines)
			if self.boot_config.hasItem("display/font"):
				font = self.boot_config["display/font"]
			else:
				font = None
			
			dst_font = None
			
			if font is None:
				fonts = ["unicode.pf2", "unifont.pf2"]
			else:
				fonts = [font]
			
			for fontpath in [self.grubpath, self.grubpath + "/fonts"]:
				if dst_font is not None:
					break
				for font in fonts:
					path_to_font = fontpath + "/" + font
					full_path_to_font = os.path.join(self.config.root_path, path_to_font.lstrip("/"))
					if os.path.exists(full_path_to_font):
						dst_font = path_to_font
						break
			
			if dst_font is None:
				# font does not exist at destination... so we will need to find it somewhere and copy into /boot/grub
				for fontpath in self.boot_config["grub/font_src"].split():
					if dst_font is not None:
						break
					for font in fonts:
						path_to_font = fontpath + "/" + font
						if os.path.exists(path_to_font):
							src_font = path_to_font
							dst_font = self.grubpath + '/fonts/' + font
							dst_font = os.path.join(self.config.root_path, dst_font.lstrip("/"))
							if not os.path.exists(dst_font):
								import shutil
								shutil.copy(src_font, dst_font)
							break
			
			if dst_font is None:
				if font:
					self.msgs.append(["fatal", "specified font \"{ft}\" not found at {dst}; aborting.".format(ft=font, dst=dst_font)])
				else:
					self.msgs.append(["fatal", "Could not find one of %s to copy into boot directory; aborting." % ",".join(fonts)])
				boot_menu.success = False

			
			boot_menu.lines += ["if loadfont {dst}; then".format(dst=self.resolver.RelativePathTo(dst_font, self.boot_config["boot/path"])),
				  "   set gfxmode={gfx}".format(gfx=self.sanitizeDisplayMode(self.boot_config["display/gfxmode"])),
				  "   insmod all_video",
				  "   terminal_output gfxterm"]
			bg = self.boot_config.item("display", "background").split()
			if len(bg):
				bgimg = None
				bgext = None
				if len(bg) == 1:
					# get extension from file:
					bgimg = bg[0]
					bgext = bg[0].rsplit(".")[-1].lower()
				elif len(bg) == 2:
					# extension specified as second argument:
					bgimg, bgext = bg
				else:
					self.msgs.append(["warn", "Unexpected number of arguments for background image - skipping."])
				if bgimg is not None:
					if bgext == "jpg":
						bgext = "jpeg"
					if bgext in ["jpeg", "png", "tga"]:
						rel_cfgpath = "{path}/{img}".format(path=self.boot_config["boot/path"], img=bgimg)
						
						# first, look for absolute path, because our relative path
						# can eval to "/boot/boot/foo.png" which
						# due to the /boot/boot symlink will "exist".
						
						if bgimg[0] == "/" and os.path.exists(bgimg):
							# user specified absolute path to file on disk:
							boot_menu.lines += [
								"   insmod {bg}".format(bg=bgext),
								"   background_image {img}".format(img=self.resolver.RelativePathTo(bgimg, self.boot_config["boot/path"]))
							]
						elif os.path.exists(rel_cfgpath):
							# user specified path relative to /boot:
							boot_menu.lines += [
								"   insmod {ext}".format(ext=bgext),
								"   background_image {img}".format(img=self.resolver.RelativePathTo(rel_cfgpath, self.boot_config["boot/path"]))
							]
						else:
							self.msgs.append(["warn", "background image \"{img}\" does not exist - skipping.".format(img=bgimg)])
					else:
						self.msgs.append(["warn", "background image \"{img}\" (format \"{ext}\") not recognized - skipping.".format(img=bgimg, ext=bgext)])
			boot_menu.lines += ["fi",
								"",
								self.boot_config.condFormatSubItem("color/normal", "set menu_color_normal={s}"),
								self.boot_config.condFormatSubItem("color/highlight", "set menu_color_highlight={s}"),
								]
		else:
			if self.boot_config.hasItem("display/background"):
				self.msgs.append(["warn", "display/gfxmode not provided - display/background \"{bg}\" will not be displayed.".format(bg=self.boot_config["display/background"])])
		self.resolver.GenerateSections(boot_menu, self.generateBootEntry, self.generateOtherBootEntry)
		
		if boot_menu.user_specified_attempt_identifier:
			if boot_menu.attempt_kname is not None and boot_menu.attempt_position is not None:
				boot_menu.lines += [

				]
				# This condition indicates that we successfully found the boot entry in the boot menu:
				# Record entry on-disk as a kernel to promote to default if we succeed booting...
				self.boot_config.idmapper.update_promote_kname(boot_menu._attempt_kname)
				self._attempt_kernel(boot_menu)
			else:
				self.msgs.append(["error", "Unable to find a matching boot entry for attempted kernel you specified."])
		else:
			# make sure the *default* kernel is attempted, to wipe out any existing attempt settings.
			self._attempt_kernel(boot_menu, set_default=True)
		
		# The following lines load the GRUB env data. Then we see if "$next_entry" is set, which specifies a to-be-attempted kernel.
		# If so, it becomes the default (for one boot.) Otherwise, we look and see if "$saved_entry" is set, which is the grub env
		# variable set by "grub-set-default". If this specifies a default kernel, we'll use it. Otherwise, fall back to a hard-
		# coded value from boot-update config itself, pointing to the default kernel.
		
		boot_menu.lines += [
			"",
			"if [ ! \"${next_entry}\" = \"\" ] ; then",
			"    set default=\"${next_entry}\"",
			"    set next_entry=",
			"    save_env next_entry",
			"    set boot_once=true",
			"elif [ ! \"${saved_entry}\" = \"\" ]; then",
			"    set default=\"${saved_entry}\"",
			"else",
			"    set default={pos}".format(pos=boot_menu.default_position),
			"fi"
		]
コード例 #4
0
ファイル: resolver.py プロジェクト: funtoo/ego
	def GenerateSections(self, boot_menu: BootLoaderMenu,
						 sfunc: Callable[[BootLoaderMenu, str, str], bool],
						 ofunc: Callable[[BootLoaderMenu, str], bool] = None) -> BootLoaderMenu:
		"""Generates sections using passed in extension-supplied functions"""
		try:
			timeout = int(self.boot_config["boot/timeout"])
		except ValueError:
			ok = False
			self.msgs.append(["fatal", "Invalid value for boot/timeout."])
			return boot_menu
		
		if timeout == 0:
			self.msgs.append(["warn", "boot/timeout value is zero - boot menu will not appear!"])
		elif timeout < 3:
			self.msgs.append(["norm", "boot/timeout value is below 3 seconds."])
		
		# Remove builtins from list of sections
		sections = self.boot_config.getSections()
		for sect in sections[:]:
			if sect in self.boot_config.builtins:
				sections.remove(sect)
		
		# If we have no boot entries, throw an error - force user to be
		# explicit.
		if len(sections) == 0:
			self.msgs.append(["fatal", "No boot entries are defined in /etc/boot.conf."])
			boot_menu.success = False
			return boot_menu
		
		# Warn if there are no linux entries
		has_linux = False
		for sect in sections:
			if self.boot_config["{s}/{t}".format(s=sect, t="type")] == "linux":
				has_linux = True
				break
		if has_linux is False:
			self.msgs.append(["warn", "No Linux boot entries are defined. You may not be able to re-enter Linux."])
		
		# Generate sections
		for sect in sections:
			if self.boot_config["{s}/type".format(s=sect)] in ["linux", "xen"]:
				ok = self._GenerateLinuxSection(boot_menu, sect, sfunc)
			elif ofunc:
				ok = self._GenerateOtherSection(boot_menu, sect, ofunc)
		
		if self._pos == 0:
			# this means we processed no kernels -- so we have nothing to boot!
			self.msgs.append(["fatal", "No matching kernels or boot entries found in /etc/boot.conf."])
			boot_menu.success = False
			return boot_menu
		elif boot_menu.default_position is None:
			# this means we didn't pick a default kernel to boot!
			self.msgs.append(["warn", "Had difficulty finding a default kernel -- using first one."])
			# If we didn't find a specified default, use the first one
			boot_menu.default_position = 0
		else:
			self.msgs.append(["note", "Default kernel selected via: %s." % self._default_mode])
			# Tag the boot menu as being default for display:
			boot_menu.boot_entries[boot_menu.default_position]["flags"].append(BootMenuFlag.DEFAULT)
		if self._default_mode == "autopick: mtime" and self.boot_config.item("boot", "autopick") == "last-booted":
				self.msgs.append(["warn", "Falling back to last modification time booting due to lack of last-booted info."])

		return boot_menu