Last active
November 28, 2023 07:01
-
-
Save h0hmj/288c4cd6753d571c186e2b81eaa14edb to your computer and use it in GitHub Desktop.
fix curveadm cluster after migration
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import yaml | |
import sqlite3 | |
class CurveadmHostsHandler: | |
def __init__(self): | |
self.data = None | |
def load(self, path=None): | |
if path is not None: | |
with open(path, "r") as fd: | |
self.data = yaml.safe_load(fd) | |
os.system("curveadm hosts show > /tmp/hosts.yaml") | |
with open("/tmp/hosts.yaml", "r") as fd: | |
self.data = yaml.safe_load(fd) | |
def dump(self, path): | |
if self.data is None: | |
raise Exception("load hosts first") | |
with open(path, "w") as fd: | |
yaml.safe_dump(self.data, fd) | |
def commit(self, path): | |
os.system(f'echo "yes"| curveadm hosts commit {path}') | |
def add_host(self, host_alias, hostname): | |
if self.data is None: | |
raise Exception("load hosts first") | |
hosts = self.data["hosts"] | |
for host in hosts: | |
if host["host"] == host_alias: | |
if host["hostname"] == hostname: | |
return | |
else: | |
raise Exception("host alias already exist with different hostname") | |
hosts.append({"host": host_alias, "hostname": hostname}) | |
class CurveadmClusterHandler: | |
def __init__(self, db_path, name): | |
self.topo = None | |
self.name = name | |
self.id = None | |
self.uuid = None | |
self.db_path = db_path | |
self.db_connection = sqlite3.connect(self.db_path) | |
self.db_cursor = self.db_connection.cursor() | |
result = self.db_cursor.execute( | |
f'SELECT id,uuid,topology FROM clusters WHERE name="{self.name}"' | |
).fetchone() | |
if result is None: | |
raise Exception("cluster not exist") | |
else: | |
self.id, self.uuid, self.topo = result | |
self.topo = yaml.safe_load(self.topo) | |
def __calculate_service_id( | |
self, uuid, service_name, host_alias, host_index, instance_index | |
): | |
import hashlib | |
m = hashlib.md5() | |
print(f"{uuid}_{service_name}_{host_alias}_{host_index}_{instance_index}") | |
m.update( | |
f"{uuid}_{service_name}_{host_alias}_{host_index}_{instance_index}".encode( | |
"utf-8" | |
) | |
) | |
return str(m.hexdigest()) | |
def add_service(self, service_name, host_alias, instance_num, container_ids): | |
if len(container_ids) != instance_num: | |
raise Exception("container_ids num not match instance_num") | |
# todo: check variable | |
services = self.topo[f"{service_name}_services"] | |
instances = services["deploy"] | |
host_index = len(instances) | |
for instance in instances: | |
host = instance["host"] | |
if host_alias == host: | |
print( | |
f"service {service_name}.{host_alias} already exist in topo, skip" | |
) | |
return | |
instances.append({"host": host_alias, "instances": instance_num}) | |
for i in range(instance_num): | |
service_id = self.__calculate_service_id( | |
self.uuid, service_name, host_alias, host_index, i | |
) | |
self.db_cursor.execute( | |
f'INSERT INTO containers (id, cluster_id, container_id) VALUES ("{service_id[:12]}", {self.id}, "{container_ids[i]}") ON CONFLICT (id) DO NOTHING' | |
) | |
self.db_cursor.execute( | |
"UPDATE clusters SET topology = ? WHERE name = ?", | |
(yaml.safe_dump(self.topo), "test"), | |
) | |
self.db_connection.commit() | |
# usage example, backup your curveadm db first | |
# tool target: fix curveadm hosts and cluster topology to match your real cluster | |
# 1. add hosts | |
hosts = CurveadmHostsHandler() | |
hosts.load() | |
hosts.add_host("vm4", "192.168.16.32") | |
hosts.add_host("vm5", "192.168.16.35") | |
hosts.add_host("vm6", "192.168.16.36") | |
hosts.dump("/tmp/hosts_mod.yaml") | |
hosts.commit("/tmp/hosts_mod.yaml") | |
# 2. add services | |
# full container id get from docker ps --no-trunc | |
cluster = CurveadmClusterHandler("/root/.curveadm/data/curveadm.db", "test") | |
cluster.add_service("etcd", "vm4", 1, ["-"]) | |
cluster.add_service("etcd", "vm5", 1, ["-"]) | |
cluster.add_service("etcd", "vm6", 1, ["-"]) | |
cluster.add_service("mds", "vm4", 1, ["-"]) | |
cluster.add_service("mds", "vm5", 1, ["-"]) | |
cluster.add_service("mds", "vm6", 1, ["-"]) | |
cluster.add_service("metaserver", "vm4", 3, ["-", "-", "-"]) | |
cluster.add_service("metaserver", "vm5", 3, ["-", "-", "-"]) | |
cluster.add_service("metaserver", "vm6", 3, ["-", "-", "-"]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment