Rewrite the 'change-osd-weight' to use the op framework
This patchset changes a single action, 'change-osd-weight' so that it's implemented with the operator framework. Change-Id: Ia11885a2096b6e4b1ecda5caea38939e17098e1d
This commit is contained in:
parent
24dfc7440d
commit
5656db92df
@ -1,4 +1,4 @@
|
|||||||
# Copyright 2016 Canonical Ltd
|
# Copyright 2022 Canonical Ltd
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
|
@ -1 +0,0 @@
|
|||||||
change_osd_weight.py
|
|
21
src/charm.py
21
src/charm.py
@ -7,6 +7,8 @@ import ops_openstack.core
|
|||||||
import ceph_hooks as hooks
|
import ceph_hooks as hooks
|
||||||
import ceph_metrics
|
import ceph_metrics
|
||||||
|
|
||||||
|
import ops_actions
|
||||||
|
|
||||||
|
|
||||||
class CephMonCharm(ops_openstack.core.OSBaseCharm):
|
class CephMonCharm(ops_openstack.core.OSBaseCharm):
|
||||||
|
|
||||||
@ -66,12 +68,31 @@ class CephMonCharm(ops_openstack.core.OSBaseCharm):
|
|||||||
def on_nrpe_relation(self, event):
|
def on_nrpe_relation(self, event):
|
||||||
hooks.upgrade_nrpe_config()
|
hooks.upgrade_nrpe_config()
|
||||||
|
|
||||||
|
# Actions.
|
||||||
|
|
||||||
|
def _observe_action(self, on_action, callable):
|
||||||
|
def _make_method(fn):
|
||||||
|
return lambda _, event: fn(event)
|
||||||
|
|
||||||
|
method_name = 'on_' + str(on_action.event_kind)
|
||||||
|
method = _make_method(callable)
|
||||||
|
# In addition to being a method, the action callbacks _must_ have
|
||||||
|
# the same '__name__' as their attribute name (this is how lookups
|
||||||
|
# work in the operator framework world).
|
||||||
|
method.__name__ = method_name
|
||||||
|
|
||||||
|
inst = type(self)
|
||||||
|
setattr(inst, method_name, method)
|
||||||
|
self.framework.observe(on_action, getattr(self, method_name))
|
||||||
|
|
||||||
def __init__(self, *args):
|
def __init__(self, *args):
|
||||||
super().__init__(*args)
|
super().__init__(*args)
|
||||||
self._stored.is_started = True
|
self._stored.is_started = True
|
||||||
fw = self.framework
|
fw = self.framework
|
||||||
|
|
||||||
self.metrics_endpoint = ceph_metrics.CephMetricsEndpointProvider(self)
|
self.metrics_endpoint = ceph_metrics.CephMetricsEndpointProvider(self)
|
||||||
|
self._observe_action(self.on.change_osd_weight_action,
|
||||||
|
ops_actions.change_osd_weight.change_osd_weight)
|
||||||
|
|
||||||
fw.observe(self.on.install, self.on_install)
|
fw.observe(self.on.install, self.on_install)
|
||||||
fw.observe(self.on.config_changed, self.on_config)
|
fw.observe(self.on.config_changed, self.on_config)
|
||||||
|
15
src/ops_actions/__init__.py
Normal file
15
src/ops_actions/__init__.py
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# Copyright 2022 Canonical Ltd
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
from . import change_osd_weight # noqa: F401
|
25
actions/change_osd_weight.py → src/ops_actions/change_osd_weight.py
Executable file → Normal file
25
actions/change_osd_weight.py → src/ops_actions/change_osd_weight.py
Executable file → Normal file
@ -16,25 +16,26 @@
|
|||||||
|
|
||||||
"""Changes the crush weight of an OSD."""
|
"""Changes the crush weight of an OSD."""
|
||||||
|
|
||||||
from charmhelpers.core.hookenv import function_fail, function_get, log
|
import charms_ceph.utils as ceph_utils
|
||||||
from charms_ceph.utils import reweight_osd
|
import logging
|
||||||
|
|
||||||
|
|
||||||
def crush_reweight(osd_num, new_weight):
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def change_osd_weight(event) -> None:
|
||||||
"""Run reweight_osd to change OSD weight."""
|
"""Run reweight_osd to change OSD weight."""
|
||||||
|
osd_num = event.params.get("osd")
|
||||||
|
new_weight = event.params.get("weight")
|
||||||
try:
|
try:
|
||||||
result = reweight_osd(str(osd_num), str(new_weight))
|
result = ceph_utils.reweight_osd(str(osd_num), str(new_weight))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log(e)
|
logger.warn(e)
|
||||||
function_fail("Reweight failed due to exception")
|
event.fail("Reweight failed due to exception")
|
||||||
return
|
return
|
||||||
|
|
||||||
if not result:
|
if not result:
|
||||||
function_fail("Reweight failed to complete")
|
event.fail("Reweight failed to complete")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
event.set_results({'message': 'success'})
|
||||||
if __name__ == "__main__":
|
|
||||||
osd_num = function_get("osd")
|
|
||||||
new_weight = function_get("weight")
|
|
||||||
crush_reweight(osd_num, new_weight)
|
|
1
tox.ini
1
tox.ini
@ -86,7 +86,6 @@ basepython = python3
|
|||||||
deps = flake8==3.9.2
|
deps = flake8==3.9.2
|
||||||
charm-tools==2.8.4
|
charm-tools==2.8.4
|
||||||
commands = flake8 {posargs} unit_tests tests actions files src
|
commands = flake8 {posargs} unit_tests tests actions files src
|
||||||
charm-proof
|
|
||||||
|
|
||||||
[testenv:cover]
|
[testenv:cover]
|
||||||
# Technique based heavily upon
|
# Technique based heavily upon
|
||||||
|
@ -13,25 +13,29 @@
|
|||||||
|
|
||||||
"""Tests for reweight_osd action."""
|
"""Tests for reweight_osd action."""
|
||||||
|
|
||||||
from actions import change_osd_weight as action
|
|
||||||
import unittest.mock as mock
|
import unittest.mock as mock
|
||||||
from test_utils import CharmTestCase
|
from test_utils import CharmTestCase, MockActionEvent
|
||||||
|
from ops.testing import Harness
|
||||||
|
|
||||||
|
with mock.patch('charmhelpers.contrib.hardening.harden.harden') as mock_dec:
|
||||||
|
mock_dec.side_effect = (lambda *dargs, **dkwargs: lambda f:
|
||||||
|
lambda *args, **kwargs: f(*args, **kwargs))
|
||||||
|
# src.charm imports ceph_hooks, so we need to workaround the inclusion
|
||||||
|
# of the 'harden' decorator.
|
||||||
|
from src.charm import CephMonCharm
|
||||||
|
|
||||||
|
|
||||||
class ReweightTestCase(CharmTestCase):
|
class ReweightTestCase(CharmTestCase):
|
||||||
"""Run tests for action."""
|
"""Run tests for action."""
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
"""Init mocks for test cases."""
|
self.harness = Harness(CephMonCharm)
|
||||||
super(ReweightTestCase, self).setUp(
|
|
||||||
action, ["function_get", "function_fail"]
|
|
||||||
)
|
|
||||||
|
|
||||||
@mock.patch("actions.change_osd_weight.reweight_osd")
|
@mock.patch("ops_actions.change_osd_weight.ceph_utils.reweight_osd")
|
||||||
def test_reweight_osd(self, _reweight_osd):
|
def test_reweight_osd(self, _reweight_osd):
|
||||||
"""Test reweight_osd action has correct calls."""
|
"""Test reweight_osd action has correct calls."""
|
||||||
_reweight_osd.return_value = True
|
_reweight_osd.return_value = True
|
||||||
osd_num = 4
|
self.harness.begin()
|
||||||
new_weight = 1.2
|
self.harness.charm.on_change_osd_weight_action(
|
||||||
action.crush_reweight(osd_num, new_weight)
|
MockActionEvent({'osd': 4, 'weight': 1.2}))
|
||||||
_reweight_osd.assert_has_calls([mock.call("4", "1.2")])
|
_reweight_osd.assert_has_calls([mock.call("4", "1.2")])
|
||||||
|
@ -17,7 +17,7 @@ import unittest
|
|||||||
import os
|
import os
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch, MagicMock
|
||||||
|
|
||||||
|
|
||||||
def load_config():
|
def load_config():
|
||||||
@ -157,3 +157,11 @@ class TestLeaderSettings(object):
|
|||||||
elif attr in self.settings:
|
elif attr in self.settings:
|
||||||
return self.settings[attr]
|
return self.settings[attr]
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
class MockActionEvent:
|
||||||
|
|
||||||
|
def __init__(self, params={}):
|
||||||
|
self.params = params
|
||||||
|
self.fail = MagicMock()
|
||||||
|
self.set_results = MagicMock()
|
||||||
|
Loading…
Reference in New Issue
Block a user