Merge ~mertkirpici/charm-logrotated:lp/2017795 into charm-logrotated:master

Proposed by Mert Kirpici
Status: Merged
Approved by: Mert Kirpici
Approved revision: 7316795355629d4ebcfe8a2b76f5faf0f5b07d23
Merged at revision: 55f7ed6f91b9a56f0241e68a4ef5c6cd75fd5492
Proposed branch: ~mertkirpici/charm-logrotated:lp/2017795
Merge into: charm-logrotated:master
Diff against target: 218 lines (+118/-22)
5 files modified
src/lib/lib_cron.py (+18/-19)
src/tests/functional/test_logrotate.py (+21/-0)
src/tests/unit/conftest.py (+7/-1)
src/tests/unit/requirements.txt (+1/-1)
src/tests/unit/test_logrotate.py (+71/-1)
Reviewer Review Type Date Requested Status
🤖 prod-jenkaas-bootstack (community) continuous-integration Approve
Chi Wai CHAN Approve
Erhan Sunar (community) Approve
BootStack Reviewers Pending
Review via email: mp+442359@code.launchpad.net

Commit message

LP #2017795

Description of the change

fix: cleanup old cronjobs upon config change

    A change in cronjob frequency used to leave the old cronjobs behind,
    causing unnecessary execution. This patch is mitigating that behavior
    and also adds some tests.

To post a comment you must log in.
Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote :

This merge proposal is being monitored by mergebot. Change the status to Approved to merge.

Revision history for this message
🤖 prod-jenkaas-bootstack (prod-jenkaas-bootstack) wrote :
review: Approve (continuous-integration)
Revision history for this message
Erhan Sunar (esunar) wrote :

LGTM

review: Approve
Revision history for this message
Chi Wai CHAN (raychan96) wrote :

LGTM

review: Approve
Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote :

Failed to merge change (unable to merge source repository due to conflicts), setting status to needs review.

Revision history for this message
🤖 prod-jenkaas-bootstack (prod-jenkaas-bootstack) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
🤖 prod-jenkaas-bootstack (prod-jenkaas-bootstack) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
🤖 prod-jenkaas-bootstack (prod-jenkaas-bootstack) wrote :
review: Approve (continuous-integration)
Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote :

