ostree/tests/grub2-entries-crosscheck.py

105 lines
3.4 KiB
Python

#!/usr/bin/python3
#
# Copyright (C) 2015 Red Hat
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library. If not, see <https://www.gnu.org/licenses/>.
import os
import sys
import functools
if len(sys.argv) == 1:
loaderpath = '/boot/loader/entries'
grub2path = '/boot/grub2/grub.cfg'
else:
loaderpath = sys.argv[1]
grub2path = sys.argv[2]
def fatal(msg):
sys.stderr.write(msg)
sys.stderr.write('\n')
sys.exit(1)
def compare_entries_descending(a, b):
return int(b['version']) - int(a['version'])
def get_ostree_option(optionstring):
for o in optionstring.split():
if o.startswith('ostree='):
return o[8:]
raise ValueError('ostree= not found')
entries = []
grub2_entries = []
# Parse loader configs
for fname in os.listdir(loaderpath):
path = os.path.join(loaderpath, fname)
with open(path) as f:
entry = {}
for line in f:
line = line.strip()
if (line == '' or line.startswith('#')):
continue
s = line.find(' ')
assert s > 0
k = line[0:s]
v = line[s+1:]
entry[k] = v
entries.append(entry)
entries.sort(key=functools.cmp_to_key(compare_entries_descending))
# Parse GRUB2 config
with open(grub2path) as f:
in_ostree_config = False
grub2_entry = None
for line in f:
if line.startswith('### BEGIN /etc/grub.d/15_ostree ###'):
in_ostree_config = True
elif line.startswith('### END /etc/grub.d/15_ostree ###'):
in_ostree_config = False
if grub2_entry is not None:
grub2_entries.append(grub2_entry)
elif in_ostree_config:
if line.startswith('menuentry '):
if grub2_entry is not None:
grub2_entries.append(grub2_entry)
grub2_entry = {}
elif line.startswith('linux'):
parts = line.split()
grub2_entry['linux'] = parts[1]
grub2_entry['options'] = ' '.join(parts[2:])
elif line.startswith('initrd'):
grub2_entry['initrd'] = line.split()[1]
if len(entries) != len(grub2_entries):
fatal("Found {0} loader entries, but {1} GRUB2 entries\n".format(len(entries), len(grub2_entries)))
def assert_matches_key(a, b, key):
aval = a[key]
bval = b[key]
if aval != bval:
fatal("Mismatch on {0}: {1} != {2}".format(key, aval, bval))
for i,(entry,grub2entry) in enumerate(zip(entries, grub2_entries)):
assert_matches_key(entry, grub2entry, 'linux')
assert_matches_key(entry, grub2entry, 'initrd')
entry_ostree = get_ostree_option(entry['options'])
grub2_ostree = get_ostree_option(grub2entry['options'])
if entry_ostree != grub2_ostree:
fatal("Mismatch on ostree option: {0} != {1}".format(entry_ostree, grub2_ostree))
sys.stdout.write('GRUB2 configuration validated\n')
sys.exit(0)