Skip to content

Commit

Permalink
Fix upgrade order for subordinate charms (#551)
Browse files Browse the repository at this point in the history
* Fix upgrade order for subordinate charms

All subordinate charms must be upgraded before principal charms.

This removes the specific logic for ovn-chassis (a subordinate charm),
including it in the new generic logic for subordinate charms.

Fixes: #552
Fixes: #553
  • Loading branch information
samuelallan72 authored Oct 3, 2024
1 parent b735fe9 commit 5b71d1f
Show file tree
Hide file tree
Showing 9 changed files with 98 additions and 195 deletions.
86 changes: 21 additions & 65 deletions cou/steps/analyze.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,7 @@
from cou.apps.base import OpenStackApplication
from cou.apps.factory import AppFactory
from cou.utils import juju_utils
from cou.utils.openstack import (
DATA_PLANE_CHARMS,
OVN_SUBORDINATES,
UPGRADE_ORDER,
OpenStackRelease,
)
from cou.utils.openstack import DATA_PLANE_CHARMS, UPGRADE_ORDER, OpenStackRelease

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -66,74 +61,35 @@ def apps_control_plane(self) -> list[OpenStackApplication]:
:return: Control plane application lists.
:rtype: list[OpenStackApplication]
"""
control_plane, _ = self._split_apps(self.apps)
return control_plane
return [app for app in self.apps if app not in self.apps_data_plane]

@property
def apps_data_plane(self) -> list[OpenStackApplication]:
"""Return list of data plane applications.
"""Return list of data plane principal applications.
OVN_SUBORDINATES is not part of the data plane apps because they need to be
upgraded before the ovn-contral.
These are charms in the known DATA_PLANE_CHARMS,
plus any principal charms colocated with nova-compute
(upgrades for these must be interleaved with nova-compute).
:return: data plane application lists.
:rtype: list[OpenStackApplication]
"""
_, data_plane = self._split_apps(self.apps)
# Remove ovn subordinates from the data plane since they have to upgrade before
# ovn-central
data_plane = [app for app in data_plane if app.charm not in OVN_SUBORDINATES]
return data_plane

@property
def apps_ovn_subordinate(self) -> list[OpenStackApplication]:
"""Return list of ovn subordinate applications.
:return: ovn subordinate application lists.
:rtype: list[OpenStackApplication]
"""
apps = []
for app in self.apps:
if app.charm in OVN_SUBORDINATES:
apps.append(app)
return apps

@staticmethod
def _split_apps(
apps: list[OpenStackApplication],
) -> tuple[list[OpenStackApplication], list[OpenStackApplication]]:
"""Split applications to control plane and data plane apps.
:param apps: List of applications to split.
:type apps: Iterable[OpenStackApplication]
:return: Control plane and data plane application lists.
:rtype: tuple[list[OpenStackApplication], list[OpenStackApplication]]
"""

def is_data_plane(app: OpenStackApplication) -> bool:
"""Check if app belong to data plane.
:param app: application
:type app: OpenStackApplication
:return: boolean
:rtype: bool
"""
return app.charm in DATA_PLANE_CHARMS

control_plane, data_plane = [], []
data_plane_machines = {
unit.machine for app in apps if is_data_plane(app) for unit in app.units.values()
}

for app in apps:
if is_data_plane(app):
data_plane.append(app)
elif any(machine in data_plane_machines for machine in app.machines.values()):
data_plane.append(app)
else:
control_plane.append(app)
nova_compute_machines = set(
unit.machine
for app in self.apps
for unit in app.units.values()
if app.charm == "nova-compute"
)

return control_plane, data_plane
return [
app
for app in self.apps
if app.charm in DATA_PLANE_CHARMS
or (
not app.is_subordinate
and any(unit.machine in nova_compute_machines for unit in app.units.values())
)
]

@classmethod
async def create(cls, model: juju_utils.Model, skip_apps: list[str]) -> Analysis:
Expand Down
48 changes: 8 additions & 40 deletions cou/steps/plan.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,8 @@ async def generate_plan(analysis_result: Analysis, args: CLIargs) -> UpgradePlan
)
plan.add_steps(_get_pre_upgrade_steps(analysis_result, args))

# NOTE (gabrielcocenza) upgrade group as None means that the user wants to upgrade
# the whole cloud.
# upgrade_group == None means that the user wants to upgrade the whole cloud.
if args.upgrade_group in {CONTROL_PLANE, None}:
plan.add_steps(_generate_ovn_subordinate_plan(target, analysis_result, args))
plan.add_steps(
_generate_control_plane_plan(target, analysis_result.apps_control_plane, args.force)
)
Expand Down Expand Up @@ -166,30 +164,6 @@ async def post_upgrade_sanity_checks(analysis_result: Analysis) -> None:
print_and_debug(message)