Change successfully merged at revision 55f7ed6f91b9a56f0241e68a4ef5c6cd75fd5492

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/src/lib/lib_cron.py b/src/lib/lib_cron.py
index be3dff9..1f30ddc 100644
--- a/src/lib/lib_cron.py
+++ b/src/lib/lib_cron.py
@@ -48,13 +48,13 @@ class CronHelper:
48 If logrotate-cronjob config option is set to True install cronjob,48 If logrotate-cronjob config option is set to True install cronjob,
49 otherwise cleanup.49 otherwise cleanup.
50 """50 """
51 clean_up_file = self.cronjob_frequency if self.cronjob_enabled else -151 self.cleanup_cronjob_files()
5252
53 if self.cronjob_enabled is True:53 if self.cronjob_enabled is True:
54 cronjob_path = os.path.realpath(__file__)54 cronjob_path = os.path.realpath(__file__)
55 cron_file_path = (55 cron_file_path = (
56 self.cronjob_base_path56 self.cronjob_base_path
57 + self.cronjob_check_paths[clean_up_file]57 + self.cronjob_check_paths[self.cronjob_frequency]
58 + "/"58 + "/"
59 + self.cronjob_logrotate_cron_file59 + self.cronjob_logrotate_cron_file
60 )60 )
@@ -73,25 +73,24 @@ class CronHelper:
73 os.chmod(cron_file_path, 700)73 os.chmod(cron_file_path, 700)
7474
75 # update cron.daily schedule if logrotate-cronjob-frequency set to "daily"75 # update cron.daily schedule if logrotate-cronjob-frequency set to "daily"
76 if self.validate_cron_conf() and self.cronjob_frequency == 1:76 if self.cronjob_frequency == 1 and self.validate_cron_conf():
77 self.update_cron_daily_schedule()77 self.update_cron_daily_schedule()
78 else:
79 self.cleanup_etc_config()
7880
79 self.cleanup_cronjob(clean_up_file)81 def cleanup_cronjob_files(self):
8082 """Cleanup previous cronjob files."""
81 def cleanup_cronjob(self, frequency=-1):83 for check_path in self.cronjob_check_paths:
82 """Cleanup previous config."""84 path = os.path.join(
83 if frequency == -1:85 self.cronjob_base_path + check_path, self.cronjob_logrotate_cron_file
84 for check_path in self.cronjob_check_paths:86 )
85 path = (87 if os.path.exists(path):
86 self.cronjob_base_path88 os.remove(path)
87 + check_path89
88 + "/"90 def cleanup_etc_config(self):
89 + self.cronjob_logrotate_cron_file91 """Cleanup the saved config in /etc directory."""
90 )92 if os.path.exists(self.cronjob_etc_config):
91 if os.path.exists(path):93 os.remove(self.cronjob_etc_config)
92 os.remove(path)
93 if os.path.exists(self.cronjob_etc_config):
94 os.remove(self.cronjob_etc_config)
9594
96 def update_logrotate_etc(self):95 def update_logrotate_etc(self):
97 """Run logrotate update config."""96 """Run logrotate update config."""
diff --git a/src/tests/functional/test_logrotate.py b/src/tests/functional/test_logrotate.py
index 4aa0aa6..0afbb82 100644
--- a/src/tests/functional/test_logrotate.py
+++ b/src/tests/functional/test_logrotate.py
@@ -112,6 +112,27 @@ async def test_configure_cron_daily(deploy_app):
112 assert deploy_app.status == "active"112 assert deploy_app.status == "active"
113113
114114
115async def test_reconfigure_cronjob_frequency(model, deploy_app, unit, jujutools):
116 """Test reconfiguration of cronjob frequency."""
117 await deploy_app.set_config({"logrotate-cronjob-frequency": "weekly"})
118 await model.block_until(lambda: deploy_app.status == "active")
119 config = await deploy_app.get_config()
120
121 result = await jujutools.run_command(
122 "test -f /etc/cron.weekly/charm-logrotate", unit
123 )
124 weekly_cronjob_exists = result["return-code"] == 0
125
126 result = await jujutools.run_command(
127 "test -f /etc/cron.daily/charm-logrotate", unit
128 )
129 daily_cronjob_exists = result["return-code"] == 0
130
131 assert config["logrotate-cronjob-frequency"]["value"] == "weekly"
132 assert not daily_cronjob_exists
133 assert weekly_cronjob_exists
134
135
115async def test_configure_override_01(model, deploy_app, jujutools, unit):136async def test_configure_override_01(model, deploy_app, jujutools, unit):
116 """Test configuring override for the deployment (interval)."""137 """Test configuring override for the deployment (interval)."""
117 test_path = "/etc/logrotate.d/apt"138 test_path = "/etc/logrotate.d/apt"
diff --git a/src/tests/unit/conftest.py b/src/tests/unit/conftest.py
index 1f15b42..9eff063 100644
--- a/src/tests/unit/conftest.py
+++ b/src/tests/unit/conftest.py
@@ -1,7 +1,7 @@
1#!/usr/bin/python31#!/usr/bin/python3
2"""Configurations for tests."""2"""Configurations for tests."""
33
4import mock4from unittest import mock
55
6import pytest6import pytest
77
@@ -54,6 +54,12 @@ def mock_remote_unit(monkeypatch):
54 monkeypatch.setattr("lib_logrotate.hookenv.remote_unit", lambda: "unit-mock/0")54 monkeypatch.setattr("lib_logrotate.hookenv.remote_unit", lambda: "unit-mock/0")
5555
5656
57@pytest.fixture()
58def mock_local_unit(monkeypatch):
59 """Local unit mock."""
60 monkeypatch.setattr("lib_logrotate.hookenv.local_unit", lambda: "unit-logrotated/0")
61
62
57@pytest.fixture63@pytest.fixture
58def mock_charm_dir(monkeypatch):64def mock_charm_dir(monkeypatch):
59 """Charm dir mock."""65 """Charm dir mock."""
diff --git a/src/tests/unit/requirements.txt b/src/tests/unit/requirements.txt
index 9c685e5..3d4047b 100644
--- a/src/tests/unit/requirements.txt
+++ b/src/tests/unit/requirements.txt
@@ -1,5 +1,5 @@
1charmhelpers1charmhelpers
2charms.reactive2charms.reactive
3mock
4pytest3pytest
5pytest-cov4pytest-cov
5pytest-mock
6\ No newline at end of file6\ No newline at end of file
diff --git a/src/tests/unit/test_logrotate.py b/src/tests/unit/test_logrotate.py
index 0c89bbc..8d329e5 100644
--- a/src/tests/unit/test_logrotate.py
+++ b/src/tests/unit/test_logrotate.py
@@ -1,6 +1,7 @@
1"""Main unit test module."""1"""Main unit test module."""
2
3import json2import json
3import os
4from textwrap import dedent
4from unittest import mock5from unittest import mock
56
6from lib_logrotate import LogrotateHelper7from lib_logrotate import LogrotateHelper
@@ -279,3 +280,72 @@ class TestCronHelper:
279 cron_config.validate_cron_conf()280 cron_config.validate_cron_conf()
280281
281 assert err.type == cron_config.InvalidCronConfig282 assert err.type == cron_config.InvalidCronConfig
283
284 def test_install_cronjob(self, cron, mock_local_unit, mocker):
285 """Test install cronjob method."""
286 mock_charm_dir = "/mock/unit-logrotated-0/charm"
287 mock_exists = mocker.patch("lib_cron.os.path.exists", return_value=True)
288 mock_remove = mocker.patch("lib_cron.os.remove")
289 mock_chmod = mocker.patch("lib_cron.os.chmod")
290 mocker.patch(
291 "lib_cron.os.path.realpath",
292 return_value=os.path.join(mock_charm_dir, "lib/lib_cron.py"),
293 )
294 mocker.patch("lib_cron.os.getcwd", return_value=mock_charm_dir)
295 mock_open = mocker.patch("lib_cron.open")
296 mock_handle = mock_open.return_value
297
298 expected_files_to_be_removed = [
299 "/etc/cron.hourly/charm-logrotate",
300 "/etc/cron.daily/charm-logrotate",
301 "/etc/cron.weekly/charm-logrotate",
302 "/etc/cron.monthly/charm-logrotate",
303 ]
304
305 cron_config = cron()
306 cron_config.cronjob_enabled = True
307 cron_config.cronjob_frequency = 2
308 cron_config.install_cronjob()
309
310 mock_exists.assert_has_calls(
311 [mock.call(file) for file in expected_files_to_be_removed], any_order=True
312 )
313 mock_remove.assert_has_calls(
314 [mock.call(file) for file in expected_files_to_be_removed], any_order=True
315 )
316 mock_open.assert_called_once_with("/etc/cron.weekly/charm-logrotate", "w")
317 mock_handle.write.assert_called_once_with(
318 dedent(
319 """\
320 #!/bin/bash
321 /usr/bin/sudo /usr/bin/juju-run unit-logrotated/0 "/mock/unit-logrotated-0/.venv/bin/python3 /mock/unit-logrotated-0/charm/lib/lib_cron.py"
322 """ # noqa
323 )
324 )
325 mock_handle.close.assert_called_once()
326 mock_chmod.assert_called_once_with("/etc/cron.weekly/charm-logrotate", 700)
327
328 def test_install_cronjob_removes_etc_config_when_cronjob_disabled(
329 self, cron, mocker
330 ):
331 """Test that all cronjob related files created upon cronjobs being disabled."""
332 mock_exists = mocker.patch("lib_cron.os.path.exists", return_value=True)
333 mock_remove = mocker.patch("lib_cron.os.remove")
334
335 expected_files_to_be_removed = [
336 "/etc/cron.hourly/charm-logrotate",
337 "/etc/cron.daily/charm-logrotate",
338 "/etc/cron.weekly/charm-logrotate",
339 "/etc/cron.monthly/charm-logrotate",
340 "/etc/logrotate_cronjob_config",
341 ]
342 cron_config = cron()
343 cron_config.cronjob_enabled = False
344 cron_config.install_cronjob()
345
346 mock_exists.assert_has_calls(
347 [mock.call(file) for file in expected_files_to_be_removed], any_order=True
348 )
349 mock_remove.assert_has_calls(
350 [mock.call(file) for file in expected_files_to_be_removed], any_order=True
351 )

Subscribers

People subscribed via source and target branches

to all changes: