debian-forge/osbuild
Lars Karlitski ae1afef209 osbuild
2019-04-08 13:03:13 +02:00

70 lines
2 KiB
Python
Executable file

#!/usr/bin/python3
import argparse
import contextlib
import json
import os
import subprocess
import sys
import tempfile
RESET = "\033[0m"
BOLD = "\033[1m"
RED = "\033[31m"
@contextlib.contextmanager
def tmpfs():
"""A contextmanager that mounts a tmpfs and returns its location."""
with tempfile.TemporaryDirectory(prefix="osbuild-tree-", dir=os.getcwd()) as path:
subprocess.run(["mount", "-t", "tmpfs", "tmpfs", path], check=True)
try:
yield path
finally:
subprocess.run(["umount", path], check=True)
def main(pipeline_path):
with open(pipeline_path) as f:
pipeline = json.load(f)
with tmpfs() as tree:
for i, stage in enumerate(pipeline["stages"], start=1):
name = stage["name"]
options = stage.get("options", {})
options["tree"] = os.path.abspath(tree)
options_str = json.dumps(options, indent=2)
print(f"{RESET}{BOLD}{i}. {name}{RESET} {options_str}")
print()
script = f"""
set -e
mount -t tmpfs tmpfs /tmp
mount -t tmpfs tmpfs /var/tmp
stages/{name}
"""
try:
subprocess.run(["unshare", "--pid", "--kill-child", "--mount", "sh", "-c", script],
input=options_str, encoding="utf-8", check=True)
except KeyboardInterrupt:
print()
print(f"{RESET}{BOLD}{RED}Aborted{RESET}")
return 1
except subprocess.CalledProcessError as error:
print()
print(f"{RESET}{BOLD}{RED}{name} failed with code {error.returncode}{RESET}")
return 1
print()
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Build operating system images")
parser.add_argument("pipeline_path", metavar="pipeline", help="json file containing the pipeline that should be built")
args = parser.parse_args()
sys.exit(main(**vars(args)))