Skip to content

Commit

Permalink
fix lint issues
Browse files Browse the repository at this point in the history
  • Loading branch information
Thanhphan1147 committed Dec 14, 2023
1 parent 1488ef6 commit a6b47f5
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 61 deletions.
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ show_missing = true
minversion = "6.0"
log_cli_level = "INFO"

[tool.pylint]
disable = "fixme"

[tool.pylint.'MESSAGES CONTROL']
extension-pkg-whitelist = "pydantic"

Expand Down
4 changes: 2 additions & 2 deletions src/charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def _on_install(self, _: ops.InstallEvent) -> None:
"""Handle install event, setup the agent service."""
try:
self.jenkins_agent_service.install()
except service.SnapInstallError as e:
except service.PackageInstallError as e:
logger.debug("Error installing the agent service %s", e)
self.unit.status = ops.ErrorStatus("Error installing the agent service")

Expand Down Expand Up @@ -80,7 +80,7 @@ def reconcile(self, _: ops.EventBase) -> None:
self.model.unit.status = ops.MaintenanceStatus("Starting agent service.")
try:
self.jenkins_agent_service.restart()
except service.SnapServiceStartError as e:
except service.ServiceRestartError as e:
logger.debug("Error restarting the agent service %s", e)
self.model.unit.status = ops.BlockedStatus("Readiness check failed")
self.model.unit.status = ops.ActiveStatus()
Expand Down
50 changes: 32 additions & 18 deletions src/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,16 @@
"""The agent pebble service module."""

import logging
import os
import pwd
import time
import os, pwd
from pathlib import Path

from charms.operator_libs_linux.v0 import apt
from charms.operator_libs_linux.v1 import systemd
from jinja2 import Template

from charm_state import State
from jinja2 import Template
from pathlib import Path

