Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions src/pyinfra/facts/bsdinit.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

from typing_extensions import override

from pyinfra.api import FactBase

from .sysvinit import InitdStatus


Expand All @@ -21,3 +23,23 @@ def command(self) -> str:
"""

default = dict


class RcdEnabled(FactBase):
"""
Returns a dict of OpenBSD rc.d services enabled at boot.
"""

default = dict

@override
def requires_command(self) -> str:
return "rcctl"

@override
def command(self) -> str:
return "rcctl ls on"

@override
def process(self, output: list[str]) -> dict[str, bool]:
return {line: True for line in output}
38 changes: 34 additions & 4 deletions src/pyinfra/operations/bsdinit.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,33 @@
from __future__ import annotations

from pyinfra import host
from pyinfra.api import operation
from pyinfra.facts.bsdinit import RcdStatus
from pyinfra.api import QuoteString, StringCommand, operation
from pyinfra.facts.bsdinit import RcdEnabled, RcdStatus
from pyinfra.facts.server import Os

from . import files
from .util.service import handle_service_control


def _handle_openbsd_enabled(service: str, enabled: bool):
enabled_services = host.get_fact(RcdEnabled)
is_enabled = enabled_services.get(service, False)

if enabled is True:
if not is_enabled:
yield StringCommand("rcctl enable", QuoteString(service))
enabled_services[service] = True
else:
host.noop(f"service {service} is enabled")

if enabled is False:
if is_enabled:
yield StringCommand("rcctl disable", QuoteString(service))
enabled_services[service] = False
else:
host.noop(f"service {service} is disabled")


@operation()
def service(
service: str,
Expand All @@ -33,22 +52,33 @@ def service(
+ enabled: whether this service should be enabled/disabled on boot
"""

os = host.get_fact(Os)
status_argument = "status"
if host.get_fact(Os) == "OpenBSD":
command_formatter = "test -e /etc/rc.d/{0} && /etc/rc.d/{0} {1} || /usr/local/etc/rc.d/{0} {1}"
if os == "OpenBSD":
status_argument = "check"
command_formatter = "rcctl {1} {0}"

if enabled is True:
yield from _handle_openbsd_enabled(service, enabled)

yield from handle_service_control(
host,
service,
host.get_fact(RcdStatus),
"test -e /etc/rc.d/{0} && /etc/rc.d/{0} {1} || /usr/local/etc/rc.d/{0} {1}",
command_formatter,
running,
restarted,
reloaded,
command,
status_argument=status_argument,
)

if os == "OpenBSD":
if enabled is False:
yield from _handle_openbsd_enabled(service, enabled)
return

# BSD init is simple, just add/remove <service>_enabled="YES"
if isinstance(enabled, bool):
yield from files.line._inner(
Expand Down
8 changes: 8 additions & 0 deletions tests/facts/bsdinit.RcdEnabled/services.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
command: rcctl ls on
requires_command: rcctl
output: |
cron
rad
fact:
cron: true
rad: true
12 changes: 12 additions & 0 deletions tests/operations/bsdinit.service/openbsd_disabled.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
args:
- rad
kwargs:
enabled: false
facts:
server.Os: OpenBSD
bsdinit.RcdStatus:
rad: true
bsdinit.RcdEnabled:
rad: true
commands:
- rcctl disable rad
12 changes: 12 additions & 0 deletions tests/operations/bsdinit.service/openbsd_enabled_start.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
args:
- rad
kwargs:
enabled: true
facts:
server.Os: OpenBSD
bsdinit.RcdStatus:
rad: false
bsdinit.RcdEnabled: {}
commands:
- rcctl enable rad
- rcctl start rad
Loading