Module paracrine.services.redis.common
Expand source code
import json
import os
import re
from ...helpers.config import build_config, core_config, other_config, other_config_file
from ...helpers.debian import apt_is_installed
from ...helpers.fs import run_command
from ...helpers.network import wireguard_ip
from ...runners.core import wireguard_ip_for_machine_for
MASTER_FILE = "masters.json"
def get_existing_masters(local):
if local:
master_file = other_config_file(MASTER_FILE)
if os.path.exists(master_file):
return json.load(open(master_file))
else:
return []
else:
try:
return other_config("masters.json")
except KeyError:
return []
def get_master_ip():
existing_masters = get_existing_masters(False)
if len(existing_masters) > 0:
if all([master == existing_masters[0] for master in existing_masters]):
# everyone agrees, awesome
return existing_masters[0]
rated = {}
for master in existing_masters:
if master not in rated:
rated[master] = 1
else:
rated[master] += 1
highest = sorted(rated.values(), reverse=True)[0]
best_masters = [k for k in rated.keys() if rated[k] == highest]
if len(best_masters) != 1:
raise Exception(
f"Can't choose, because {len(best_masters)} with {highest} entries in {best_masters}. See also {existing_masters}"
)
return best_masters[0]
if not apt_is_installed("redis-tools"):
return wireguard_ip_for_machine_for("redis-master")
LOCAL = build_config(core_config())
local_ip = wireguard_ip()
try:
output = run_command(
f"redis-cli -a {LOCAL['REDIS_PASSWORD']} -h {local_ip} info replication"
)
except AssertionError:
# redis isn't up
return wireguard_ip_for_machine_for("redis-master")
if "role:master" in output and ",port=6379,state=online" in output:
master_ip = local_ip
elif "master_host:" in output:
master_ip = re.search("master_host:(.+)", output).groups()[0].strip()
else:
master_ip = wireguard_ip_for_machine_for("redis-master")
return master_ip
Functions
def get_existing_masters(local)
-
Expand source code
def get_existing_masters(local): if local: master_file = other_config_file(MASTER_FILE) if os.path.exists(master_file): return json.load(open(master_file)) else: return [] else: try: return other_config("masters.json") except KeyError: return []
def get_master_ip()
-
Expand source code
def get_master_ip(): existing_masters = get_existing_masters(False) if len(existing_masters) > 0: if all([master == existing_masters[0] for master in existing_masters]): # everyone agrees, awesome return existing_masters[0] rated = {} for master in existing_masters: if master not in rated: rated[master] = 1 else: rated[master] += 1 highest = sorted(rated.values(), reverse=True)[0] best_masters = [k for k in rated.keys() if rated[k] == highest] if len(best_masters) != 1: raise Exception( f"Can't choose, because {len(best_masters)} with {highest} entries in {best_masters}. See also {existing_masters}" ) return best_masters[0] if not apt_is_installed("redis-tools"): return wireguard_ip_for_machine_for("redis-master") LOCAL = build_config(core_config()) local_ip = wireguard_ip() try: output = run_command( f"redis-cli -a {LOCAL['REDIS_PASSWORD']} -h {local_ip} info replication" ) except AssertionError: # redis isn't up return wireguard_ip_for_machine_for("redis-master") if "role:master" in output and ",port=6379,state=online" in output: master_ip = local_ip elif "master_host:" in output: master_ip = re.search("master_host:(.+)", output).groups()[0].strip() else: master_ip = wireguard_ip_for_machine_for("redis-master") return master_ip