Skip to content

Commit

Permalink
Merge pull request #19 from plesk/check-service-can-be-enbaled
Browse files Browse the repository at this point in the history
Add function to check if service can be started
  • Loading branch information
SandakovMM authored Mar 27, 2024
2 parents 225eb4a + a58cb38 commit 9d42af2
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 5 deletions.
10 changes: 6 additions & 4 deletions pleskdistup/actions/systemd.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ class DisablePleskRelatedServicesDuringUpgrade(action.ActiveAction):
oneshot_services: typing.List[str]

def __init__(self):
self.name = "rule plesk services"
self.name = "disable plesk related services"
plesk_known_systemd_services = [
"crond.service",
"dovecot.service",
Expand All @@ -102,7 +102,9 @@ def __init__(self):
"sw-cp-server.service",
"sw-engine.service",
]
self.plesk_systemd_services = [service for service in plesk_known_systemd_services if systemd.is_service_exists(service)]
self.plesk_systemd_services = [
service for service in plesk_known_systemd_services if systemd.is_service_startable(service)
]

# Oneshot services are special, so they shouldn't be started on revert or after conversion, just enabled
self.oneshot_services = [
Expand All @@ -111,9 +113,9 @@ def __init__(self):

# We don't remove postfix service when remove it during qmail installation
# so we should choose the right smtp service, otherwise they will conflict
if systemd.is_service_exists("qmail.service"):
if systemd.is_service_startable("qmail.service"):
self.plesk_systemd_services.append("qmail.service")
elif systemd.is_service_exists("postfix.service"):
elif systemd.is_service_startable("postfix.service"):
self.plesk_systemd_services.append("postfix.service")

def _prepare_action(self) -> action.ActionResult:
Expand Down
55 changes: 54 additions & 1 deletion pleskdistup/common/src/systemd.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import typing
import subprocess

from . import dist, util
from . import dist, log, util

SYSTEMCTL_BIN_PATH = "/usr/bin/systemctl"
if dist.get_distro().deb_based:
Expand All @@ -24,6 +24,59 @@ def is_service_active(service: str):
return res.returncode == 0


def get_required_services(service: str) -> typing.List[str]:
res = subprocess.run(
[SYSTEMCTL_BIN_PATH, 'show', '--property', 'Requires', service],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
check=True,
universal_newlines=True
)

required_services = [service for service in res.stdout.split('s=')[1].split() if '.service' in service]
return required_services


def is_service_masked(service: str) -> bool:
res = subprocess.run(
[SYSTEMCTL_BIN_PATH, 'is-enabled', service],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
check=True,
universal_newlines=True
)
if res.stdout == 'masked':
return True
return False


def is_service_startable(
service: str,
already_checked: typing.Optional[typing.Set[str]] = None
) -> bool:
if not is_service_exists(service):
log.debug(f"Service '{service}' doesn't exist")
return False
if is_service_masked(service):
log.debug(f"Service '{service}' can't be started because it is masked")
return False

if already_checked is not None and service in already_checked:
return True

if already_checked is None:
already_checked = {service}
else:
already_checked.add(service)

required_services = get_required_services(service)
for required_service in required_services:
if not is_service_startable(required_service, already_checked):
log.debug(f"Service '{service}' can't be started because required service '{required_service}' doesn't exist")
return False
return True


def reload_systemd_daemon():
util.logged_check_call([SYSTEMCTL_BIN_PATH, "daemon-reload"])

Expand Down

0 comments on commit 9d42af2

Please sign in to comment.