Skip to content

Commit

Permalink
fix: upgrade MySQL from 5.7 to 8.1 first and then to 8.4
Browse files Browse the repository at this point in the history
This is required when upgrading from Tutor v15 to v18 directly
MySQL does not allow direct upgrades from v5.7 to v8.4
  • Loading branch information
Danyal-Faheem authored Sep 26, 2024
1 parent 3892dd2 commit 0f2229b
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- [Bugfix] Do not directly upgrade MySQL from v5.7 to v8.4 when upgrading from quince as MySQL does not allow that. First, upgrade to v8.1 and then to v8.4. (by @Danyal-Faheem)
This process should be automatic for most users. However, if you are running a third-party MySQL (i.e., RUN_MYSQL=false), you are expected to perform this process yourself. Please refer to the third-party provider's documentation for detailed instructions. Ensuring that your MySQL version is up-to-date is crucial for maintaining compatibility and security.
33 changes: 32 additions & 1 deletion tutor/commands/upgrade/common.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
from __future__ import annotations

from typing import Optional

import click
from packaging import version

from tutor import config as tutor_config
from tutor import fmt, plugins
from tutor.types import Config
from tutor.types import Config, get_typed


def upgrade_from_lilac(config: Config) -> None:
Expand Down Expand Up @@ -60,6 +63,34 @@ def get_mongo_upgrade_parameters(
return mongo_version, admin_command


def get_intermediate_mysql_upgrade(config: Config) -> Optional[str]:
"""
Checks if a MySQL upgrade is needed based on the Tutor version and MySQL setup.
This method ensures that MySQL is running and determines if the upgrade
process should proceed based on the Tutor version. It is intended for upgrades
from Tutor version 15 to version 18 or later. Manual upgrade steps are not
required for versions 16 or 17.
Returns:
Optional[str]: The docker image of MySQL to upgrade to or None if not applicable
"""
if not get_typed(config, "RUN_MYSQL", bool):
fmt.echo_info(
"You are not running MySQL (RUN_MYSQL=false). It is your "
"responsibility to upgrade your MySQL instance to v8.4. There is "
"nothing left to do to upgrade from Olive."
)
return None
image_tag = get_typed(config, "DOCKER_IMAGE_MYSQL", str).split(":")[-1]
# If latest image, we assign a constant value to invalidate the condition
# as we know that the latest image will always be greater than 8.1.0
target_version = (
version.Version("8.1.1") if image_tag == "latest" else version.parse(image_tag)
)
return "docker.io/mysql:8.1.0" if target_version > version.parse("8.1.0") else None


PALM_RENAME_ORA2_FOLDER_COMMAND = """
if stat '/openedx/data/ora2/SET-ME-PLEASE (ex. bucket-name)' 2> /dev/null; then
echo "Renaming ora2 folder..."
Expand Down
22 changes: 21 additions & 1 deletion tutor/commands/upgrade/compose.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from tutor import config as tutor_config
from tutor import env as tutor_env
from tutor import fmt
from tutor.commands import compose
from tutor.commands import compose, jobs
from tutor.types import Config

from . import common as common_upgrade
Expand Down Expand Up @@ -158,6 +158,26 @@ def upgrade_from_olive(context: click.Context, config: Config) -> None:
upgrade_mongodb(context, config, "4.2.17", "4.2")
upgrade_mongodb(context, config, "4.4.22", "4.4")

intermediate_mysql_docker_image = common_upgrade.get_intermediate_mysql_upgrade(
config
)
if not intermediate_mysql_docker_image:
return

click.echo(fmt.title(f"Upgrading MySQL to {intermediate_mysql_docker_image}"))

# Revert the MySQL image to build the data dictionary on v8.1
mysql_docker_image = config["DOCKER_IMAGE_MYSQL"]
config["DOCKER_IMAGE_MYSQL"] = intermediate_mysql_docker_image
tutor_env.save(context.obj.root, config)
# Run the init command to make sure MySQL is ready for connections
context.invoke(jobs.initialise, limit="mysql")

# Change the image back to v8.4
config["DOCKER_IMAGE_MYSQL"] = mysql_docker_image
tutor_env.save(context.obj.root, config)
context.invoke(compose.stop, services=["mysql"])


def upgrade_from_quince(context: click.Context, config: Config) -> None:
click.echo(fmt.title("Upgrading from Quince"))
Expand Down
15 changes: 15 additions & 0 deletions tutor/commands/upgrade/k8s.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,21 @@ def upgrade_from_olive(context: Context, config: Config) -> None:
upgrade_mongodb(config, "4.2.17", "4.2")
upgrade_mongodb(config, "4.4.22", "4.4")

intermediate_mysql_docker_image = common_upgrade.get_intermediate_mysql_upgrade(
config
)
if not intermediate_mysql_docker_image:
return

message = f"""Automatic release upgrade is unsupported in Kubernetes. If you are upgrading from Olive or an earlier release to Redwood, you will have to first upgrade MySQL to v8.1 and then to v8.4. To upgrade, run the following commands:
tutor k8s stop
tutor config save --set DOCKER_IMAGE_MYSQL=docker.io/mysql:8.1.0
tutor k8s start
tutor config save --unset DOCKER_IMAGE_MYSQL
"""
fmt.echo_info(message)


def upgrade_from_quince(config: Config) -> None:
click.echo(fmt.title("Upgrading from Quince"))
Expand Down

0 comments on commit 0f2229b

Please sign in to comment.