osbuild: add -l/--libdir parameter
Stop guessing if we're in the source directory by looking if a `stages`
subdirectory exists. Instead, assume that osbuild is installed on the
host.
If `--libdir` is given, mount the libdir into `/run/osbuild/lib` (alas,
we can't overwrite `/usr/libexec/osbuild`) and run osbuild from there.
Thus, running from source must now be done like this:
# python3 -m osbuild --libdir . [other args]
This commit is contained in:
parent
100dfd4f90
commit
5b50dec8c5
2 changed files with 16 additions and 23 deletions
|
|
@ -26,11 +26,6 @@ RESET = "\033[0m"
|
||||||
BOLD = "\033[1m"
|
BOLD = "\033[1m"
|
||||||
|
|
||||||
|
|
||||||
libdir = os.path.dirname(os.path.dirname(__file__))
|
|
||||||
if not os.path.exists(f"{libdir}/stages"):
|
|
||||||
libdir = f"{sys.prefix}/libexec/osbuild"
|
|
||||||
|
|
||||||
|
|
||||||
class StageFailed(Exception):
|
class StageFailed(Exception):
|
||||||
def __init__(self, name, returncode, output):
|
def __init__(self, name, returncode, output):
|
||||||
super(StageFailed, self).__init__()
|
super(StageFailed, self).__init__()
|
||||||
|
|
@ -103,7 +98,6 @@ class BuildRoot:
|
||||||
|
|
||||||
Its arguments mean the same as those for subprocess.run().
|
Its arguments mean the same as those for subprocess.run().
|
||||||
"""
|
"""
|
||||||
command = "/run/osbuild/" + os.path.basename(argv[0])
|
|
||||||
return subprocess.run([
|
return subprocess.run([
|
||||||
"systemd-nspawn",
|
"systemd-nspawn",
|
||||||
"--quiet",
|
"--quiet",
|
||||||
|
|
@ -113,15 +107,9 @@ class BuildRoot:
|
||||||
"--volatile=yes",
|
"--volatile=yes",
|
||||||
"--property=DeviceAllow=block-loop rw",
|
"--property=DeviceAllow=block-loop rw",
|
||||||
f"--directory={self.root}",
|
f"--directory={self.root}",
|
||||||
f"--bind={libdir}/osbuild-run:/run/osbuild/osbuild-run",
|
|
||||||
f"--bind-ro={libdir}/osbuild:/run/osbuild/osbuild",
|
|
||||||
*[f"--bind={b}" for b in (binds or [])],
|
*[f"--bind={b}" for b in (binds or [])],
|
||||||
*[f"--bind-ro={b}" for b in [argv[0] + ":" + command,
|
*[f"--bind-ro={b}" for b in [f"{self.api}:/run/osbuild/api"] + (readonly_binds or [])],
|
||||||
self.api + ":" + "/run/osbuild/api",
|
] + argv, **kwargs)
|
||||||
*(readonly_binds or [])]],
|
|
||||||
"/run/osbuild/osbuild-run",
|
|
||||||
command
|
|
||||||
] + argv[1:], **kwargs)
|
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def bound_socket(self, name):
|
def bound_socket(self, name):
|
||||||
|
|
@ -161,7 +149,7 @@ class Stage:
|
||||||
self.name = name
|
self.name = name
|
||||||
self.options = options
|
self.options = options
|
||||||
|
|
||||||
def run(self, tree, interactive=False, check=True):
|
def run(self, tree, interactive=False, check=True, libdir=None):
|
||||||
with BuildRoot() as buildroot:
|
with BuildRoot() as buildroot:
|
||||||
if interactive:
|
if interactive:
|
||||||
print_header(f"{self.name}: {self.id}", self.options)
|
print_header(f"{self.name}: {self.id}", self.options)
|
||||||
|
|
@ -171,9 +159,11 @@ class Stage:
|
||||||
"options": self.options,
|
"options": self.options,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
path = "/run/osbuild/lib" if libdir else "/usr/libexec/osbuild"
|
||||||
r = buildroot.run(
|
r = buildroot.run(
|
||||||
[f"{libdir}/stages/{self.name}"],
|
[f"{path}/osbuild-run", f"{path}/stages/{self.name}"],
|
||||||
binds=[f"{tree}:/run/osbuild/tree"],
|
binds=[f"{tree}:/run/osbuild/tree"],
|
||||||
|
readonly_binds=[f"{libdir}:{path}"] if libdir else [],
|
||||||
encoding="utf-8",
|
encoding="utf-8",
|
||||||
input=json.dumps(args),
|
input=json.dumps(args),
|
||||||
stdout=None if interactive else subprocess.PIPE,
|
stdout=None if interactive else subprocess.PIPE,
|
||||||
|
|
@ -194,7 +184,7 @@ class Assembler:
|
||||||
self.name = name
|
self.name = name
|
||||||
self.options = options
|
self.options = options
|
||||||
|
|
||||||
def run(self, tree, output_dir=None, interactive=False, check=True):
|
def run(self, tree, output_dir=None, interactive=False, check=True, libdir=None):
|
||||||
with BuildRoot() as buildroot:
|
with BuildRoot() as buildroot:
|
||||||
if interactive:
|
if interactive:
|
||||||
print_header(f"Assembling: {self.name}", self.options)
|
print_header(f"Assembling: {self.name}", self.options)
|
||||||
|
|
@ -210,12 +200,13 @@ class Assembler:
|
||||||
binds.append(f"{output_dir}:/run/osbuild/output")
|
binds.append(f"{output_dir}:/run/osbuild/output")
|
||||||
args["output_dir"] = "/run/osbuild/output"
|
args["output_dir"] = "/run/osbuild/output"
|
||||||
|
|
||||||
|
path = "/run/osbuild/lib" if libdir else "/usr/libexec/osbuild"
|
||||||
with buildroot.bound_socket("remoteloop") as sock, \
|
with buildroot.bound_socket("remoteloop") as sock, \
|
||||||
remoteloop.LoopServer(sock):
|
remoteloop.LoopServer(sock):
|
||||||
r = buildroot.run(
|
r = buildroot.run(
|
||||||
[f"{libdir}/assemblers/{self.name}"],
|
[f"{path}/osbuild-run", f"{path}/assemblers/{self.name}"],
|
||||||
binds=binds,
|
binds=binds,
|
||||||
readonly_binds=[f"{tree}:/run/osbuild/tree"],
|
readonly_binds=[f"{tree}:/run/osbuild/tree"] + ([f"{libdir}:{path}"] if libdir else []),
|
||||||
encoding="utf-8",
|
encoding="utf-8",
|
||||||
input=json.dumps(args),
|
input=json.dumps(args),
|
||||||
stdout=None if interactive else subprocess.PIPE,
|
stdout=None if interactive else subprocess.PIPE,
|
||||||
|
|
@ -244,7 +235,7 @@ class Pipeline:
|
||||||
def set_assembler(self, name, options=None):
|
def set_assembler(self, name, options=None):
|
||||||
self.assembler = Assembler(name, options or {})
|
self.assembler = Assembler(name, options or {})
|
||||||
|
|
||||||
def run(self, output_dir, objects=None, interactive=False, check=True):
|
def run(self, output_dir, objects=None, interactive=False, check=True, libdir=None):
|
||||||
os.makedirs("/run/osbuild", exist_ok=True)
|
os.makedirs("/run/osbuild", exist_ok=True)
|
||||||
if objects:
|
if objects:
|
||||||
os.makedirs(objects, exist_ok=True)
|
os.makedirs(objects, exist_ok=True)
|
||||||
|
|
@ -259,14 +250,14 @@ class Pipeline:
|
||||||
subprocess.run(["cp", "-a", f"{objects}/{self.base}/.", tree], check=True)
|
subprocess.run(["cp", "-a", f"{objects}/{self.base}/.", tree], check=True)
|
||||||
|
|
||||||
for stage in self.stages:
|
for stage in self.stages:
|
||||||
r = stage.run(tree, interactive, check)
|
r = stage.run(tree, interactive, check, libdir=libdir)
|
||||||
results["stages"].append(r)
|
results["stages"].append(r)
|
||||||
if r["returncode"] != 0:
|
if r["returncode"] != 0:
|
||||||
results["returncode"] = r["returncode"]
|
results["returncode"] = r["returncode"]
|
||||||
return results
|
return results
|
||||||
|
|
||||||
if self.assembler:
|
if self.assembler:
|
||||||
r = self.assembler.run(tree, output_dir, interactive, check)
|
r = self.assembler.run(tree, output_dir, interactive, check, libdir=libdir)
|
||||||
results["assembler"] = r
|
results["assembler"] = r
|
||||||
if r["returncode"] != 0:
|
if r["returncode"] != 0:
|
||||||
results["returncode"] = r["returncode"]
|
results["returncode"] = r["returncode"]
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,8 @@ def main():
|
||||||
parser.add_argument("--objects", metavar="DIRECTORY", type=os.path.abspath,
|
parser.add_argument("--objects", metavar="DIRECTORY", type=os.path.abspath,
|
||||||
default=".osbuild/objects",
|
default=".osbuild/objects",
|
||||||
help="the directory where intermediary os trees are stored")
|
help="the directory where intermediary os trees are stored")
|
||||||
|
parser.add_argument("-l", "--libdir", metavar="DIRECTORY", type=os.path.abspath,
|
||||||
|
help="the directory containing stages, assemblers, and the osbuild library")
|
||||||
requiredNamed = parser.add_argument_group('required named arguments')
|
requiredNamed = parser.add_argument_group('required named arguments')
|
||||||
requiredNamed.add_argument("-o", "--output", dest="output_dir", metavar="DIRECTORY", type=os.path.abspath,
|
requiredNamed.add_argument("-o", "--output", dest="output_dir", metavar="DIRECTORY", type=os.path.abspath,
|
||||||
help="provide the empty DIRECTORY as output argument to the last stage", required=True)
|
help="provide the empty DIRECTORY as output argument to the last stage", required=True)
|
||||||
|
|
@ -26,7 +28,7 @@ def main():
|
||||||
pipeline = osbuild.load(json.load(f))
|
pipeline = osbuild.load(json.load(f))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
pipeline.run(args.output_dir, args.objects, interactive=True)
|
pipeline.run(args.output_dir, args.objects, interactive=True, libdir=args.libdir)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
print()
|
print()
|
||||||
print(f"{RESET}{BOLD}{RED}Aborted{RESET}")
|
print(f"{RESET}{BOLD}{RED}Aborted{RESET}")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue