From 90a6b3bd109a45e5212af702abcff08915febecc Mon Sep 17 00:00:00 2001 From: David Rheinsberg Date: Sat, 29 Feb 2020 11:26:18 +0100 Subject: [PATCH] runners: add blank runner This adds a new runner called `org.osbuild.blank`, which assumes /usr is pre-populated and ready to go. It does not perform any OS setup. It only initializes the environment and executes the stage. This runner allows easy bootstrapping of new systems. It assumes our ideal setup where `/usr` describes a host system in its entirety, without any local policy applied. Thus, this runner is also what we ultimately want to work towards as a default. This might not happen anytime soon, though, given how `passwd`, `ldconfig`, `nss`, etc. still depend on prepopulated caches in `/etc`. --- runners/org.osbuild.blank | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100755 runners/org.osbuild.blank diff --git a/runners/org.osbuild.blank b/runners/org.osbuild.blank new file mode 100755 index 00000000..b58ec583 --- /dev/null +++ b/runners/org.osbuild.blank @@ -0,0 +1,38 @@ +#!/usr/bin/python3 + +import array +import json +import os +import socket +import subprocess +import sys + + +def load_fds(sock, msglen): + fds = array.array("i") # Array of ints + msg, ancdata, _, addr = sock.recvmsg(msglen, socket.CMSG_LEN(253 * fds.itemsize)) + for cmsg_level, cmsg_type, cmsg_data in ancdata: + if (cmsg_level == socket.SOL_SOCKET and cmsg_type == socket.SCM_RIGHTS): + # Append data, ignoring any truncated integers at the end. + fds.frombytes(cmsg_data[:len(cmsg_data) - (len(cmsg_data) % fds.itemsize)]) + return json.loads(msg), list(fds), addr + +def setup_stdio(): + with socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM) as sock: + sock.setsockopt(socket.SOL_SOCKET, socket.SO_PASSCRED, 1) + sock.connect("/run/osbuild/api/osbuild") + req = {'method': 'setup-stdio'} + sock.send(json.dumps(req).encode('utf-8')) + msg, fds, _ = load_fds(sock, 1024) + for io in ['stdin', 'stdout', 'stderr']: + target = getattr(sys, io) + source = fds[msg[io]] + os.dup2(source, target.fileno()) + os.close(source) + + +if __name__ == "__main__": + setup_stdio() + + r = subprocess.run(sys.argv[1:], check=False) + sys.exit(r.returncode)