summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'sys-boot/refind-bin/files/refind-mkconfig')
-rw-r--r--sys-boot/refind-bin/files/refind-mkconfig177
1 files changed, 177 insertions, 0 deletions
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