diff --git a/cmdeploy/src/cmdeploy/basedeploy.py b/cmdeploy/src/cmdeploy/basedeploy.py index 45654c27..732ed049 100644 --- a/cmdeploy/src/cmdeploy/basedeploy.py +++ b/cmdeploy/src/cmdeploy/basedeploy.py @@ -1,6 +1,7 @@ import importlib.resources import io import os +from contextlib import contextmanager from pyinfra.operations import files, server, systemd @@ -10,6 +11,28 @@ def has_systemd(): return os.path.isdir("/run/systemd/system") +@contextmanager +def blocked_service_startup(): + """Prevent services from auto-starting during package installation. + + Installs a ``/usr/sbin/policy-rc.d`` that exits 101, blocking any + service from being started by the package manager. This avoids bind + conflicts and CPU/RAM spikes during initial setup. The file is removed + when the context exits. + """ + # For documentation about policy-rc.d, see: + # https://people.debian.org/~hmh/invokerc.d-policyrc.d-specification.txt + files.put( + src=get_resource("policy-rc.d"), + dest="/usr/sbin/policy-rc.d", + user="root", + group="root", + mode="755", + ) + yield + files.file("/usr/sbin/policy-rc.d", present=False) + + def get_resource(arg, pkg=__package__): return importlib.resources.files(pkg).joinpath(arg)