Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add log to inform skipped(non-empty) hypervisors #351

Merged
merged 21 commits into from
Apr 11, 2024
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
fd770a9
# This is a combination of 3 commits.
rgildein Mar 26, 2024
87b03b6
Rebase onto main
zxhdaze Apr 4, 2024
7d2281a
Merge branch 'main' into BSENG-2235/add-nonempty-hypervisor-log
agileshaw Apr 5, 2024
6584cee
Merge branch 'main' into BSENG-2235/add-nonempty-hypervisor-log
zxhdaze Apr 8, 2024
3a726c5
Update get_empty_hypervisor, add unit test for upgradable log
zxhdaze Apr 8, 2024
1075cd0
Merge branch 'main' into BSENG-2235/add-nonempty-hypervisor-log
zxhdaze Apr 9, 2024
946ae69
reformat code
zxhdaze Apr 9, 2024
4348c2b
merge onto main
zxhdaze Apr 9, 2024
1f48fe6
move log logic into get_empty_hyperviosr
zxhdaze Apr 9, 2024
55d42d9
reformat code
zxhdaze Apr 9, 2024
df3efa4
reformat code
zxhdaze Apr 9, 2024
126baff
Update cou/utils/nova_compute.py description
zxhdaze Apr 10, 2024
b0ef7a3
Update cou/utils/nova_compute.py description
zxhdaze Apr 10, 2024
30314f7
Merge branch 'main' into BSENG-2235/add-nonempty-hypervisor-log
zxhdaze Apr 10, 2024
df63779
Merge branch 'main' into BSENG-2235/add-nonempty-hypervisor-log
zxhdaze Apr 10, 2024
09c86f8
Merge branch 'main' into BSENG-2235/add-nonempty-hypervisor-log
zxhdaze Apr 10, 2024
53aa21e
change unit test to use mock logger, adjust log level to warning
zxhdaze Apr 10, 2024
8f4e3f1
switch to assert_called_once_with in unit test
zxhdaze Apr 10, 2024
6e392ba
remove unused import
zxhdaze Apr 10, 2024
f5eeb9a
Merge branch 'main' into BSENG-2235/add-nonempty-hypervisor-log
agileshaw Apr 10, 2024
3e6cd3e
Merge branch 'main' into BSENG-2235/add-nonempty-hypervisor-log
agileshaw Apr 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion cou/steps/plan.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
from cou.steps.analyze import Analysis
from cou.steps.backup import backup
from cou.steps.hypervisor import HypervisorUpgradePlanner
from cou.utils.app_utils import set_require_osd_release_option
from cou.utils.app_utils import set_require_osd_release_option, stringify_units
from cou.utils.juju_utils import DEFAULT_TIMEOUT, Machine, Unit
from cou.utils.nova_compute import get_empty_hypervisors
from cou.utils.openstack import LTS_TO_OS_RELEASE, OpenStackRelease
Expand Down Expand Up @@ -594,6 +594,7 @@ async def _get_upgradable_hypervisors_machines(
)

if cli_force:
logger.info("Selected all hypervisors: %s", stringify_units(nova_compute_units))
return nova_compute_machines
zxhdaze marked this conversation as resolved.
Show resolved Hide resolved

return await get_empty_hypervisors(nova_compute_units, analysis_result.model)
Expand Down
16 changes: 14 additions & 2 deletions cou/utils/app_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
"""Application utilities."""
import json
import logging
from typing import Optional
from typing import Iterable, Optional

from cou.exceptions import RunUpgradeError
from cou.utils.juju_utils import Model
from cou.utils.juju_utils import Model, Unit
from cou.utils.openstack import CEPH_RELEASES

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -133,3 +133,15 @@ async def _get_current_osd_release(unit: str, model: Model) -> str:
logger.debug("Currently OSDs are on the '%s' release", current_osd_release)

return current_osd_release


def stringify_units(units: Iterable[Unit]) -> str:
"""Convert Units into a comma-separated string of unit names, sorted alphabetically.

:param units: An iterable of Unit objects to be converted.
:type units: Iterable[Unit]
:return: A comma-separated string of sorted unit names.
:rtype: str
"""
sorted_unit_names = sorted([unit.name for unit in units])
return ", ".join(sorted_unit_names)
10 changes: 9 additions & 1 deletion cou/utils/nova_compute.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import logging

from cou.exceptions import HaltUpgradeExecution
from cou.utils.app_utils import stringify_units
from cou.utils.juju_utils import Machine, Model, Unit

logger = logging.getLogger(__name__)
Expand All @@ -36,7 +37,14 @@ async def get_empty_hypervisors(units: list[Unit], model: Model) -> list[Machine
tasks = [get_instance_count(unit.name, model) for unit in units]
instances = await asyncio.gather(*tasks)
units_instances = zip(units, instances)
return [unit.machine for unit, instances in units_instances if instances == 0]
empty_units = {unit for unit, instances in units_instances if instances == 0}
skipped_units = set(units) - empty_units

if skipped_units:
logger.warning("Found non-empty hypervisors: %s", stringify_units(skipped_units))
logger.info("Selected hypervisors: %s", stringify_units(empty_units))

return [unit.machine for unit in empty_units]


async def get_instance_count(unit: str, model: Model) -> int:
Expand Down
20 changes: 17 additions & 3 deletions tests/unit/utils/test_nova_compute.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@
# 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 unittest.mock import AsyncMock, MagicMock, patch
from unittest.mock import AsyncMock, MagicMock, call, patch

import pytest
from juju.action import Action
Expand Down Expand Up @@ -64,16 +63,31 @@ async def test_get_instance_count_invalid_result(model, result_key, value):
],
)
@pytest.mark.asyncio
@patch("cou.utils.nova_compute.logger")
@patch("cou.utils.nova_compute.get_instance_count")
async def test_get_empty_hypervisors(
mock_instance_count, hypervisors_count, expected_result, model
mock_instance_count, mock_logger, hypervisors_count, expected_result, model
):
mock_instance_count.side_effect = [count for _, count in hypervisors_count]
result = await nova_compute.get_empty_hypervisors(
[_mock_nova_unit(nova_unit) for nova_unit, _ in hypervisors_count], model
)

assert {machine.machine_id for machine in result} == expected_result

selected_hypervisors = ", ".join(
[f"nova-compute/{i}" for i, count in hypervisors_count if count == 0]
)
non_empty_hypervisors = ", ".join(
[f"nova-compute/{i}" for i, count in hypervisors_count if count != 0]
)

mock_logger.info.assert_has_calls([call("Selected hypervisors: %s", selected_hypervisors)])
if non_empty_hypervisors:
mock_logger.warning.assert_has_calls(
[call("Found non-empty hypervisors: %s", non_empty_hypervisors)]
)
agileshaw marked this conversation as resolved.
Show resolved Hide resolved


@pytest.mark.parametrize("instance_count", [1, 10, 50])
@pytest.mark.asyncio
Expand Down
Loading