From cd2501d7b22e74e15afc1e2f91604908b067e5fc Mon Sep 17 00:00:00 2001 From: David Crandall Date: Fri, 17 Apr 2015 20:23:08 -0500 Subject: added refind-bin --- sys-boot/refind-bin/files/refind-mkconfig | 177 ++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 sys-boot/refind-bin/files/refind-mkconfig (limited to 'sys-boot/refind-bin/files/refind-mkconfig') diff --git a/sys-boot/refind-bin/files/refind-mkconfig b/sys-boot/refind-bin/files/refind-mkconfig new file mode 100644 index 0000000..560503d --- /dev/null +++ b/sys-boot/refind-bin/files/refind-mkconfig @@ -0,0 +1,177 @@ +#!/usr/bin/env python +# +# script to automate creation of rEFInd configuration files +# +# Usage: +# +# refind-mkconfig +# +# This program is copyright (c) 2012 by David P. Crandall +# It is released under the terms of the GNU GPL, version 3. +# +# Revision history: +# +# 0.4.5 -- Initial version +# +# Note: version numbers match those of the rEFInd package +# with which this script first appeared. + +import os, re +from collections import OrderedDict, deque +from string import Template + +class _Template(Template): + idpattern = '[0-9]+' + +class _Parser(object): + def __init__(self, files): + self.files = files + self.state = pattern + self.stanzas = OrderedDict() + self.header = None + self.menu = None + + def process(self, lines): + remaining = self.state.process(lines, self) + if remaining: + self.process(remaining) + + def getstanzas(self): + for file in self.files: + with open(file, 'r') as sf: + lines = deque(sf.readlines()) + self.process(lines) + return self.stanzas + +class _Pattern(object): + def __init__(self): + self.header = re.compile("^\[(.+)\]") + + def process(self, lines, parser): + line = lines.popleft() + match = self.header.match(line) + if match: + parser.header = match.group(1) + parser.stanzas[parser.header] = OrderedDict() if parser.header not in parser.stanzas + parser.state = transition + return lines + +class _Menustart(object): + def __init__(): + self.start = re.compile("^menuentry\s+(.+)\s+\{") + + def process(self, lines, parser): + line = lines.popleft() + match = self.start.match(line) + if match: + parser.menu = match.group(1) + parser.stanzas[parser.header][parser.menu] = [line] + parser.state = menu_end + return lines + +class _Menuend(object): + def __init__(): + self.end = re.compile("^\}") + + def process(self, lines, parser): + line = lines.popleft() + parser.stanzas[parser.header][parser.menu].append(line) + if self.end.match(line): + parser.state = transition + return lines + +class _Transition(object): + def process(self, lines, parser): + if pattern.header.match(lines[0]): + parser.state = pattern + elif menu_start.start.match(lines[0]) + parser.state = menu_start + else + discard = lines.popleft() + return lines + +class Mkconfig(object): + def __init__(self): + self.efi = self._findEFI() + self.conf = os.path.join(self.efi, "/EFI/refind/refind.test") + self.comment = re.compile('^\s*#') + self.stanzas = OrderedDict() + self.stanzaFiles = sum([[os.path.join(r, f) for f in fl] + for r, d, fl in os.walk("/etc/refind.d")], []) + + blockdir = re.compile('^' + self.efi + '/EFI/(refind|tools)') + stripdir = re.compile('^' + self.efi) + efiFiles = [[os.path.join(r, f) for f in fl] + for r, d, fl in os.walk(self.efi) if not blockdir.match(r)] + # flatten generated lists + efiFiles = sum(efiFiles, []) + # sort by modification date of files, newest first + efiFiles = sorted(efiFiles, reverse=True, key=lambda i: os.path.getmtime(i)) + # strip mount path + self.efiFiles = [stripdir.sub('', f) for f in efiFiles] + + def _findEFI(self): + if os.path.ismount("/boot/efi"): + mntpath = os.path.abspath("/boot/efi") + elif os.path.ismount("/boot"): + mntpath = os.path.abspath("/boot") + else + print "The EFI partition could not be found at /boot or /boot/efi. Exiting" + exit + with open("/proc/mounts") as mnts: + for line in mnts: + words = re.split('\s+', line) + if words[1] == mntpath: + if words[2] == "vfat": + return mntpath + print "EFI partition must be vfat, but the filesystem is " + words[3] + ". Exiting" + exit + + def _getstanzas(self): + p = + for file in self.stanzaFiles: + with open(file, 'r') as sf: + lines = sf.readlines() + + + def writeGlobalOptions(self): + with open(self.conf, 'w') as newconf: + newconf.write("# This file has been automatically generated by refind-mkconfig.\n") + newconf.write("# Manual edits will be overwritten the next time refind-mkconfig\n") + newconf.write("# is invoked. To change settings, edit /etc/default/refind and\n") + newconf.write("# the files located at /etc/refind.d.\n\n") + # Get global options + newconf.write("# Global options\n") + with open("/etc/default/refind") as default: + for line in default: + if NOT self.comment.match(line): + newconf.write(line + "\n") + + def writeStanzas(self): + # Get OS stanzas + with open(self.conf, 'a') as newconf: + newconf.write("\n# OS stanzas\n\n") + p = _Parser(self.stanzaFiles) + self.stanzas = p.getstanzas + for pk in self.stanzas: + pattern = re.compile(pk) + for file in self.efiFiles: + match = pattern.match(file) + if match: + values = {str(i): match.group(i) for i in range(pattern.groups)} + for mk in self.stanzas[pk]: + for line in self.stanzas[pk][mk]: + t = _Template(line) + newconf.write(t.substitute(values)) + newconf.write("\n") + +pattern = _Pattern() +menu_start = _Menustart() +menu_end = _Menuend() +transition = _Transition() + +if __name__ == '__main__': + cfg = Mkconfig() + cfg.writeGlobalOptions + cfg.writeStanzas + print "New refind.conf written to " + cfg.efi \ No newline at end of file -- cgit v1.2.3-65-gdbad