Skip to content

Commit

Permalink
ISD-1307 Update permission when mounting storage (#63)
Browse files Browse the repository at this point in the history
  • Loading branch information
Thanhphan1147 authored Nov 21, 2023
1 parent 9d33107 commit 3e4c253
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 1 deletion.
26 changes: 26 additions & 0 deletions src/charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ def __init__(self, *args: typing.Any):
self.ingress_observer = ingress.Observer(self)
self.framework.observe(self.on.jenkins_pebble_ready, self._on_jenkins_pebble_ready)
self.framework.observe(self.on.get_admin_password_action, self._on_get_admin_password)
self.framework.observe(
self.on.jenkins_home_storage_attached, self._on_jenkins_home_storage_attached
)
self.framework.observe(self.on.update_status, self._on_update_status)

def _get_pebble_layer(self, jenkins_env: jenkins.Environment) -> ops.pebble.Layer:
Expand Down Expand Up @@ -191,6 +194,29 @@ def _on_update_status(self, _: ops.UpdateStatusEvent) -> None:

self.unit.status = self._remove_unlisted_plugins(container=container)

def _on_jenkins_home_storage_attached(self, event: ops.StorageAttachedEvent) -> None:
"""Correctly set permission when storage is attached.
Args:
event: The event fired when the storage is attached.
"""
container = self.unit.get_container(self.state.jenkins_service_name)
if not container.can_connect():
event.defer()
return

command = [
"chown",
"-R",
f"{jenkins.USER}:{jenkins.GROUP}",
str(event.storage.location.resolve()),
]

container.exec(
command,
timeout=120,
).wait()


if __name__ == "__main__": # pragma: nocover
ops.main.main(JenkinsK8sOperatorCharm)
16 changes: 16 additions & 0 deletions tests/integration/test_jenkins.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,19 @@ async def test_storage_mount(
assert action.results.get("return-code") == 0
# Remove leading and trailing newline since jenkins client autoformat config
assert job_configuration.strip("\n") in str(action.results.get("stdout"))


async def test_storage_mount_owner(application: Application):
"""
arrange: after Jenkins charm has been deployed and storage mounted.
act: get jenkins_home directory owner.
assert: jenkins_home belongs to jenkins user.
"""
jenkins_unit: Unit = application.units[0]
command = 'stat --printf="%u" /var/lib/jenkins'

action: Action = await jenkins_unit.run(command=command, timeout=60)
await action.wait()

assert action.results.get("return-code") == 0
assert "2000" in str(action.results.get("stdout"))
49 changes: 48 additions & 1 deletion tests/unit/test_charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from charm import JenkinsK8sOperatorCharm

from .helpers import ACTIVE_STATUS_NAME, BLOCKED_STATUS_NAME
from .types_ import HarnessWithContainer
from .types_ import Harness, HarnessWithContainer


@pytest.mark.parametrize(
Expand Down Expand Up @@ -358,3 +358,50 @@ def test__on_update_status(
jenkins_charm._on_update_status(MagicMock(spec=ops.UpdateStatusEvent))

assert jenkins_charm.unit.status == expected_status


def test__on_jenkins_home_storage_attached(harness: Harness, monkeypatch: pytest.MonkeyPatch):
"""
arrange: given a base jenkins charm.
act: when _on_jenkins_home_storage_attached is called.
assert: The chown command was ran on the jenkins container with correct parameters.
"""
harness.begin()
jenkins_charm = typing.cast(JenkinsK8sOperatorCharm, harness.charm)
container = jenkins_charm.unit.containers["jenkins"]
harness.set_can_connect(container, True)
# We don't use harness.handle_exec here because we want to assert
# the parameters passed to exec()
exec_handler = MagicMock()
monkeypatch.setattr(container, "exec", exec_handler)

event = MagicMock()
mock_jenkins_home_path = "/var/lib/jenkins"
event.storage.location.resolve = lambda: mock_jenkins_home_path
jenkins_charm._on_jenkins_home_storage_attached(event)

exec_handler.assert_called_once_with(
["chown", "-R", "jenkins:jenkins", mock_jenkins_home_path], timeout=120
)


def test__on_jenkins_home_storage_attached_container_not_ready(
harness: Harness, monkeypatch: pytest.MonkeyPatch
):
"""
arrange: given a base jenkins charm with container not ready.
act: when _on_jenkins_home_storage_attached is called.
assert: The chown command was not ran.
"""
harness.begin()
jenkins_charm = typing.cast(JenkinsK8sOperatorCharm, harness.charm)
container = jenkins_charm.unit.containers["jenkins"]
harness.set_can_connect(container, False)
# We don't use harness.handle_exec here because we want to assert
# whether exec() was called
exec_handler = MagicMock()
monkeypatch.setattr(container, "exec", exec_handler)

jenkins_charm._on_jenkins_home_storage_attached(MagicMock())

exec_handler.assert_not_called()

0 comments on commit 3e4c253

Please sign in to comment.