def _generate_ovn_subordinate_plan(
target: OpenStackRelease, analysis_result: Analysis, args: CLIargs
) -> list[UpgradePlan]:
"""Generate upgrade plan for ovn subordinate applications.
:param target: Target OpenStack release.
:type target: OpenStackRelease
:param analysis_result: Analysis result
:type analysis_result: Analysis
:param args: CLI arguments
:type args: CLIargs
:return: A list of the upgrade plans for ovn subordinate applications.
:rtype: list[UpgradePlan]
"""
return [
_create_upgrade_group(
apps=analysis_result.apps_ovn_subordinate,
description="OVN subordinate upgrade plan",
target=target,
force=args.force,
)
]


async def _generate_data_plane_plan(
target: OpenStackRelease, analysis_result: Analysis, args: CLIargs
) -> list[UpgradePlan]:
Expand Down Expand Up @@ -671,9 +645,12 @@ def _generate_control_plane_plan(
force=force,
)

# NOTE: these are all subordinates on the cloud,
# not just those related to the control plane.
# This should be refactored later to separate from control plane methods.
subordinate_upgrade_plan = _create_upgrade_group(
apps=[app for app in apps if app.is_subordinate],
description="Control Plane subordinate(s) upgrade plan",
description="Subordinate(s) upgrade plan",
target=target,
force=force,
)
Expand Down Expand Up @@ -706,7 +683,7 @@ def _separate_hypervisors_apps(
if (
any(unit.machine in nova_compute_machines for unit in app.units.values())
and app.charm != "ceph-osd"
and app.is_subordinate is False
and not app.is_subordinate
):
hypervisor_apps.append(app)
else:
Expand Down Expand Up @@ -748,7 +725,7 @@ async def _generate_data_plane_hypervisors_plan(
def _generate_data_plane_remaining_plan(
target: OpenStackRelease, apps: list[OpenStackApplication], force: bool
) -> list[UpgradePlan]:
"""Generate upgrade plan for principals and subordinates data-plane apps.
"""Generate upgrade plan for remaining principal data-plane apps.
Those plans are done using the all-in-one upgrade strategy.
Expand All @@ -768,17 +745,8 @@ def _generate_data_plane_remaining_plan(
force=force,
)

subordinate_upgrade_plan = _create_upgrade_group(
apps=[app for app in apps if app.is_subordinate],
description="Data Plane subordinate(s) upgrade plan",
target=target,
force=force,
)

logger.debug("Generation of remaining data plane upgrade plan complete")
data_plane_upgrade_plan = [principal_upgrade_plan, subordinate_upgrade_plan]

return data_plane_upgrade_plan
return [principal_upgrade_plan]


async def _filter_hypervisors_machines(args: CLIargs, analysis_result: Analysis) -> list[Machine]:
Expand Down
3 changes: 2 additions & 1 deletion cou/utils/openstack.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@
"mysql": ["mysql-innodb-cluster", "mysql-router"],
}

# nova-compute + other principal charms that must be upgraded after nova-compute
DATA_PLANE_CHARMS = ["nova-compute", "ceph-osd", "swift-proxy", "swift-storage"]
OVN_SUBORDINATES = ["ovn-chassis"]

# https://docs.openstack.org/charm-guide/latest/admin/upgrades/openstack.html#list-the-upgrade-order
UCA_UPGRADE_ORDER = [
Expand Down Expand Up @@ -103,6 +103,7 @@
"neutron-openvswitch",
"octavia-dashboard",
"octavia-diskimage-retrofit",
"ovn-chassis",
]

AUXILIARY_SUBORDINATES = ["hacluster", "mysql-router", "ceph-dashboard"]
Expand Down
2 changes: 1 addition & 1 deletion docs/how-to/plan-upgrade.rst
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ Output example
Change charm config of 'keystone' 'openstack-origin' to 'cloud:focal-victoria'
Wait for up to 2400s for model 'test_model' to reach the idle state
Verify that the workload of 'keystone' has been upgraded on units: keystone/0
Control Plane subordinate(s) upgrade plan
Subordinate(s) upgrade plan
Upgrade plan for 'keystone-ldap' to 'victoria'
Refresh 'keystone-ldap' to the latest revision of 'ussuri/stable'
Upgrade 'keystone-ldap' to the new channel: 'victoria/stable'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,27 @@ plan: |
Upgrade cloud from 'ussuri' to 'victoria'
Back up MySQL databases
Archive old database data on nova-cloud-controller
Control Plane subordinate(s) upgrade plan
Subordinate(s) upgrade plan
Upgrade plan for 'ceilometer-agent' to 'victoria'
Refresh 'ceilometer-agent' to the latest revision of 'ussuri/stable'
Wait for up to 300s for app 'ceilometer-agent' to reach the idle state
Upgrade 'ceilometer-agent' from 'ussuri/stable' to the new channel: 'victoria/stable'
Wait for up to 300s for app 'ceilometer-agent' to reach the idle state
Upgrade plan for 'ceph-dashboard' to 'victoria'
Refresh 'ceph-dashboard' to the latest revision of 'octopus/stable'
Wait for up to 300s for app 'ceph-dashboard' to reach the idle state
Upgrade plan for 'cinder-ceph' to 'victoria'
Upgrade 'cinder-ceph' from 'ussuri/stable' to the new channel: 'victoria/stable'
Wait for up to 300s for app 'cinder-ceph' to reach the idle state
Upgrade plan for 'cinder-lvm-fast' to 'victoria'
Upgrade 'cinder-lvm-fast' from 'ussuri/stable' to the new channel: 'victoria/stable'
Wait for up to 300s for app 'cinder-lvm-fast' to reach the idle state
Upgrade plan for 'cinder-lvm-fast2' to 'victoria'
Upgrade 'cinder-lvm-fast2' from 'ussuri/stable' to the new channel: 'victoria/stable'
Wait for up to 300s for app 'cinder-lvm-fast2' to reach the idle state
Upgrade plan for 'cinder-lvm-slow' to 'victoria'
Upgrade 'cinder-lvm-slow' from 'ussuri/stable' to the new channel: 'victoria/stable'
Wait for up to 300s for app 'cinder-lvm-slow' to reach the idle state
Upgrade plan for 'hacluster-aodh' to 'victoria'
WARNING: Changing 'hacluster-aodh' channel from latest/stable to 2.4/stable. This may be a charm downgrade, which is generally not supported.
Wait for up to 300s for app 'hacluster-aodh' to reach the idle state
Expand Down Expand Up @@ -65,6 +79,9 @@ plan: |
Upgrade plan for 'cinder-mysql-router' to 'victoria'
Refresh 'cinder-mysql-router' to the latest revision of '8.0/stable'
Wait for up to 300s for app 'cinder-mysql-router' to reach the idle state
Upgrade plan for 'cinder-volume-mysql-router' to 'victoria'
Refresh 'cinder-volume-mysql-router' to the latest revision of '8.0/stable'
Wait for up to 300s for app 'cinder-volume-mysql-router' to reach the idle state
Upgrade plan for 'designate-mysql-router' to 'victoria'
Refresh 'designate-mysql-router' to the latest revision of '8.0/stable'
Wait for up to 300s for app 'designate-mysql-router' to reach the idle state
Expand Down Expand Up @@ -546,24 +563,6 @@ plan: |
Change charm config of 'ceph-osd' 'source' to 'cloud:focal-victoria'
Wait for up to 300s for app 'ceph-osd' to reach the idle state
Verify that the workload of 'ceph-osd' has been upgraded on units: ceph-osd/0, ceph-osd/1, ceph-osd/2
Data Plane subordinate(s) upgrade plan
Upgrade plan for 'ceilometer-agent' to 'victoria'
Refresh 'ceilometer-agent' to the latest revision of 'ussuri/stable'
Wait for up to 300s for app 'ceilometer-agent' to reach the idle state
Upgrade 'ceilometer-agent' from 'ussuri/stable' to the new channel: 'victoria/stable'
Wait for up to 300s for app 'ceilometer-agent' to reach the idle state
Upgrade plan for 'cinder-lvm-fast' to 'victoria'
Upgrade 'cinder-lvm-fast' from 'ussuri/stable' to the new channel: 'victoria/stable'
Wait for up to 300s for app 'cinder-lvm-fast' to reach the idle state
Upgrade plan for 'cinder-lvm-fast2' to 'victoria'
Upgrade 'cinder-lvm-fast2' from 'ussuri/stable' to the new channel: 'victoria/stable'
Wait for up to 300s for app 'cinder-lvm-fast2' to reach the idle state
Upgrade plan for 'cinder-lvm-slow' to 'victoria'
Upgrade 'cinder-lvm-slow' from 'ussuri/stable' to the new channel: 'victoria/stable'
Wait for up to 300s for app 'cinder-lvm-slow' to reach the idle state
Upgrade plan for 'cinder-volume-mysql-router' to 'victoria'
Refresh 'cinder-volume-mysql-router' to the latest revision of '8.0/stable'
Wait for up to 300s for app 'cinder-volume-mysql-router' to reach the idle state
Ensure ceph-mon's 'require-osd-release' option matches the 'ceph-osd' version
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,13 @@ plan: |
Upgrade cloud from 'ussuri' to 'victoria'
Back up MySQL databases
Archive old database data on nova-cloud-controller
OVN subordinate upgrade plan
Upgrade plan for 'octavia-ovn-chassis' to 'victoria'
WARNING: Changing 'octavia-ovn-chassis' channel from latest/stable to 22.03/stable. This may be a charm downgrade, which is generally not supported.
Wait for up to 300s for app 'octavia-ovn-chassis' to reach the idle state
Upgrade plan for 'ovn-chassis' to 'victoria'
WARNING: Changing 'ovn-chassis' channel from latest/stable to 22.03/stable. This may be a charm downgrade, which is generally not supported.
Wait for up to 300s for app 'ovn-chassis' to reach the idle state
Control Plane subordinate(s) upgrade plan
Subordinate(s) upgrade plan
Upgrade plan for 'barbican-vault' to 'victoria'
Upgrade 'barbican-vault' from 'ussuri/stable' to the new channel: 'victoria/stable'
Wait for up to 300s for app 'barbican-vault' to reach the idle state
Upgrade plan for 'ceilometer-agent' to 'victoria'
Upgrade 'ceilometer-agent' from 'ussuri/stable' to the new channel: 'victoria/stable'
Wait for up to 300s for app 'ceilometer-agent' to reach the idle state
Upgrade plan for 'ceph-dashboard' to 'victoria'
Refresh 'ceph-dashboard' to the latest revision of 'octopus/stable'
Wait for up to 300s for app 'ceph-dashboard' to reach the idle state
Expand Down Expand Up @@ -163,6 +159,9 @@ plan: |
Upgrade plan for 'octavia-ovn-chassis' to 'victoria'
WARNING: Changing 'octavia-ovn-chassis' channel from latest/stable to 22.03/stable. This may be a charm downgrade, which is generally not supported.
Wait for up to 300s for app 'octavia-ovn-chassis' to reach the idle state
Upgrade plan for 'ovn-chassis' to 'victoria'
WARNING: Changing 'ovn-chassis' channel from latest/stable to 22.03/stable. This may be a charm downgrade, which is generally not supported.
Wait for up to 300s for app 'ovn-chassis' to reach the idle state
Control Plane principal(s) upgrade plan
Upgrade plan for 'vault' to 'victoria'
Upgrade software packages of 'vault' from the current APT repositories
Expand Down Expand Up @@ -521,10 +520,6 @@ plan: |
Change charm config of 'ceph-osd' 'source' to 'cloud:focal-victoria'
Wait for up to 300s for app 'ceph-osd' to reach the idle state
Verify that the workload of 'ceph-osd' has been upgraded on units: ceph-osd/0, ceph-osd/1, ceph-osd/2, ceph-osd/3, ceph-osd/4, ceph-osd/5, ceph-osd/6, ceph-osd/7, ceph-osd/8
Data Plane subordinate(s) upgrade plan
Upgrade plan for 'ceilometer-agent' to 'victoria'
Upgrade 'ceilometer-agent' from 'ussuri/stable' to the new channel: 'victoria/stable'
Wait for up to 300s for app 'ceilometer-agent' to reach the idle state
Ensure ceph-mon's 'require-osd-release' option matches the 'ceph-osd' version
applications:
Expand Down
9 changes: 4 additions & 5 deletions tests/mocked_plans/sample_plans/base.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,15 @@ plan: |
Upgrade cloud from 'ussuri' to 'victoria'
Back up MySQL databases
Archive old database data on nova-cloud-controller
OVN subordinate upgrade plan
Upgrade plan for 'ovn-chassis' to 'victoria'
Refresh 'ovn-chassis' to the latest revision of '22.03/stable'
Wait for up to 300s for app 'ovn-chassis' to reach the idle state
Control Plane subordinate(s) upgrade plan
Subordinate(s) upgrade plan
Upgrade plan for 'keystone-ldap' to 'victoria'
Refresh 'keystone-ldap' to the latest revision of 'ussuri/stable'
Wait for up to 300s for app 'keystone-ldap' to reach the idle state
Upgrade 'keystone-ldap' from 'ussuri/stable' to the new channel: 'victoria/stable'
Wait for up to 300s for app 'keystone-ldap' to reach the idle state
Upgrade plan for 'ovn-chassis' to 'victoria'
Refresh 'ovn-chassis' to the latest revision of '22.03/stable'
Wait for up to 300s for app 'ovn-chassis' to reach the idle state
Control Plane principal(s) upgrade plan
Upgrade plan for 'keystone' to 'victoria'
Upgrade software packages of 'keystone' from the current APT repositories
Expand Down
Loading

0 comments on commit 5b71d1f

Please sign in to comment.