284 lines
8.7 KiB
Python
284 lines
8.7 KiB
Python
from __future__ import annotations
|
|
|
|
import os
|
|
import typing
|
|
|
|
import click
|
|
import jingrow
|
|
|
|
if typing.TYPE_CHECKING:
|
|
from jcloude.infrastructure.doctype.arm_build_record.arm_build_record import ARMBuildRecord
|
|
from jcloude.infrastructure.doctype.arm_docker_image.arm_docker_image import ARMDockerImage
|
|
from jcloude.infrastructure.doctype.virtual_machine_migration.virtual_machine_migration import (
|
|
VirtualMachineMigration,
|
|
)
|
|
from jcloude.jcloude.doctype.server.server import Server
|
|
|
|
|
|
arm_machine_mappings = {
|
|
"t2": "t4g",
|
|
"c6i": "c8g",
|
|
"m6i": "m8g",
|
|
"m7i": "m8g",
|
|
"r6i": "r8g",
|
|
# Following are for Zurich due to lack of newer processors in that region
|
|
"r5": "r7g",
|
|
"m5": "m7g",
|
|
"c5": "c7g",
|
|
}
|
|
|
|
amd_machine_mappings = {"r6i": "m6a", "m6i": "m6a", "c6i": "m6a", "m5": "m6a", "r7i": "m6a", "m7i": "m6a"}
|
|
|
|
|
|
def has_arm_build_record(server: str) -> bool:
|
|
return bool(jingrow.get_value("ARM Build Record", {"server": server}))
|
|
|
|
|
|
def check_image_build_failure(arm_build_record: ARMBuildRecord) -> bool:
|
|
return any(arm_image.status != "Success" for arm_image in arm_build_record.arm_images)
|
|
|
|
|
|
def create_vmm(server: str, virtual_machine_image: str, target_machine_type: str) -> VirtualMachineMigration:
|
|
virtual_machine_migration: VirtualMachineMigration = jingrow.get_pg(
|
|
{
|
|
"doctype": "Virtual Machine Migration",
|
|
"virtual_machine_image": virtual_machine_image,
|
|
"machine_type": target_machine_type,
|
|
"virtual_machine": server,
|
|
}
|
|
)
|
|
return virtual_machine_migration.insert()
|
|
|
|
|
|
def vmm(server, vmi, amd_conversion: bool = False) -> VirtualMachineMigration:
|
|
machine_type = jingrow.db.get_value("Virtual Machine", {"name": server}, "machine_type")
|
|
machine_series, machine_size = machine_type.split(".")
|
|
|
|
machine_mappings = arm_machine_mappings if not amd_conversion else amd_machine_mappings
|
|
if amd_conversion and ("r6i" in machine_series or "r7i" in machine_series):
|
|
if machine_size == "xlarge":
|
|
machine_size = "2xlarge"
|
|
else:
|
|
machine_size = machine_size.replace("2", "4")
|
|
|
|
virtual_machine_migration: VirtualMachineMigration = create_vmm(
|
|
server=server,
|
|
virtual_machine_image=vmi,
|
|
target_machine_type=f"{machine_mappings[machine_series]}.{machine_size}",
|
|
)
|
|
return virtual_machine_migration
|
|
|
|
|
|
def connect(bench_dir, site_dir):
|
|
sites_dir = os.path.join(bench_dir, "sites")
|
|
jingrow.init(site=site_dir, sites_path=sites_dir)
|
|
jingrow.connect()
|
|
|
|
|
|
def load_servers_from_file(file_path: str) -> list[str]:
|
|
with open(file_path) as server_file:
|
|
return server_file.read().strip().split("\n")
|
|
|
|
|
|
@click.group()
|
|
@click.option("--site", "site_name", required=True, help="Jingrow site name")
|
|
def cli(site_name):
|
|
"""CLI entry point."""
|
|
bench_dir = os.path.dirname(__file__).split("apps")[0]
|
|
site_dir = os.path.join(bench_dir, "sites", site_name)
|
|
connect(bench_dir, site_dir)
|
|
|
|
|
|
@cli.command()
|
|
@click.option(
|
|
"--server-file", type=click.Path(exists=True), help="Path to a file containing a list of servers."
|
|
)
|
|
@click.argument("servers", nargs=-1, type=str)
|
|
def trigger_arm_build(servers: list[str], server_file: str):
|
|
"""Trigger ARM build for one or more servers."""
|
|
if server_file:
|
|
servers = load_servers_from_file(server_file)
|
|
|
|
for server in servers:
|
|
if has_arm_build_record(server):
|
|
continue
|
|
|
|
server: Server = jingrow.get_pg("Server", server)
|
|
server.collect_arm_images()
|
|
jingrow.db.commit()
|
|
|
|
|
|
@cli.command()
|
|
@click.option(
|
|
"--server-file", type=click.Path(exists=True), help="Path to a file containing a list of servers."
|
|
)
|
|
@click.argument("servers", nargs=-1, type=str)
|
|
def pull_images_on_servers(servers: list[str], server_file: str):
|
|
"""Trigger image pulls on Intel server to be converted"""
|
|
if server_file:
|
|
servers = load_servers_from_file(server_file)
|
|
|
|
for server in servers:
|
|
arm_build_record: ARMBuildRecord = jingrow.get_pg("ARM Build Record", {"server": server})
|
|
|
|
try:
|
|
arm_build_record.pull_images()
|
|
print(f"Pulled image on {server}")
|
|
except jingrow.ValidationError:
|
|
print(f"Skipping server {server} due to failed builds")
|
|
|
|
jingrow.db.commit()
|
|
|
|
|
|
@cli.command()
|
|
@click.option("--vmi", default="f377-mumbai.jingrow.cloud")
|
|
@click.option("--vmi-cluster", required=True)
|
|
@click.option(
|
|
"--server-file", type=click.Path(exists=True), help="Path to a file containing a list of servers."
|
|
)
|
|
@click.argument("servers", nargs=-1, type=str)
|
|
def update_image_and_create_migration(
|
|
vmi: str,
|
|
vmi_cluster: str,
|
|
servers: list[str],
|
|
server_file: str,
|
|
):
|
|
"""Update docker image on bench config and create virtual machine migration"""
|
|
vmi = jingrow.get_value("Virtual Machine Image", {"virtual_machine": vmi, "cluster": vmi_cluster}, "name")
|
|
if not vmi:
|
|
print(f"Aborting VMI not found {vmi}!")
|
|
return
|
|
|
|
if server_file:
|
|
servers = load_servers_from_file(server_file)
|
|
|
|
for server in servers:
|
|
arm_build_record: ARMBuildRecord = jingrow.get_pg("ARM Build Record", {"server": server})
|
|
try:
|
|
arm_build_record.update_image_tags_on_benches()
|
|
virtual_machine_migration = vmm(server, vmi)
|
|
jingrow.db.commit()
|
|
print(f"Created {virtual_machine_migration.name}")
|
|
except jingrow.ValidationError as e:
|
|
print(f"Aborting: {e}!")
|
|
break
|
|
|
|
|
|
@cli.command()
|
|
@click.option("--vmi", default="m263-mumbai.jingrow.cloud")
|
|
@click.option("--vmi-cluster", required=True)
|
|
@click.option(
|
|
"--server-file",
|
|
type=click.Path(exists=True),
|
|
help="Path to a file containing a list of servers.",
|
|
)
|
|
@click.option("--start", type=bool, default=False)
|
|
@click.argument("servers", nargs=-1, type=str)
|
|
def convert_database_servers(
|
|
vmi: str, vmi_cluster: str, servers: list[str], server_file: str, start: bool = False
|
|
):
|
|
vmi = jingrow.get_value("Virtual Machine Image", {"virtual_machine": vmi, "cluster": vmi_cluster}, "name")
|
|
if not vmi:
|
|
print(f"Aborting VMI not found {vmi}!")
|
|
return
|
|
|
|
if server_file:
|
|
servers = load_servers_from_file(server_file)
|
|
|
|
for server in servers:
|
|
virtual_machine_migration = vmm(server, vmi, amd_conversion=True)
|
|
jingrow.db.commit()
|
|
print(f"Created {virtual_machine_migration.name}")
|
|
|
|
if start:
|
|
for server in servers:
|
|
virtual_machine_migration: VirtualMachineMigration = jingrow.get_pg(
|
|
"Virtual Machine Migration", {"virtual_machine": server}
|
|
)
|
|
virtual_machine_migration.execute()
|
|
jingrow.db.commit()
|
|
|
|
|
|
@cli.command()
|
|
@click.option(
|
|
"--server-file", type=click.Path(exists=True), help="Path to a file containing a list of servers."
|
|
)
|
|
@click.argument("servers", nargs=-1, type=str)
|
|
def arm_build_info(servers: list[str], server_file: str):
|
|
total, successful, failed, running = 0, 0, 0, 0
|
|
if server_file:
|
|
servers = load_servers_from_file(server_file)
|
|
|
|
def _status_info(images: list[ARMDockerImage], status: str):
|
|
return len([image for image in images if image.status == status])
|
|
|
|
for server in servers:
|
|
arm_build_record: ARMBuildRecord = jingrow.get_pg("ARM Build Record", {"server": server})
|
|
arm_build_record.sync_status()
|
|
total += len(arm_build_record.arm_images)
|
|
running += _status_info(arm_build_record.arm_images, "Running")
|
|
successful += _status_info(arm_build_record.arm_images, "Success")
|
|
failed += _status_info(arm_build_record.arm_images, "Failure")
|
|
|
|
print(f"Total: {total}\nSuccessful: {successful}\nRunning: {running}\nFailed: {failed}")
|
|
|
|
|
|
@cli.command()
|
|
@click.option(
|
|
"--server-file", type=click.Path(exists=True), help="Path to a file containing a list of servers."
|
|
)
|
|
@click.option("--vmi", default="f436-mumbai.jingrow.cloud")
|
|
@click.option("--vmi-cluster", required=True)
|
|
@click.argument("servers", nargs=-1, type=str)
|
|
def convert_to_amd(servers: list[str], vmi: str, server_file: str, vmi_cluster: str):
|
|
"""Update docker image on bench config and create virtual machine migration"""
|
|
vmi = jingrow.get_value("Virtual Machine Image", {"virtual_machine": vmi, "cluster": vmi_cluster}, "name")
|
|
if not vmi:
|
|
print(f"Aborting VMI not found {vmi}!")
|
|
return
|
|
|
|
if server_file:
|
|
servers = load_servers_from_file(server_file)
|
|
|
|
for server in servers:
|
|
try:
|
|
virtual_machine_migration = vmm(server, vmi, amd_conversion=True)
|
|
jingrow.db.commit()
|
|
print(f"Created {virtual_machine_migration.name}")
|
|
except jingrow.ValidationError as e:
|
|
print(f"Aborting: {e}!")
|
|
break
|
|
|
|
|
|
@cli.command()
|
|
@click.option(
|
|
"--server-file", type=click.Path(exists=True), help="Path to a file containing a list of servers."
|
|
)
|
|
@click.argument("servers", nargs=-1, type=str)
|
|
def database_post_migration_steps(servers: list[str], server_file: str):
|
|
"""Not a part of the migration script since"""
|
|
if server_file:
|
|
servers = load_servers_from_file(server_file)
|
|
|
|
for server in servers:
|
|
server = jingrow.get_pg("Database Server", server)
|
|
server.set_swappiness()
|
|
server.add_glass_file()
|
|
server.install_filebeat()
|
|
server.adjust_memory_config()
|
|
server.setup_logrotate()
|
|
server.save()
|
|
|
|
|
|
@cli.result_callback()
|
|
def cleanup(*args, **kwargs):
|
|
jingrow.destroy()
|
|
|
|
|
|
def main():
|
|
cli(obj={})
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|