to make sure the repository metadata in `/mkosi` is not cleaned up,
otherwise any extension images using this image as their base tree
will not be able to install additional packages.
+- Implemented `CacheOnly=metadata`. Note that in the JSON output, the
+ value of `CacheOnly=` will now be a string instead of a boolean.
## v20.2
"--output", output,
"--workspace-dir=/var/tmp",
"--package-cache-dir=/var",
+ "--cache-only=metadata",
"--output-dir", context.staging_area,
"--extra-tree", f"/usr/lib/modules/{context.kernel_version}:/usr/lib/modules/{context.kernel_version}",
"--extra-tree=/usr/lib/firmware:/usr/lib/firmware",
Args,
BiosBootloader,
Bootloader,
+ Cacheonly,
Compression,
Config,
ConfigFeature,
*(["--compress-output", str(context.config.compress_output)] if context.config.compress_output else []),
"--compress-level", str(context.config.compress_level),
"--with-network", str(context.config.with_network),
- "--cache-only", str(context.config.cache_only),
+ "--cache-only", str(context.config.cacheonly),
"--output-dir", str(context.workspace / "initrd"),
*(["--workspace-dir", str(context.config.workspace_dir)] if context.config.workspace_dir else []),
*(["--cache-dir", str(context.config.cache_dir)] if context.config.cache_dir else []),
*(["--release", config.tools_tree_release] if config.tools_tree_release else []),
*(["--mirror", config.tools_tree_mirror] if config.tools_tree_mirror else []),
"--repository-key-check", str(config.repository_key_check),
- "--cache-only", str(config.cache_only),
+ "--cache-only", str(config.cacheonly),
*(["--output-dir", str(config.output_dir)] if config.output_dir else []),
*(["--workspace-dir", str(config.workspace_dir)] if config.workspace_dir else []),
*(["--cache-dir", str(config.cache_dir)] if config.cache_dir else []),
def sync_repository_metadata(args: Args, config: Config, *, resources: Path) -> None:
- if have_cache(config) or config.cache_only or config.base_trees:
+ if have_cache(config) or config.cacheonly != Cacheonly.none or config.base_trees:
return
with (
unsigned = enum.auto()
+class Cacheonly(StrEnum):
+ always = enum.auto()
+ none = enum.auto()
+ metadata = enum.auto()
+
+
class QemuFirmware(StrEnum):
auto = enum.auto()
linux = enum.auto()
return [f"console={namespace.architecture.default_serial_tty()}"]
-def make_enum_parser(type: type[enum.Enum]) -> Callable[[str], enum.Enum]:
- def parse_enum(value: str) -> enum.Enum:
+def make_enum_parser(type: type[StrEnum]) -> Callable[[str], StrEnum]:
+ def parse_enum(value: str) -> StrEnum:
try:
return type(value)
except ValueError:
return parse_enum
-def config_make_enum_parser(type: type[enum.Enum]) -> ConfigParseCallback:
- def config_parse_enum(value: Optional[str], old: Optional[enum.Enum]) -> Optional[enum.Enum]:
+def config_make_enum_parser(type: type[StrEnum]) -> ConfigParseCallback:
+ def config_parse_enum(value: Optional[str], old: Optional[StrEnum]) -> Optional[StrEnum]:
return make_enum_parser(type)(value) if value else None
return config_parse_enum
-def config_make_enum_matcher(type: type[enum.Enum]) -> ConfigMatchCallback:
- def config_match_enum(match: str, value: enum.Enum) -> bool:
+def config_make_enum_parser_with_boolean(type: type[StrEnum], *, yes: StrEnum, no: StrEnum) -> ConfigParseCallback:
+ def config_parse_enum(value: Optional[str], old: Optional[StrEnum]) -> Optional[StrEnum]:
+ if not value:
+ return None
+
+ if value in type.values():
+ return type(value)
+
+ return yes if parse_boolean(value) else no
+
+ return config_parse_enum
+
+
+def config_make_enum_matcher(type: type[StrEnum]) -> ConfigMatchCallback:
+ def config_match_enum(match: str, value: StrEnum) -> bool:
return make_enum_parser(type)(match) == value
return config_match_enum
local_mirror: Optional[str]
repository_key_check: bool
repositories: list[str]
- cache_only: bool
+ cacheonly: Cacheonly
package_manager_trees: list[ConfigTree]
output_format: OutputFormat
help="Repositories to use",
),
ConfigSetting(
- dest="cache_only",
- metavar="BOOL",
+ dest="cacheonly",
+ long="--cache-only",
+ name="CacheOnly",
+ metavar="CACHEONLY",
section="Distribution",
- parse=config_parse_boolean,
+ parse=config_make_enum_parser_with_boolean(Cacheonly, yes=Cacheonly.always, no=Cacheonly.none),
+ default=Cacheonly.none,
help="Only use the package cache when installing packages",
),
ConfigSetting(
Local Mirror (build): {none_to_none(config.local_mirror)}
Repo Signature/Key check: {yes_no(config.repository_key_check)}
Repositories: {line_join_list(config.repositories)}
- Use Only Package Cache: {yes_no(config.cache_only)}
+ Use Only Package Cache: {config.cacheonly}
Package Manager Trees: {line_join_tree_list(config.package_manager_trees)}
{bold("OUTPUT")}:
DocFormat: enum_transformer,
list[QemuDrive]: config_drive_transformer,
GenericVersion: generic_version_transformer,
+ Cacheonly: enum_transformer,
}
def json_transformer(key: str, val: Any) -> Any:
from collections.abc import Iterable, Sequence
from pathlib import Path
-from mkosi.config import Config
+from mkosi.config import Cacheonly, Config
from mkosi.context import Context
from mkosi.installer import PackageManager
from mkosi.installer.rpm import RpmRepository, fixup_rpmdb_location, rpm_cmd, setup_rpm
opt = "--enable-repo" if dnf.endswith("dnf5") else "--enablerepo"
cmdline += [f"{opt}={repo}" for repo in context.config.repositories]
- if context.config.cache_only:
+ if context.config.cacheonly == Cacheonly.always:
cmdline += ["--cacheonly"]
else:
cmdline += ["--setopt=metadata_expire=never"]
`CacheOnly=`, `--cache-only=`
-: If specified, the package manager is instructed not to contact the
- network for updating package data. This provides a minimal level of
- reproducibility, as long as the package cache is already fully
- populated.
+: Takes one of `none`, `metadata` or `always`. If `always`, the package
+ manager is instructed not to contact the network. This provides a
+ minimal level of reproducibility, as long as the package cache is
+ already fully populated. If set to `metadata`, the package manager can
+ still download packages, but we won't sync the repository metadata. If
+ set to `none`, the repository metadata is synced and packages can be
+ downloaded during the build.
`PackageManagerTrees=`, `--package-manager-tree=`
Args,
BiosBootloader,
Bootloader,
+ Cacheonly,
Compression,
Config,
ConfigFeature,
],
"BuildSourcesEphemeral": true,
"CacheDirectory": "/is/this/the/cachedir",
- "CacheOnly": true,
+ "CacheOnly": "always",
"Checksum": false,
"CleanPackageMetadata": "auto",
"CompressLevel": 3,
build_sources = [ConfigTree(Path("/qux"), Path("/frob"))],
build_sources_ephemeral = True,
cache_dir = Path("/is/this/the/cachedir"),
- cache_only = True,
+ cacheonly = Cacheonly.always,
checksum = False,
clean_package_metadata = ConfigFeature.auto,
compress_level = 3,