mirror of https://github.com/Mai-with-u/MaiBot.git
90 lines
3.4 KiB
Python
90 lines
3.4 KiB
Python
#!/bin/python3
|
||
# 这个程序的作用是辅助麦麦的WebUI更新配置文件,随core容器持续运行。
|
||
# 麦麦的配置文件存储于ConfigMap中,挂载进core容器后属于只读文件,无法直接修改。
|
||
# 此程序将core容器内的配置文件替换为可读写的中间层临时文件。启动时将实际配置文件写入,并在后台持续检测文件变化,实时同步到k8s apiServer,反向修改ConfigMap。
|
||
# 工作目录:/MaiMBot/webui-cm-sync
|
||
|
||
import os
|
||
import time
|
||
from datetime import datetime
|
||
from kubernetes import client, config
|
||
from watchdog.observers import Observer
|
||
from watchdog.events import FileSystemEventHandler
|
||
|
||
work_dir = '/MaiMBot/webui-cm-sync'
|
||
os.chdir(work_dir)
|
||
|
||
config.load_incluster_config()
|
||
core_api = client.CoreV1Api()
|
||
with open("/var/run/secrets/kubernetes.io/serviceaccount/namespace", "r") as f:
|
||
namespace = f.read().strip()
|
||
release_name = os.getenv("RELEASE_NAME")
|
||
configmap_name = f'{release_name}-maibot-core'
|
||
|
||
# 过滤列表,只监控指定文件
|
||
target_files = {
|
||
os.path.abspath("model_config.toml"): "model_config.toml",
|
||
os.path.abspath("bot_config.toml"): "bot_config.toml"
|
||
}
|
||
|
||
|
||
def get_configmap():
|
||
"""获取core的ConfigMap内容"""
|
||
cm = core_api.read_namespaced_config_map(name=configmap_name, namespace=namespace)
|
||
return cm.data
|
||
|
||
|
||
def set_configmap(configmap_data: dict[str, str]):
|
||
"""设置core的ConfigMap内容"""
|
||
core_api.patch_namespaced_config_map(configmap_name, namespace, {'data': configmap_data})
|
||
|
||
|
||
class ConfigObserverHandler(FileSystemEventHandler):
|
||
"""配置文件变化的事件处理器"""
|
||
def on_modified(self, event):
|
||
if os.path.abspath(event.src_path) in target_files:
|
||
print(
|
||
f'[{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}] File `{event.src_path}` was modified. Start to sync...')
|
||
with open(event.src_path, "r", encoding="utf-8") as _f:
|
||
current_data = _f.read()
|
||
new_cm = {
|
||
target_files[os.path.abspath("model_config.toml")]: current_data
|
||
}
|
||
try:
|
||
set_configmap(new_cm)
|
||
except client.exceptions.ApiException as _e:
|
||
print(f'\tError while setting configmap:\n'
|
||
f'\t\tStatus Code: {_e.status}\n'
|
||
f'\t\tReason: {_e.reason}')
|
||
|
||
|
||
if __name__ == '__main__':
|
||
# 初始化配置文件
|
||
print(f'[{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}] Initializing config files...')
|
||
try:
|
||
__initial_model_config = get_configmap()['model_config.toml']
|
||
__initial_bot_config = get_configmap()['bot_config.toml']
|
||
except client.exceptions.ApiException as e:
|
||
print(f'\tError while getting configmap:\n'
|
||
f'\t\tStatus Code: {e.status}\n'
|
||
f'\t\tReason: {e.reason}')
|
||
exit(1)
|
||
with open('model_config.toml', 'w') as f:
|
||
f.write(__initial_model_config)
|
||
with open('bot_config.toml', 'w') as f:
|
||
f.write(__initial_bot_config)
|
||
with open('ready', 'w') as f:
|
||
f.write('true')
|
||
print(f'[{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}] Initializing done. Ready to sync.')
|
||
|
||
# 持续检测变化并同步
|
||
observer = Observer()
|
||
observer.schedule(ConfigObserverHandler(), '', recursive=False)
|
||
observer.start()
|
||
try:
|
||
while True:
|
||
time.sleep(1)
|
||
except KeyboardInterrupt:
|
||
observer.stop()
|
||
observer.join()
|