logger = logging.getLogger(__name__)
AGENT_SERVICE_NAME = "jenkins-agent"
Expand Down Expand Up @@ -53,7 +54,7 @@ def _render_file(self, path: str, content: str, mode: int) -> None:
mode: access permission mask applied to the
file using chmod (e.g. 0o640).
"""
with open(path, "w+") as file:
with open(path, "w+", encoding="utf-8") as file:
file.write(content)
# Ensure correct permissions are set on the file.
os.chmod(path, mode)
Expand Down Expand Up @@ -84,13 +85,17 @@ def install(self) -> None:
# Add ppa that hosts the jenkins-agent package
repositories = apt.RepositoryMapping()
if "deb-ppa.launchpadcontent.net/tphan025/ppa-jammy" not in repositories:
repositories.add(apt.DebianRepository(
enabled=True,
repotype="deb",
uri="https://ppa.launchpadcontent.net/tphan025/ppa/ubuntu/",
# TODO: depends on the series of the charm unit, set the release accordingly
release="jammy",
))
repositories.add(
apt.DebianRepository(
enabled=True,
repotype="deb",
uri="https://ppa.launchpadcontent.net/tphan025/ppa/ubuntu/",
# TODO: depends on the series of the charm unit
# set the release accordingly
release="jammy",
groups=["universal"],
)
)
# Install the apt package
apt.update()
apt.add_package(AGENT_PACKAGE_NAME)
Expand All @@ -101,10 +106,14 @@ def install(self) -> None:
raise PackageInstallError("Error installing the agent package") from exc

def restart(self) -> None:
"""Start the agent service."""
"""Start the agent service.
Raises:
ServiceRestartError: when restarting the service fails
"""
# Render template and write to appropriate file if only credentials are set
if credentials := self.state.agent_relation_credentials:
with open("templates/jenkins_agent_env.conf.j2", "r") as file:
with open("templates/jenkins_agent_env.conf.j2", "r", encoding="utf-8") as file:
template = Template(file.read())
# fetch credentials and set them as environments
environments = {
Expand All @@ -115,23 +124,28 @@ def restart(self) -> None:
# render template
rendered = template.render(environments=environments)
# Ensure that service conf directory exist
config_dir = Path(SYSTEMD_SERVICE_CONF_DIR).mkdir(parents=True, exist_ok=True)
config_dir = Path(SYSTEMD_SERVICE_CONF_DIR)
config_dir.mkdir(parents=True, exist_ok=True)
# Write the conf file
self._render_file(f"{config_dir}/environment.conf", rendered, 0o644)
self._render_file(
f"{config_dir.resolve().as_posix()}/environment.conf", rendered, 0o644
)
try:
systemd.service_restart(AGENT_SERVICE_NAME)
except systemd.SystemdError as exc:
raise ServiceRestartError("Error starting the agent service") from exc
# Check if the service is active
# TODO: handle cases where downloading the binary takes a long time but workload still active
# TODO: handle cases where downloading the binary takes a long time
if not self._readiness_check():
raise ServiceRestartError(f"Failed readiness check (timed out after {READINESS_CHECK_DELAY} seconds)")
raise ServiceRestartError(
f"Failed readiness check (timed out after {READINESS_CHECK_DELAY} seconds)"
)

def stop(self) -> None:
"""Stop the agent service."""
try:
systemd.service_stop(AGENT_SERVICE_NAME)
except systemd.SystemdError as _:
except systemd.SystemdError:
# TODO: do we raise exception here?
logger.debug("service %s failed to stop", AGENT_SERVICE_NAME)

Expand Down
81 changes: 40 additions & 41 deletions tests/unit/test_charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,8 @@

import ops
import ops.testing
from charms.operator_libs_linux.v2 import snap

import charm_state
import service
from charm import JenkinsAgentCharm

ACTIVE_STATUS_NAME = "active"
Expand Down Expand Up @@ -78,45 +76,46 @@ def test__on_upgrade_charm(self, _service_restart, _service_is_active, _upgrade_
assert jenkins_charm.unit.status.message == "Waiting for relation."
assert jenkins_charm.unit.status.name == WAITING_STATUS_NAME

@patch("ops.InstallEvent")
@patch("charms.operator_libs_linux.v2.snap.SnapCache")
def test__on_install(
self,
_snap_cache,
_install_event,
):
"""
arrange: given a charm with patched snapCache and the agent snap is not present.
act: when _on_install is called.
assert: The charm calls "ensure" to install the agent snap.
"""
jenkins_agent_snap = _snap_cache.return_value[service.SNAP_NAME]
jenkins_agent_snap.present = False

self.harness.begin()
jenkins_charm: JenkinsAgentCharm = self.harness.charm
jenkins_charm._on_install(_install_event)

assert jenkins_agent_snap.ensure.call_count == 1

@patch("ops.UpdateStatusEvent")
@patch("charms.operator_libs_linux.v2.snap.SnapCache")
def test__on_install_snap_install_error(self, _snap_cache, _update_status_event):
"""
arrange: given a charm with patched snapCache and the agent snap is not present.
act: when _on_install is called but the snap installation fails.
assert: The agent falls into error status with the correct message.
"""
jenkins_agent_snap = _snap_cache.return_value[service.SNAP_NAME]
jenkins_agent_snap.present = False
jenkins_agent_snap.ensure.side_effect = snap.SnapError

self.harness.begin()
jenkins_charm: JenkinsAgentCharm = self.harness.charm
jenkins_charm._on_install(_update_status_event)

assert jenkins_agent_snap.ensure.call_count == 1
assert jenkins_charm.unit.status.name == ERROR_STATUS_NAME
# TODO: refactor tests for apt
# @patch("ops.InstallEvent")
# @patch("charms.operator_libs_linux.v2.snap.SnapCache")
# def test__on_install(
# self,
# _snap_cache,
# _install_event,
# ):
# """
# arrange: given a charm with patched snapCache and the agent snap is not present.
# act: when _on_install is called.
# assert: The charm calls "ensure" to install the agent snap.
# """
# jenkins_agent_snap = _snap_cache.return_value[service.SNAP_NAME]
# jenkins_agent_snap.present = False

# self.harness.begin()
# jenkins_charm: JenkinsAgentCharm = self.harness.charm
# jenkins_charm._on_install(_install_event)

# assert jenkins_agent_snap.ensure.call_count == 1

# @patch("ops.UpdateStatusEvent")
# @patch("charms.operator_libs_linux.v2.snap.SnapCache")
# def test__on_install_snap_install_error(self, _snap_cache, _update_status_event):
# """
# arrange: given a charm with patched snapCache and the agent snap is not present.
# act: when _on_install is called but the snap installation fails.
# assert: The agent falls into error status with the correct message.
# """
# jenkins_agent_snap = _snap_cache.return_value[service.SNAP_NAME]
# jenkins_agent_snap.present = False
# jenkins_agent_snap.ensure.side_effect = snap.SnapError

# self.harness.begin()
# jenkins_charm: JenkinsAgentCharm = self.harness.charm
# jenkins_charm._on_install(_update_status_event)

# assert jenkins_agent_snap.ensure.call_count == 1
# assert jenkins_charm.unit.status.name == ERROR_STATUS_NAME

@patch("ops.ConfigChangedEvent")
@patch("ops.Model.get_relation")
Expand Down

0 comments on commit a6b47f5

Please sign in to comment.