mirror of
https://github.com/linuxboot/heads.git
synced 2025-05-18 16:52:53 +00:00
77 lines
2.9 KiB
Python
Executable File
77 lines
2.9 KiB
Python
Executable File
#!/usr/bin/python3
|
|
# SPDX-License-Identifier: GPL-2.0-only
|
|
|
|
import argparse
|
|
import os
|
|
from lib.image import parse_ifd_or_me
|
|
from lib.mfs import INTEL_IDX, FITC_IDX, HOME_IDX, MFS
|
|
from lib.cfg import CFG
|
|
|
|
def delta_from_fitc_cfg(overridable, fitc_files, output):
|
|
if set(fitc_files.keys()).difference(overridable.keys()) != set():
|
|
raise ValueError("fitc.cfg contains unexpected data, please report this for investigation")
|
|
# Iterate overridable paths from intel.cfg
|
|
for path, intel_file in overridable.items():
|
|
# Skip dirs
|
|
if intel_file.isDirectory():
|
|
continue
|
|
# Skip files not in fitc
|
|
if path not in fitc_files:
|
|
continue
|
|
fitc_file = fitc_files[path]
|
|
if intel_file.data != fitc_file.data:
|
|
# Write out differing file to delta
|
|
filepath = os.path.join(output, path.lstrip("/"))
|
|
os.makedirs(os.path.dirname(filepath), exist_ok=True)
|
|
with open(filepath, "wb") as f:
|
|
f.write(fitc_file.data)
|
|
|
|
def delta_from_home(overridable, home_files, output):
|
|
# Iterate overridable paths from intel.cfg
|
|
for path, intel_file in overridable.items():
|
|
# Skip dirs
|
|
if intel_file.isDirectory():
|
|
continue
|
|
# Skip files not in /home
|
|
if path not in home_files:
|
|
continue
|
|
if intel_file.data != home_files[path]:
|
|
# Write out differing file to delta
|
|
filepath = os.path.join(output, path.lstrip("/"))
|
|
os.makedirs(os.path.dirname(filepath), exist_ok=True)
|
|
with open(filepath, "wb") as f:
|
|
f.write(home_files[path])
|
|
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("--input", required=True, help="Input vendor image (either full with IFD or just ME)")
|
|
parser.add_argument("--output", required=True, help="Output MFS delta directory")
|
|
args = parser.parse_args()
|
|
|
|
# Get ME from input image
|
|
with open(args.input, "rb") as f:
|
|
me = parse_ifd_or_me(f.read())
|
|
|
|
# Parse MFS and get its system volume
|
|
mfs = MFS(me.entry_data("MFS"))
|
|
sysvol = mfs.getSystemVolume()
|
|
|
|
# Lookup table of directories and overridable paths in intel.cfg
|
|
intel_cfg = CFG(sysvol.getFile(INTEL_IDX).data)
|
|
overridable = { file.path: file for file in intel_cfg.files \
|
|
if file.isDirectory() or (file.record.opt & 1) != 0 }
|
|
|
|
fitc = sysvol.getFile(FITC_IDX)
|
|
|
|
if fitc:
|
|
# We have a fitc.cfg, so compute delta from that
|
|
fitc_cfg = CFG(fitc.data)
|
|
fitc_files = { file.path: file for file in fitc_cfg.files }
|
|
delta_from_fitc_cfg(overridable, fitc_files, args.output)
|
|
else:
|
|
# If there is no fitc we must have a /home
|
|
if not sysvol.getFile(HOME_IDX):
|
|
raise Error("MFS has no fitc.cfg or home directory, please provide an image with valid config data")
|
|
# Build lookup table from files in home in /home
|
|
home_files = { path: data for path, data in sysvol.listDir(HOME_IDX, True, "/home") }
|
|
delta_from_home(overridable, home_files, args.output)
|