Skip to content

Commit

Permalink
Add option to save the BuildSourcesEphemeral overlay.
Browse files Browse the repository at this point in the history
  • Loading branch information
behrmann committed Jan 22, 2025
1 parent 0df7ef3 commit 73e6844
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 16 deletions.
22 changes: 18 additions & 4 deletions mkosi/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,15 @@ def __bool__(self) -> bool:
return self != Incremental.no


class BuildSourcesEphemeral(StrEnum):
yes = enum.auto()
no = enum.auto()
buildcache = enum.auto()

def __bool__(self) -> bool:
return self != BuildSourcesEphemeral.no


class Architecture(StrEnum):
alpha = enum.auto()
arc = enum.auto()
Expand Down Expand Up @@ -1897,7 +1906,7 @@ class Config:
repart_offline: bool
history: bool
build_sources: list[ConfigTree]
build_sources_ephemeral: bool
build_sources_ephemeral: BuildSourcesEphemeral
environment: dict[str, str]
environment_files: list[Path]
with_tests: bool
Expand Down Expand Up @@ -3360,11 +3369,15 @@ def parse_ini(path: Path, only_sections: Collection[str] = ()) -> Iterator[tuple
),
ConfigSetting(
dest="build_sources_ephemeral",
metavar="BOOL",
nargs="?",
section="Build",
parse=config_parse_boolean,
parse=config_make_enum_parser_with_boolean(
BuildSourcesEphemeral, yes=BuildSourcesEphemeral.yes, no=BuildSourcesEphemeral.no
),
default=BuildSourcesEphemeral.no,
help="Make build sources ephemeral when running scripts",
scope=SettingScope.universal,
choices=BuildSourcesEphemeral.values(),
),
ConfigSetting(
dest="environment",
Expand Down Expand Up @@ -4943,7 +4956,7 @@ def summary(config: Config) -> str:
Repart Offline: {yes_no(config.repart_offline)}
Save History: {yes_no(config.history)}
Build Sources: {line_join_list(config.build_sources)}
Build Sources Ephemeral: {yes_no(config.build_sources_ephemeral)}
Build Sources Ephemeral: {config.build_sources_ephemeral}
Script Environment: {line_join_list(env)}
Environment Files: {line_join_list(config.environment_files)}
Run Tests in Build Scripts: {yes_no(config.with_tests)}
Expand Down Expand Up @@ -5134,6 +5147,7 @@ def uki_profile_transformer(
Firmware: enum_transformer,
SecureBootSignTool: enum_transformer,
Incremental: enum_transformer,
BuildSourcesEphemeral: enum_transformer,
Optional[Distribution]: optional_enum_transformer,
list[ManifestFormat]: enum_list_transformer,
Verb: enum_transformer,
Expand Down
22 changes: 16 additions & 6 deletions mkosi/mounts.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
import tempfile
from collections.abc import Iterator, Sequence
from pathlib import Path
from typing import Optional
from typing import Optional, Union

from mkosi.config import Config
from mkosi.config import BuildSourcesEphemeral, Config
from mkosi.sandbox import OverlayOperation
from mkosi.util import PathString, flatten

Expand Down Expand Up @@ -56,20 +56,30 @@ def mount_overlay(


@contextlib.contextmanager
def finalize_source_mounts(config: Config, *, ephemeral: bool) -> Iterator[list[PathString]]:
def finalize_source_mounts(
config: Config,
*,
ephemeral: Union[BuildSourcesEphemeral, bool],
) -> Iterator[list[PathString]]:
with contextlib.ExitStack() as stack:
options: list[PathString] = []

for t in config.build_sources:
src, dst = t.with_prefix("/work/src")

if ephemeral:
upperdir = Path(stack.enter_context(tempfile.TemporaryDirectory(prefix="volatile-overlay")))
os.chmod(upperdir, src.stat().st_mode)
if ephemeral == BuildSourcesEphemeral.buildcache and config.build_dir is not None:
upperdir = config.build_dir / f"mkosi.buildovl.{src.name}"
upperdir.mkdir(mode=src.stat().st_mode, exist_ok=True)
else:
upperdir = Path(
stack.enter_context(tempfile.TemporaryDirectory(prefix="volatile-overlay."))
)
os.chmod(upperdir, src.stat().st_mode)

workdir = Path(
stack.enter_context(
tempfile.TemporaryDirectory(dir=upperdir.parent, prefix=f"{upperdir.name}-workdir")
tempfile.TemporaryDirectory(dir=upperdir.parent, prefix=f"{upperdir.name}-workdir.")
)
)

Expand Down
12 changes: 8 additions & 4 deletions mkosi/resources/man/mkosi.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -1476,12 +1476,16 @@ boolean argument: either `1`, `yes`, or `true` to enable, or `0`, `no`,
working directory is mounted to `/work/src`.

`BuildSourcesEphemeral=`, `--build-sources-ephemeral=`
: Takes a boolean. Disabled by default. Configures whether changes to
source directories (the working directory and configured using
`BuildSources=`) are persisted. If enabled, all source directories
will be reset to their original state every time after running all
: Takes a boolean or the special value `buildcache`. Disabled by default. Configures whether changes to
source directories, the working directory and configured using `BuildSources=`, are persisted. If
enabled, all source directories will be reset to their original state every time after running all
scripts of a specific type (except sync scripts).

💥💣💥 If set to `buildcache` the overlay is not discarded when running build scripts, but saved to the
build directory, configured via `BuildDirectory=`, and will be reused on subsequent runs. The overlay is
still discarded for all other scripts. This option can be used to implement more advanced caching of
builds, but can lead to unexpected states of the source directory. 💥💣💥

`Environment=`, `--environment=`
: Adds variables to the environment that package managers and the
prepare/build/postinstall/finalize scripts are executed with. Takes
Expand Down
5 changes: 3 additions & 2 deletions tests/test_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
ArtifactOutput,
BiosBootloader,
Bootloader,
BuildSourcesEphemeral,
Cacheonly,
CertificateSource,
CertificateSourceType,
Expand Down Expand Up @@ -117,7 +118,7 @@ def test_config() -> None:
"Target": "/frob"
}
],
"BuildSourcesEphemeral": true,
"BuildSourcesEphemeral": "yes",
"CDROM": false,
"CPUs": 2,
"CacheDirectory": "/is/this/the/cachedir",
Expand Down Expand Up @@ -424,7 +425,7 @@ def test_config() -> None:
build_dir=None,
build_packages=["pkg1", "pkg2"],
build_scripts=[Path("/path/to/buildscript")],
build_sources_ephemeral=True,
build_sources_ephemeral=BuildSourcesEphemeral.yes,
build_sources=[ConfigTree(Path("/qux"), Path("/frob"))],
cache_dir=Path("/is/this/the/cachedir"),
cacheonly=Cacheonly.always,
Expand Down

0 comments on commit 73e6844

Please sign in to comment.