mirror of
https://github.com/ChristianLight/tutor.git
synced 2024-12-12 22:27:47 +00:00
refactor: move upgrade code to separate modules
This results in clearer code.
This commit is contained in:
parent
9fc928a711
commit
c61accedfc
@ -4,12 +4,13 @@ from typing import Any, List, Optional, Type
|
|||||||
|
|
||||||
import click
|
import click
|
||||||
|
|
||||||
from .. import config as tutor_config
|
from tutor import config as tutor_config
|
||||||
from .. import env as tutor_env
|
from tutor import env as tutor_env
|
||||||
from .. import exceptions, fmt, jobs, serialize, utils
|
from tutor import exceptions, fmt, jobs, serialize, utils
|
||||||
from ..types import Config, get_typed
|
from tutor.commands.config import save as config_save_command
|
||||||
from .config import save as config_save_command
|
from tutor.commands.context import Context
|
||||||
from .context import Context
|
from tutor.commands.upgrade.k8s import upgrade_from
|
||||||
|
from tutor.types import Config, get_typed
|
||||||
|
|
||||||
|
|
||||||
class K8sClients:
|
class K8sClients:
|
||||||
@ -452,116 +453,7 @@ def wait(context: Context, name: str) -> None:
|
|||||||
@click.option("-I", "--non-interactive", is_flag=True, help="Run non-interactively")
|
@click.option("-I", "--non-interactive", is_flag=True, help="Run non-interactively")
|
||||||
@click.pass_obj
|
@click.pass_obj
|
||||||
def upgrade(context: Context, from_version: str, non_interactive: bool) -> None:
|
def upgrade(context: Context, from_version: str, non_interactive: bool) -> None:
|
||||||
config = tutor_config.load(context.root)
|
upgrade_from(context, from_version, interactive=not non_interactive)
|
||||||
|
|
||||||
running_version = from_version
|
|
||||||
if running_version == "ironwood":
|
|
||||||
upgrade_from_ironwood(config)
|
|
||||||
running_version = "juniper"
|
|
||||||
|
|
||||||
if running_version == "juniper":
|
|
||||||
upgrade_from_juniper(config)
|
|
||||||
running_version = "koa"
|
|
||||||
|
|
||||||
if running_version == "koa":
|
|
||||||
upgrade_from_koa(config)
|
|
||||||
running_version = "lilac"
|
|
||||||
|
|
||||||
if running_version == "lilac":
|
|
||||||
upgrade_from_lilac(config)
|
|
||||||
running_version = "maple"
|
|
||||||
|
|
||||||
# Update env such that the build environment is up-to-date
|
|
||||||
tutor_env.save(context.root, config)
|
|
||||||
if not non_interactive:
|
|
||||||
question = f"""
|
|
||||||
Your platform was successfuly upgraded from {from_version} to {running_version}.
|
|
||||||
Depending on your setup, you might have to rebuild some of your Docker images
|
|
||||||
and push them to your private registry (if any). You can do this now by running
|
|
||||||
the following command in a different shell:
|
|
||||||
|
|
||||||
tutor images build openedx # add your custom images here
|
|
||||||
tutor images push openedx
|
|
||||||
|
|
||||||
Press enter when you are ready to continue"""
|
|
||||||
click.confirm(
|
|
||||||
fmt.question(question), default=True, abort=True, prompt_suffix=" "
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def upgrade_from_ironwood(config: Config) -> None:
|
|
||||||
if not config["RUN_MONGODB"]:
|
|
||||||
fmt.echo_info(
|
|
||||||
"You are not running MongDB (RUN_MONGODB=false). It is your "
|
|
||||||
"responsibility to upgrade your MongoDb instance to v3.6. There is "
|
|
||||||
"nothing left to do to upgrade from Ironwood."
|
|
||||||
)
|
|
||||||
return
|
|
||||||
message = """Automatic release upgrade is unsupported in Kubernetes. To upgrade from Ironwood, you should upgrade
|
|
||||||
your MongoDb cluster from v3.2 to v3.6. You should run something similar to:
|
|
||||||
|
|
||||||
# Upgrade from v3.2 to v3.4
|
|
||||||
tutor k8s stop
|
|
||||||
tutor config save --set DOCKER_IMAGE_MONGODB=mongo:3.4.24
|
|
||||||
tutor k8s start
|
|
||||||
tutor k8s exec mongodb mongo --eval 'db.adminCommand({ setFeatureCompatibilityVersion: "3.4" })'
|
|
||||||
|
|
||||||
# Upgrade from v3.4 to v3.6
|
|
||||||
tutor k8s stop
|
|
||||||
tutor config save --set DOCKER_IMAGE_MONGODB=mongo:3.6.18
|
|
||||||
tutor k8s start
|
|
||||||
tutor k8s exec mongodb mongo --eval 'db.adminCommand({ setFeatureCompatibilityVersion: "3.6" })'
|
|
||||||
|
|
||||||
tutor config save --unset DOCKER_IMAGE_MONGODB"""
|
|
||||||
fmt.echo_info(message)
|
|
||||||
|
|
||||||
|
|
||||||
def upgrade_from_juniper(config: Config) -> None:
|
|
||||||
if not config["RUN_MYSQL"]:
|
|
||||||
fmt.echo_info(
|
|
||||||
"You are not running MySQL (RUN_MYSQL=false). It is your "
|
|
||||||
"responsibility to upgrade your MySQL instance to v5.7. There is "
|
|
||||||
"nothing left to do to upgrade from Juniper."
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
message = """Automatic release upgrade is unsupported in Kubernetes. To upgrade from Juniper, you should upgrade
|
|
||||||
your MySQL database from v5.6 to v5.7. You should run something similar to:
|
|
||||||
|
|
||||||
tutor k8s start
|
|
||||||
tutor k8s exec mysql bash -e -c "mysql_upgrade \
|
|
||||||
-u $(tutor config printvalue MYSQL_ROOT_USERNAME) \
|
|
||||||
--password='$(tutor config printvalue MYSQL_ROOT_PASSWORD)'
|
|
||||||
"""
|
|
||||||
fmt.echo_info(message)
|
|
||||||
|
|
||||||
|
|
||||||
def upgrade_from_koa(config: Config) -> None:
|
|
||||||
if not config["RUN_MONGODB"]:
|
|
||||||
fmt.echo_info(
|
|
||||||
"You are not running MongDB (RUN_MONGODB=false). It is your "
|
|
||||||
"responsibility to upgrade your MongoDb instance to v4.0. There is "
|
|
||||||
"nothing left to do to upgrade to Lilac from Koa."
|
|
||||||
)
|
|
||||||
return
|
|
||||||
message = """Automatic release upgrade is unsupported in Kubernetes. To upgrade from Koa to Lilac, you should upgrade
|
|
||||||
your MongoDb cluster from v3.6 to v4.0. You should run something similar to:
|
|
||||||
|
|
||||||
tutor k8s stop
|
|
||||||
tutor config save --set DOCKER_IMAGE_MONGODB=mongo:4.0.25
|
|
||||||
tutor k8s start
|
|
||||||
tutor k8s exec mongodb mongo --eval 'db.adminCommand({ setFeatureCompatibilityVersion: "4.0" })'
|
|
||||||
tutor config save --unset DOCKER_IMAGE_MONGODB
|
|
||||||
"""
|
|
||||||
fmt.echo_info(message)
|
|
||||||
|
|
||||||
|
|
||||||
def upgrade_from_lilac(config: Config) -> None:
|
|
||||||
fmt.echo_info(
|
|
||||||
"All Kubernetes services and deployments need to be deleted during "
|
|
||||||
"upgrade from Lilac to Maple"
|
|
||||||
)
|
|
||||||
delete_resources(config, resources=["deployments", "services"])
|
|
||||||
|
|
||||||
|
|
||||||
def kubectl_exec(
|
def kubectl_exec(
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
from time import sleep
|
|
||||||
|
|
||||||
import click
|
import click
|
||||||
|
|
||||||
from .. import config as tutor_config
|
from tutor import config as tutor_config
|
||||||
from .. import env as tutor_env
|
from tutor import env as tutor_env
|
||||||
from .. import exceptions, fmt, utils
|
from tutor import exceptions, fmt, utils
|
||||||
from ..types import Config, get_typed
|
from tutor.commands import compose
|
||||||
from . import compose
|
from tutor.commands.config import save as config_save_command
|
||||||
from .config import save as config_save_command
|
from tutor.commands.upgrade.local import upgrade_from
|
||||||
|
from tutor.types import Config, get_typed
|
||||||
|
|
||||||
|
|
||||||
class LocalJobRunner(compose.ComposeJobRunner):
|
class LocalJobRunner(compose.ComposeJobRunner):
|
||||||
@ -49,10 +48,12 @@ def quickstart(context: click.Context, non_interactive: bool, pullimages: bool)
|
|||||||
except exceptions.TutorError as e:
|
except exceptions.TutorError as e:
|
||||||
fmt.echo_alert(
|
fmt.echo_alert(
|
||||||
f"""Could not verify sufficient RAM allocation in Docker:
|
f"""Could not verify sufficient RAM allocation in Docker:
|
||||||
|
|
||||||
{e}
|
{e}
|
||||||
Tutor may not work if Docker is configured with < 4 GB RAM. Please follow the instructions from:
|
|
||||||
https://docs.tutor.overhang.io/install.html
|
Tutor may not work if Docker is configured with < 4 GB RAM. Please follow instructions from:
|
||||||
"""
|
|
||||||
|
https://docs.tutor.overhang.io/install.html"""
|
||||||
)
|
)
|
||||||
|
|
||||||
if tutor_env.needs_major_upgrade(context.obj.root):
|
if tutor_env.needs_major_upgrade(context.obj.root):
|
||||||
@ -64,12 +65,7 @@ Tutor may not work if Docker is configured with < 4 GB RAM. Please follow the in
|
|||||||
)
|
)
|
||||||
|
|
||||||
click.echo(fmt.title("Interactive platform configuration"))
|
click.echo(fmt.title("Interactive platform configuration"))
|
||||||
context.invoke(
|
context.invoke(config_save_command, interactive=(not non_interactive))
|
||||||
config_save_command,
|
|
||||||
interactive=(not non_interactive),
|
|
||||||
set_vars=[],
|
|
||||||
unset_vars=[],
|
|
||||||
)
|
|
||||||
click.echo(fmt.title("Stopping any existing platform"))
|
click.echo(fmt.title("Stopping any existing platform"))
|
||||||
context.invoke(compose.stop)
|
context.invoke(compose.stop)
|
||||||
if pullimages:
|
if pullimages:
|
||||||
@ -105,143 +101,7 @@ Your Open edX platform is ready and can be accessed at the following urls:
|
|||||||
@click.option("-I", "--non-interactive", is_flag=True, help="Run non-interactively")
|
@click.option("-I", "--non-interactive", is_flag=True, help="Run non-interactively")
|
||||||
@click.pass_context
|
@click.pass_context
|
||||||
def upgrade(context: click.Context, from_version: str, non_interactive: bool) -> None:
|
def upgrade(context: click.Context, from_version: str, non_interactive: bool) -> None:
|
||||||
config = tutor_config.load(context.obj.root)
|
upgrade_from(context, from_version, not non_interactive)
|
||||||
|
|
||||||
if not non_interactive:
|
|
||||||
question = """You are about to upgrade your Open edX platform. It is strongly recommended to make a backup before upgrading. To do so, run:
|
|
||||||
|
|
||||||
tutor local stop
|
|
||||||
sudo rsync -avr "$(tutor config printroot)"/ /tmp/tutor-backup/
|
|
||||||
|
|
||||||
In case of problem, to restore your backup you will then have to run: sudo rsync -avr /tmp/tutor-backup/ "$(tutor config printroot)"/
|
|
||||||
|
|
||||||
Are you sure you want to continue?"""
|
|
||||||
click.confirm(
|
|
||||||
fmt.question(question), default=True, abort=True, prompt_suffix=" "
|
|
||||||
)
|
|
||||||
|
|
||||||
running_version = from_version
|
|
||||||
if running_version == "ironwood":
|
|
||||||
upgrade_from_ironwood(context, config)
|
|
||||||
running_version = "juniper"
|
|
||||||
|
|
||||||
if running_version == "juniper":
|
|
||||||
upgrade_from_juniper(context, config)
|
|
||||||
running_version = "koa"
|
|
||||||
|
|
||||||
if running_version == "koa":
|
|
||||||
upgrade_from_koa(context, config)
|
|
||||||
running_version = "lilac"
|
|
||||||
|
|
||||||
if running_version == "lilac":
|
|
||||||
# Nothing to do here
|
|
||||||
running_version = "maple"
|
|
||||||
|
|
||||||
# Update env such that the build environment is up-to-date
|
|
||||||
tutor_env.save(context.obj.root, config)
|
|
||||||
if not non_interactive:
|
|
||||||
question = f"""
|
|
||||||
Your platform was successfuly upgraded from {from_version} to {running_version}.
|
|
||||||
Depending on your setup, you might have to rebuild some of your Docker images.
|
|
||||||
You can do this now by running the following command in a different shell:
|
|
||||||
|
|
||||||
tutor images build openedx # add your custom images here
|
|
||||||
|
|
||||||
Press enter when you are ready to continue"""
|
|
||||||
click.confirm(
|
|
||||||
fmt.question(question), default=True, abort=True, prompt_suffix=" "
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def upgrade_from_ironwood(context: click.Context, config: Config) -> None:
|
|
||||||
click.echo(fmt.title("Upgrading from Ironwood"))
|
|
||||||
tutor_env.save(context.obj.root, config)
|
|
||||||
|
|
||||||
click.echo(fmt.title("Stopping any existing platform"))
|
|
||||||
context.invoke(compose.stop)
|
|
||||||
|
|
||||||
if not config["RUN_MONGODB"]:
|
|
||||||
fmt.echo_info(
|
|
||||||
"You are not running MongDB (RUN_MONGODB=false). It is your "
|
|
||||||
"responsibility to upgrade your MongoDb instance to v3.6. There is "
|
|
||||||
"nothing left to do to upgrade from Ironwood to Juniper."
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
upgrade_mongodb(context, config, "3.4", "3.4")
|
|
||||||
context.invoke(compose.stop)
|
|
||||||
upgrade_mongodb(context, config, "3.6", "3.6")
|
|
||||||
context.invoke(compose.stop)
|
|
||||||
|
|
||||||
|
|
||||||
def upgrade_from_juniper(context: click.Context, config: Config) -> None:
|
|
||||||
click.echo(fmt.title("Upgrading from Juniper"))
|
|
||||||
tutor_env.save(context.obj.root, config)
|
|
||||||
|
|
||||||
click.echo(fmt.title("Stopping any existing platform"))
|
|
||||||
context.invoke(compose.stop)
|
|
||||||
|
|
||||||
if not config["RUN_MYSQL"]:
|
|
||||||
fmt.echo_info(
|
|
||||||
"You are not running MySQL (RUN_MYSQL=false). It is your "
|
|
||||||
"responsibility to upgrade your MySQL instance to v5.7. There is "
|
|
||||||
"nothing left to do to upgrade from Juniper."
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
click.echo(fmt.title("Upgrading MySQL from v5.6 to v5.7"))
|
|
||||||
context.invoke(compose.start, detach=True, services=["mysql"])
|
|
||||||
context.invoke(
|
|
||||||
compose.execute,
|
|
||||||
args=[
|
|
||||||
"mysql",
|
|
||||||
"bash",
|
|
||||||
"-e",
|
|
||||||
"-c",
|
|
||||||
"mysql_upgrade -u {} --password='{}'".format(
|
|
||||||
config["MYSQL_ROOT_USERNAME"], config["MYSQL_ROOT_PASSWORD"]
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
context.invoke(compose.stop)
|
|
||||||
|
|
||||||
|
|
||||||
def upgrade_from_koa(context: click.Context, config: Config) -> None:
|
|
||||||
if not config["RUN_MONGODB"]:
|
|
||||||
fmt.echo_info(
|
|
||||||
"You are not running MongDB (RUN_MONGODB=false). It is your "
|
|
||||||
"responsibility to upgrade your MongoDb instance to v4.0. There is "
|
|
||||||
"nothing left to do to upgrade from Koa to Lilac."
|
|
||||||
)
|
|
||||||
return
|
|
||||||
upgrade_mongodb(context, config, "4.0.25", "4.0")
|
|
||||||
|
|
||||||
|
|
||||||
def upgrade_mongodb(
|
|
||||||
context: click.Context,
|
|
||||||
config: Config,
|
|
||||||
to_docker_version: str,
|
|
||||||
to_compatibility_version: str,
|
|
||||||
) -> None:
|
|
||||||
click.echo(fmt.title("Upgrading MongoDb to v{}".format(to_docker_version)))
|
|
||||||
# Note that the DOCKER_IMAGE_MONGODB value is never saved, because we only save the
|
|
||||||
# environment, not the configuration.
|
|
||||||
config["DOCKER_IMAGE_MONGODB"] = "mongo:{}".format(to_docker_version)
|
|
||||||
tutor_env.save(context.obj.root, config)
|
|
||||||
context.invoke(compose.start, detach=True, services=["mongodb"])
|
|
||||||
fmt.echo_info("Waiting for mongodb to boot...")
|
|
||||||
sleep(10)
|
|
||||||
context.invoke(
|
|
||||||
compose.execute,
|
|
||||||
args=[
|
|
||||||
"mongodb",
|
|
||||||
"mongo",
|
|
||||||
"--eval",
|
|
||||||
'db.adminCommand({ setFeatureCompatibilityVersion: "%s" })'
|
|
||||||
% to_compatibility_version,
|
|
||||||
],
|
|
||||||
)
|
|
||||||
context.invoke(compose.stop)
|
|
||||||
|
|
||||||
|
|
||||||
local.add_command(quickstart)
|
local.add_command(quickstart)
|
||||||
|
0
tutor/commands/upgrade/__init__.py
Normal file
0
tutor/commands/upgrade/__init__.py
Normal file
123
tutor/commands/upgrade/k8s.py
Normal file
123
tutor/commands/upgrade/k8s.py
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
import click
|
||||||
|
|
||||||
|
from tutor import config as tutor_config
|
||||||
|
from tutor import env as tutor_env
|
||||||
|
from tutor import fmt
|
||||||
|
from tutor.commands import k8s
|
||||||
|
from tutor.commands.context import Context
|
||||||
|
from tutor.types import Config
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade_from(
|
||||||
|
context: Context, from_version: str, interactive: bool = False
|
||||||
|
) -> None:
|
||||||
|
config = tutor_config.load(context.root)
|
||||||
|
|
||||||
|
running_version = from_version
|
||||||
|
if running_version == "ironwood":
|
||||||
|
upgrade_from_ironwood(config)
|
||||||
|
running_version = "juniper"
|
||||||
|
|
||||||
|
if running_version == "juniper":
|
||||||
|
upgrade_from_juniper(config)
|
||||||
|
running_version = "koa"
|
||||||
|
|
||||||
|
if running_version == "koa":
|
||||||
|
upgrade_from_koa(config)
|
||||||
|
running_version = "lilac"
|
||||||
|
|
||||||
|
if running_version == "lilac":
|
||||||
|
upgrade_from_lilac(config)
|
||||||
|
running_version = "maple"
|
||||||
|
|
||||||
|
# Update env such that the build environment is up-to-date
|
||||||
|
tutor_env.save(context.root, config)
|
||||||
|
if interactive:
|
||||||
|
question = f"""Your platform was successfuly upgraded from {from_version} to {running_version}.
|
||||||
|
|
||||||
|
Depending on your setup, you might have to rebuild some of your Docker images
|
||||||
|
and push them to your private registry (if any). You can do this now by running
|
||||||
|
the following command in a different shell:
|
||||||
|
|
||||||
|
tutor images build openedx # add your custom images here
|
||||||
|
tutor images push openedx
|
||||||
|
|
||||||
|
Press enter when you are ready to continue"""
|
||||||
|
click.confirm(
|
||||||
|
fmt.question(question), default=True, abort=True, prompt_suffix=" "
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade_from_ironwood(config: Config) -> None:
|
||||||
|
if not config["RUN_MONGODB"]:
|
||||||
|
fmt.echo_info(
|
||||||
|
"You are not running MongDB (RUN_MONGODB=false). It is your "
|
||||||
|
"responsibility to upgrade your MongoDb instance to v3.6. There is "
|
||||||
|
"nothing left to do to upgrade from Ironwood."
|
||||||
|
)
|
||||||
|
return
|
||||||
|
message = """Automatic release upgrade is unsupported in Kubernetes. To upgrade from Ironwood, you should upgrade
|
||||||
|
your MongoDb cluster from v3.2 to v3.6. You should run something similar to:
|
||||||
|
|
||||||
|
# Upgrade from v3.2 to v3.4
|
||||||
|
tutor k8s stop
|
||||||
|
tutor config save --set DOCKER_IMAGE_MONGODB=mongo:3.4.24
|
||||||
|
tutor k8s start
|
||||||
|
tutor k8s exec mongodb mongo --eval 'db.adminCommand({ setFeatureCompatibilityVersion: "3.4" })'
|
||||||
|
|
||||||
|
# Upgrade from v3.4 to v3.6
|
||||||
|
tutor k8s stop
|
||||||
|
tutor config save --set DOCKER_IMAGE_MONGODB=mongo:3.6.18
|
||||||
|
tutor k8s start
|
||||||
|
tutor k8s exec mongodb mongo --eval 'db.adminCommand({ setFeatureCompatibilityVersion: "3.6" })'
|
||||||
|
|
||||||
|
tutor config save --unset DOCKER_IMAGE_MONGODB"""
|
||||||
|
fmt.echo_info(message)
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade_from_juniper(config: Config) -> None:
|
||||||
|
if not config["RUN_MYSQL"]:
|
||||||
|
fmt.echo_info(
|
||||||
|
"You are not running MySQL (RUN_MYSQL=false). It is your "
|
||||||
|
"responsibility to upgrade your MySQL instance to v5.7. There is "
|
||||||
|
"nothing left to do to upgrade from Juniper."
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
message = """Automatic release upgrade is unsupported in Kubernetes. To upgrade from Juniper, you should upgrade
|
||||||
|
your MySQL database from v5.6 to v5.7. You should run something similar to:
|
||||||
|
|
||||||
|
tutor k8s start
|
||||||
|
tutor k8s exec mysql bash -e -c "mysql_upgrade \
|
||||||
|
-u $(tutor config printvalue MYSQL_ROOT_USERNAME) \
|
||||||
|
--password='$(tutor config printvalue MYSQL_ROOT_PASSWORD)'
|
||||||
|
"""
|
||||||
|
fmt.echo_info(message)
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade_from_koa(config: Config) -> None:
|
||||||
|
if not config["RUN_MONGODB"]:
|
||||||
|
fmt.echo_info(
|
||||||
|
"You are not running MongDB (RUN_MONGODB=false). It is your "
|
||||||
|
"responsibility to upgrade your MongoDb instance to v4.0. There is "
|
||||||
|
"nothing left to do to upgrade to Lilac from Koa."
|
||||||
|
)
|
||||||
|
return
|
||||||
|
message = """Automatic release upgrade is unsupported in Kubernetes. To upgrade from Koa to Lilac, you should upgrade
|
||||||
|
your MongoDb cluster from v3.6 to v4.0. You should run something similar to:
|
||||||
|
|
||||||
|
tutor k8s stop
|
||||||
|
tutor config save --set DOCKER_IMAGE_MONGODB=mongo:4.0.25
|
||||||
|
tutor k8s start
|
||||||
|
tutor k8s exec mongodb mongo --eval 'db.adminCommand({ setFeatureCompatibilityVersion: "4.0" })'
|
||||||
|
tutor config save --unset DOCKER_IMAGE_MONGODB
|
||||||
|
"""
|
||||||
|
fmt.echo_info(message)
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade_from_lilac(config: Config) -> None:
|
||||||
|
fmt.echo_info(
|
||||||
|
"All Kubernetes services and deployments need to be deleted during "
|
||||||
|
"upgrade from Lilac to Maple"
|
||||||
|
)
|
||||||
|
k8s.delete_resources(config, resources=["deployments", "services"])
|
150
tutor/commands/upgrade/local.py
Normal file
150
tutor/commands/upgrade/local.py
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
from time import sleep
|
||||||
|
|
||||||
|
import click
|
||||||
|
|
||||||
|
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.types import Config
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade_from(
|
||||||
|
context: click.Context, from_version: str, interactive: bool = False
|
||||||
|
) -> None:
|
||||||
|
config = tutor_config.load(context.obj.root)
|
||||||
|
|
||||||
|
if interactive:
|
||||||
|
question = """You are about to upgrade your Open edX platform.
|
||||||
|
|
||||||
|
It is strongly recommended to make a backup before upgrading. To do so, run:
|
||||||
|
|
||||||
|
tutor local stop
|
||||||
|
sudo rsync -avr "$(tutor config printroot)"/ /tmp/tutor-backup/
|
||||||
|
|
||||||
|
In case of problem, to restore your backup you will then have to run: sudo rsync -avr /tmp/tutor-backup/ "$(tutor config printroot)"/
|
||||||
|
|
||||||
|
Are you sure you want to continue?"""
|
||||||
|
click.confirm(
|
||||||
|
fmt.question(question), default=True, abort=True, prompt_suffix=" "
|
||||||
|
)
|
||||||
|
|
||||||
|
running_version = from_version
|
||||||
|
if running_version == "ironwood":
|
||||||
|
upgrade_from_ironwood(context, config)
|
||||||
|
running_version = "juniper"
|
||||||
|
|
||||||
|
if running_version == "juniper":
|
||||||
|
upgrade_from_juniper(context, config)
|
||||||
|
running_version = "koa"
|
||||||
|
|
||||||
|
if running_version == "koa":
|
||||||
|
upgrade_from_koa(context, config)
|
||||||
|
running_version = "lilac"
|
||||||
|
|
||||||
|
if running_version == "lilac":
|
||||||
|
# Nothing to do here
|
||||||
|
running_version = "maple"
|
||||||
|
|
||||||
|
# Update env such that the build environment is up-to-date
|
||||||
|
tutor_env.save(context.obj.root, config)
|
||||||
|
if interactive:
|
||||||
|
question = f"""Your platform was successfuly upgraded from {from_version} to {running_version}.
|
||||||
|
|
||||||
|
Depending on your setup, you might have to rebuild some of your Docker images.
|
||||||
|
You can do this now by running the following command in a different shell:
|
||||||
|
|
||||||
|
tutor images build openedx # add your custom images here
|
||||||
|
|
||||||
|
Press enter when you are ready to continue"""
|
||||||
|
click.confirm(
|
||||||
|
fmt.question(question), default=True, abort=True, prompt_suffix=" "
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade_from_ironwood(context: click.Context, config: Config) -> None:
|
||||||
|
click.echo(fmt.title("Upgrading from Ironwood"))
|
||||||
|
tutor_env.save(context.obj.root, config)
|
||||||
|
|
||||||
|
click.echo(fmt.title("Stopping any existing platform"))
|
||||||
|
context.invoke(compose.stop)
|
||||||
|
|
||||||
|
if not config["RUN_MONGODB"]:
|
||||||
|
fmt.echo_info(
|
||||||
|
"You are not running MongDB (RUN_MONGODB=false). It is your "
|
||||||
|
"responsibility to upgrade your MongoDb instance to v3.6. There is "
|
||||||
|
"nothing left to do to upgrade from Ironwood to Juniper."
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
upgrade_mongodb(context, config, "3.4", "3.4")
|
||||||
|
context.invoke(compose.stop)
|
||||||
|
upgrade_mongodb(context, config, "3.6", "3.6")
|
||||||
|
context.invoke(compose.stop)
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade_from_juniper(context: click.Context, config: Config) -> None:
|
||||||
|
click.echo(fmt.title("Upgrading from Juniper"))
|
||||||
|
tutor_env.save(context.obj.root, config)
|
||||||
|
|
||||||
|
click.echo(fmt.title("Stopping any existing platform"))
|
||||||
|
context.invoke(compose.stop)
|
||||||
|
|
||||||
|
if not config["RUN_MYSQL"]:
|
||||||
|
fmt.echo_info(
|
||||||
|
"You are not running MySQL (RUN_MYSQL=false). It is your "
|
||||||
|
"responsibility to upgrade your MySQL instance to v5.7. There is "
|
||||||
|
"nothing left to do to upgrade from Juniper."
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
click.echo(fmt.title("Upgrading MySQL from v5.6 to v5.7"))
|
||||||
|
context.invoke(compose.start, detach=True, services=["mysql"])
|
||||||
|
context.invoke(
|
||||||
|
compose.execute,
|
||||||
|
args=[
|
||||||
|
"mysql",
|
||||||
|
"bash",
|
||||||
|
"-e",
|
||||||
|
"-c",
|
||||||
|
f"mysql_upgrade -u {config['MYSQL_ROOT_USERNAME']} --password='{config['MYSQL_ROOT_PASSWORD']}'",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
context.invoke(compose.stop)
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade_from_koa(context: click.Context, config: Config) -> None:
|
||||||
|
if not config["RUN_MONGODB"]:
|
||||||
|
fmt.echo_info(
|
||||||
|
"You are not running MongDB (RUN_MONGODB=false). It is your "
|
||||||
|
"responsibility to upgrade your MongoDb instance to v4.0. There is "
|
||||||
|
"nothing left to do to upgrade from Koa to Lilac."
|
||||||
|
)
|
||||||
|
return
|
||||||
|
upgrade_mongodb(context, config, "4.0.25", "4.0")
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade_mongodb(
|
||||||
|
context: click.Context,
|
||||||
|
config: Config,
|
||||||
|
to_docker_version: str,
|
||||||
|
to_compatibility_version: str,
|
||||||
|
) -> None:
|
||||||
|
click.echo(fmt.title(f"Upgrading MongoDb to v{to_docker_version}"))
|
||||||
|
# Note that the DOCKER_IMAGE_MONGODB value is never saved, because we only save the
|
||||||
|
# environment, not the configuration.
|
||||||
|
config["DOCKER_IMAGE_MONGODB"] = f"mongo:{to_docker_version}"
|
||||||
|
tutor_env.save(context.obj.root, config)
|
||||||
|
context.invoke(compose.start, detach=True, services=["mongodb"])
|
||||||
|
fmt.echo_info("Waiting for mongodb to boot...")
|
||||||
|
sleep(10)
|
||||||
|
context.invoke(
|
||||||
|
compose.execute,
|
||||||
|
args=[
|
||||||
|
"mongodb",
|
||||||
|
"mongo",
|
||||||
|
"--eval",
|
||||||
|
f'db.adminCommand({{ setFeatureCompatibilityVersion: "{to_compatibility_version}" }})',
|
||||||
|
],
|
||||||
|
)
|
||||||
|
context.invoke(compose.stop)
|
Loading…
Reference in New Issue
Block a user