Operator Libs Linux

  • By Jon Seager
Channel Revision Published Runs on
latest/stable 2 09 Mar 2023
Ubuntu 22.04
juju deploy operator-libs-linux
Show information

Platform:

Ubuntu
22.04

charms.operator_libs_linux.v0.juju_systemd_notices

Library for utilizing systemd to observe and emit notices when services change state.

This library provides both the public API for observing systemd services from within charmed operators, and utilities for running a minimal juju-systemd-notices daemon that watches observed services running on the machine. The juju-systemd-notices daemon watches observed services using DBus; it observes messages received on the DBus message bus and evaluates the contents of the messages to determine if a service state-change event must be emitted.

How to use within a charmed operator (machine only)

Here is an example of subscribing a charmed operator to observe the state of an internal systemd service and handle events based on the current emitted state:

from charms.operator_libs_linux.v0.juju_systemd_notices import (
    ServiceStartedEvent,
    ServiceStoppedEvent,
    SystemdNotices,
)


class ApplicationCharm(CharmBase):
    # Application charm that needs to observe the state of an internal service.

    def __init__(self, *args, **kwargs) -> None:
        super().__init__(*args, **kwargs)

        # Register services with charm. This adds the events to observe.
        self._systemd_notices = SystemdNotices(self, ["slurmd"])
        self.framework.observe(self.on.install, self._on_install)
        self.framework.observe(self.on.stop, self._on_stop)
        self.framework.observe(self.on.service_slurmd_started, self._on_slurmd_started)
        self.framework.observe(self.on.service_slurmd_stopped, self._on_slurmd_stopped)

    def _on_install(self, _: InstallEvent) -> None:
        # Subscribe the charmed operator to the services on the machine.
        # .subscribe() configures the notices hooks and starts the juju-systemd-notices daemon.
        # The juju-systemd-notices daemon is per unit. This means that the unit name will be
        # meshed into the service name. E.g. juju-systemd-notices becomes
        # juju-{unit_name}-{unit_number}-systemd-notices.
        self._systemd_notices.subscribe()

    def _on_start(self, _: StartEvent) -> None:
        # This will trigger the juju-systemd-notices daemon to
        # emit a `service-slurmd-started` event.
        systemd.service_start("slurmd")

    def _on_stop(self, _: StopEvent) -> None:
        # To stop the juju-systemd-notices service running in the background.
        # .stop() also disables the juju-systemd-notices so that it does not
        # start back up if the underlying machine is rebooted.
        self._systemd_notices.stop()

    def _on_slurmd_started(self, _: ServiceStartedEvent) -> None:
        self.unit.status = ActiveStatus()
        time.sleep(60)

        # This will trigger the juju-systemd-notices daemon to
        # emit a `service-slurmd-stopped` event.
        systemd.service_stop("slurmd")

    def _on_slurmd_stopped(self, _: ServiceStoppedEvent) -> None:
        self.unit.status = BlockedStatus("slurmd not running")

class ServiceStartedEvent

Description

Event emitted when service has started. None

class ServiceStoppedEvent

Description

Event emitted when service has stopped. None

class SystemdNotices

Description

Observe systemd services on your machine base. None

Methods

SystemdNotices. __init__( self , charm: CharmBase , services )

Description

Instantiate systemd notices service. None

SystemdNotices. subscribe( self )

Description

Subscribe charmed operator to observe status of systemd services. None

SystemdNotices. stop( self )

Description

Stop charmed operator from observing the status of subscribed services. None