Skip to content

Commit 794e3d0

Browse files
script/build-with-container: add support for overlay dir
The source dir (aka homedir, default /ceph) is mounted in the container read-write. This is needed as the various ceph build scripts expect to write things into the tree - often this is in the build directory - but not always. This can lead to small messes and/or situations that are confusing to debug, especially if one is jumping between distros often. Add an option to use an overlay volume for the homedir - by default we enable a persistent overlay with a supplied "upper dir" where files that were written will appear. One can also enable a temporary overlay that forgets the writes when the container exits - maybe useful when doing experiments in 'interactive' mode. To use this option run the command with the `--overlay=<dir>` option. For example: `./src/script/build-with-container.py -b build.inner --overlay-dir build.ovr`. This will create a directory `build.ovr/content` automatically and all new files will appear there. For example the build directory will appear at `build.ovr/content/build.inner`. To use the temporary overlay use a `-` as the directory name. For example: `./src/script/build-with-container.py -b build.inner --overlay-dir -` Signed-off-by: John Mulligan <[email protected]>
1 parent 4208a73 commit 794e3d0

File tree

1 file changed

+52
-4
lines changed

1 file changed

+52
-4
lines changed

src/script/build-with-container.py

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -182,10 +182,16 @@ def _container_cmd(ctx, args, *, workdir=None, interactive=False):
182182
if workdir:
183183
cmd.append(f"--workdir={workdir}")
184184
cwd = pathlib.Path(".").absolute()
185-
cmd += [
186-
f"--volume={cwd}:{ctx.cli.homedir}:Z",
187-
f"-eHOMEDIR={ctx.cli.homedir}",
188-
]
185+
overlay = ctx.overlay()
186+
if overlay and overlay.temporary:
187+
cmd.append(f"--volume={cwd}:{ctx.cli.homedir}:O")
188+
elif overlay:
189+
cmd.append(
190+
f"--volume={cwd}:{ctx.cli.homedir}:O,upperdir={overlay.upper},workdir={overlay.work}"
191+
)
192+
else:
193+
cmd.append(f"--volume={cwd}:{ctx.cli.homedir}:Z")
194+
cmd.append(f"-eHOMEDIR={ctx.cli.homedir}")
189195
if ctx.cli.build_dir:
190196
cmd.append(f"-eBUILD_DIR={ctx.cli.build_dir}")
191197
if ctx.cli.ccache_dir:
@@ -356,6 +362,29 @@ def user_command(self):
356362
except DidNotExecute:
357363
pass
358364

365+
def overlay(self):
366+
if not self.cli.overlay_dir:
367+
return None
368+
overlay = Overlay(temporary=self.cli.overlay_dir == "-")
369+
if not overlay.temporary:
370+
obase = pathlib.Path(self.cli.overlay_dir).resolve()
371+
# you can't nest the workdir inside the upperdir at least on the
372+
# version of podman I tried. But the workdir does need to be on the
373+
# same FS according to the docs. So make the workdir and the upper
374+
# dir (content) siblings within the specified dir. podman doesn't
375+
# have the courtesy to manage the workdir automatically when
376+
# specifying upper dir.
377+
overlay.upper = obase / "content"
378+
overlay.work = obase / "work"
379+
return overlay
380+
381+
382+
class Overlay:
383+
def __init__(self, temporary=True, upper=None, work=None):
384+
self.temporary = temporary
385+
self.upper = upper
386+
self.work = work
387+
359388

360389
class Builder:
361390
"""Organize and manage the build steps."""
@@ -373,6 +402,8 @@ def wants(self, step, ctx, *, force=False, top=False):
373402
if step in self._did_steps:
374403
log.info("step already done: %s", step)
375404
return
405+
if not self._did_steps:
406+
prepare_env_once(ctx)
376407
self._steps[step](ctx)
377408
self._did_steps.add(step)
378409
log.info("step done: %s", step)
@@ -395,6 +426,14 @@ def docs(cls):
395426
yield str(step), getattr(func, "__doc__", "")
396427

397428

429+
def prepare_env_once(ctx):
430+
overlay = ctx.overlay()
431+
if overlay and not overlay.temporary:
432+
log.info("Creating overlay dirs: %s, %s", overlay.upper, overlay.work)
433+
overlay.upper.mkdir(parents=True, exist_ok=True)
434+
overlay.work.mkdir(parents=True, exist_ok=True)
435+
436+
398437
@Builder.set(Steps.DNF_CACHE)
399438
def dnf_cache_dir(ctx):
400439
"""Set up a DNF cache directory for reuse across container builds."""
@@ -745,6 +784,15 @@ def parse_cli(build_step_names):
745784
" (the ceph source root)"
746785
),
747786
)
787+
parser.add_argument(
788+
"--overlay-dir",
789+
"-l",
790+
help=(
791+
"Mount the homedir as an overlay volume using the given dir"
792+
"to host the overlay content and working dir. Specify '-' to"
793+
"use a temporary overlay (discarding writes on container exit)"
794+
),
795+
)
748796
parser.add_argument(
749797
"--ccache-dir",
750798
help=(

0 commit comments

Comments
 (0)