Files
iconograph/client/update_grub.py
2016-05-09 20:40:38 +00:00

88 lines
2.1 KiB
Python
Executable File

#!/usr/bin/python3
import argparse
import os
import re
import string
import subprocess
import sys
parser = argparse.ArgumentParser(description='iconograph update_grub')
parser.add_argument(
'--boot-dir',
dest='boot_dir',
action='store',
required=True)
parser.add_argument(
'--image-dir',
dest='image_dir',
action='store',
required=True)
FLAGS = parser.parse_args()
class GrubUpdater(object):
_VOLUME_ID_REGEX = re.compile(b'^Volume id: (?P<volume_id>.+)$', re.MULTILINE)
_HOTKEYS = string.digits + string.ascii_letters
def __init__(self, image_dir, boot_dir):
self._image_dir = image_dir
self._boot_dir = boot_dir
assert self._image_dir.startswith(self._boot_dir)
self._image_path = '/' + os.path.relpath(self._image_dir, self._boot_dir)
def _GetVolumeID(self, path):
isoinfo = subprocess.check_output([
'isoinfo',
'-d',
'-i', path,
])
match = self._VOLUME_ID_REGEX.search(isoinfo)
return match.group('volume_id').decode('ascii')
def Update(self):
current = os.readlink(os.path.join(self._image_dir, 'current'))
sys.stdout.write("""
set timeout=5
set default=%(default_image_filename)s
""" % {
'default_image_filename': os.path.basename(current),
})
files = []
for filename in os.listdir(self._image_dir):
if not filename.endswith('.iso'):
continue
files.append(filename)
for i, filename in enumerate(sorted(files, reverse=True)):
sys.stdout.write("""
menuentry "%(image_filename)s (%(volume_id)s)" --hotkey=%(hotkey)s {
search --no-floppy --file --set=root %(image_path)s/%(image_filename)s
iso_path="%(image_path)s/%(image_filename)s"
export iso_path
loopback loop "%(image_path)s/%(image_filename)s"
set root=(loop)
configfile /boot/grub/loopback.cfg
}
""" % {
'image_filename': filename,
'image_path': self._image_path,
'hotkey': self._HOTKEYS[i],
'volume_id': self._GetVolumeID(os.path.join(self._image_dir, filename)),
})
def main():
updater = GrubUpdater(FLAGS.image_dir, FLAGS.boot_dir)
updater.Update()
if __name__ == '__main__':
main()