from mkosi.util import (
flatten,
flock,
+ flock_or_die,
format_rlimit,
make_executable,
one_zero,
if config.ephemeral:
fname = stack.enter_context(copy_ephemeral(config, config.output_dir_or_cwd() / config.output))
else:
- fname = config.output_dir_or_cwd() / config.output
+ fname = stack.enter_context(flock_or_die(config.output_dir_or_cwd() / config.output))
if config.output_format == OutputFormat.disk and args.verb == Verb.boot:
run(
remove_package_cache = args.force > 2
if outputs := list(config.output_dir_or_cwd().glob(f"{config.output}*")):
- with complete_step(f"Removing output files of {config.name()} image…"):
+ with (
+ complete_step(f"Removing output files of {config.name()} image…"),
+ flock_or_die(config.output_dir_or_cwd() / config.output)
+ if (config.output_dir_or_cwd() / config.output).exists()
+ else contextlib.nullcontext()
+ ):
rmtree(*outputs)
if remove_build_cache:
from mkosi.tree import copy_tree, rmtree
from mkosi.types import PathString
from mkosi.user import INVOKING_USER, become_root
-from mkosi.util import StrEnum, flatten
+from mkosi.util import StrEnum, flatten, flock, flock_or_die
from mkosi.versioncomp import GenericVersion
QEMU_KVM_DEVICE_VERSION = GenericVersion("9.0")
sandbox=config.sandbox,
)
- fork_and_wait(copy)
+ with flock(src):
+ fork_and_wait(copy)
yield tmp
finally:
def rm() -> None:
copy_ephemeral(config, config.output_dir_or_cwd() / config.output_with_compression)
)
else:
- fname = config.output_dir_or_cwd() / config.output_with_compression
+ fname = stack.enter_context(flock_or_die(config.output_dir_or_cwd() / config.output_with_compression))
if config.output_format == OutputFormat.disk and config.runtime_size:
run(
import contextlib
import copy
import enum
+import errno
import fcntl
import functools
import importlib
from types import ModuleType
from typing import Any, Callable, Optional, TypeVar, no_type_check
+from mkosi.log import die
from mkosi.types import PathString
T = TypeVar("T")
os.close(fd)
+@contextlib.contextmanager
+def flock_or_die(path: Path) -> Iterator[Path]:
+ try:
+ with flock(path, fcntl.LOCK_EX|fcntl.LOCK_NB):
+ yield path
+ except OSError as e:
+ if e.errno != errno.EWOULDBLOCK:
+ raise e
+
+ die(f"Cannot lock {path} as it is locked by another process",
+ hint="Maybe another mkosi process is still using it?")
+
+
@contextlib.contextmanager
def scopedenv(env: Mapping[str, Any]) -> Iterator[None]:
old = copy.deepcopy(os.environ)
)
from mkosi.run import run
from mkosi.types import PathString
+from mkosi.util import flock_or_die
def run_vmspawn(args: Args, config: Config) -> None:
if config.ephemeral:
fname = stack.enter_context(copy_ephemeral(config, config.output_dir_or_cwd() / config.output))
else:
- fname = config.output_dir_or_cwd() / config.output
+ fname = stack.enter_context(flock_or_die(config.output_dir_or_cwd() / config.output))
if config.output_format == OutputFormat.disk and config.runtime_size:
run(