Compare commits

..

No commits in common. "86385261fecf0d16cecd459dc93ece5e1931c366" and "9632552cffc5ac109028c65dd6bdcc7a8fe33a6f" have entirely different histories.

5 changed files with 29 additions and 108 deletions

View file

@ -1,13 +0,0 @@
services:
master-node:
container_name: master_node_container
image: master_node_image
build:
context: ./
dockerfile: Dockerfile
volumes:
- ./src:/app/src
- /var/run/docker.sock:/var/run/docker.sock
networks:
- defaults
restart: unless-stopped

View file

@ -1,5 +1,4 @@
import os import os
import requests
import configparser import configparser
import datetime import datetime
@ -78,9 +77,6 @@ app.config["SESSION_TYPE"] = "filesystem"
@app.before_first_request @app.before_first_request
def startup(): def startup():
# Приведем систему в начальное состояние # Приведем систему в начальное состояние
# TODO: запуск плейбука, который проверит кодовую базу
# желательно, чтобы он скопировал код и указал путь к корневой директории
# в переменной окружения ML_PATH
reset_to_initial_state() reset_to_initial_state()
app_logger.info("master-node запущена!") app_logger.info("master-node запущена!")
@ -115,47 +111,6 @@ def run_ansible():
app_logger.error(data) app_logger.error(data)
return make_response(jsonify(data), 400) return make_response(jsonify(data), 400)
@app.route('/api/v1.0/interact_with_custom_modules', methods=['POST'])
@auth.login_required
def interact_with_custom_modules():
# Получим данные запроса
data = request.get_json()
# TODO: настроить адрес бекенда
back_url = "https://api.statanly.com:8443"
try:
# TODO: получим токен авторизации
token = requests.post(
f"{back_url}/api/auth/login",
data = {"username": "admin@eatom.ru", "password": "admin"}
).json()['access_token']
# выполним необходимую операция с кастомными модулями
if data["request_type"] == "get_all_modules":
response = requests.get(
f"{back_url}/api/custom-modules",
headers = {"Authorization": f"Bearer {token}"}
)
elif data["request_type"] == "change_status":
response = requests.patch(
f"{back_url}/api/custom-modules/{data['module_id']}",
json = {"status": data["status"]}
)
data = {
"response": response.json(),
"message": "",
"code": "SUCCESS"
}
return make_response(jsonify(data), 200)
except Exception as e:
data = {
"response": "",
"message": f"Cannot interact with custom modules: {e}",
"code": "FAILED"
}
return make_response(jsonify(data), 400)
# -------------------------- # --------------------------
# Методы, которыми управляет scheduler # Методы, которыми управляет scheduler
# -------------------------- # --------------------------
@ -170,12 +125,14 @@ def interact_with_custom_modules():
# AUTO.check_cluster_state() # AUTO.check_cluster_state()
# app_logger.debug("Finished with auto cluster state") # app_logger.debug("Finished with auto cluster state")
scheduler.task( #@scheduler.task(
"interval", # "interval",
id="cluster_state", # id="cluster_state",
seconds=30, # seconds=30,
misfire_grace_time=900 # misfire_grace_time=900
)(create_custom_containers) #)
#def custom_modules():
# create_custom_containers()
if __name__ == "__main__": if __name__ == "__main__":
port = int(os.environ.get("PORT", 5010)) port = int(os.environ.get("PORT", 5010))

View file

@ -16,10 +16,8 @@ def load_env_files(
def get_env_vars(): def get_env_vars():
# Проверяем наличие кодовой базы # Проверяем наличие кодовой базы
try: # TODO: ansible playbook
ml_path = os.environ["ML_PATH"] ml_path = "/path-to-ml"
except KeyError:
raise RuntimeError("Не указан путь к кодовой базе мл модулей")
# Получаем переменные # Получаем переменные
env_files = [f"{ml_path}/.env", f"{ml_path}/docker/.env.dev", f"{ml_path}/docker/.env.compose_vars"] env_files = [f"{ml_path}/.env", f"{ml_path}/docker/.env.dev", f"{ml_path}/docker/.env.compose_vars"]

View file

@ -1,28 +1,20 @@
from multiprocessing import Process from multiprocessing import Process
import os
import requests import requests
from .manager_methods import start_container, stop_container from .manager_methods import start_container, stop_container
from .get_env_vars import get_env_vars from .get_env_vars import get_env_vars
from ..logger import LoggerFactory from ..logger import LoggerFactory
_AUTH_URL = "https://api.statanly.com:8443/api/auth/login"
_ALL_MODULES_URL = "https://api.statanly.com:8443/api/custom-modules"
manager_logger = LoggerFactory.get_logger("CustomModuleManager") manager_logger = LoggerFactory.get_logger("CustomModuleManager")
def get_all_modules():
response = requests.post(
f"http://localhost:{int(os.environ.get('PORT', 5010))}/api/v1.0/interact_with_custom_modules",
data = {"request_type": "get_all_modules", "module_id": None, "status": None}
)
if response.status_code != 200:
manager_logger.warning(f"Не удалось получить информацию о кастомных модулях. Код: {response['message']}")
return
return response.json()
def reset_to_initial_state(): def reset_to_initial_state():
# получим информацию о кастомных модулей # получим информацию о кастомных модулей
custom_modules = get_all_modules() response = requests.get(_ALL_MODULES_URL)
if not custom_modules: if response.status_code != 200:
manager_logger.warning(f"Не удалось получить информацию о кастомных модулях. Код: {response.status_code}")
return return
# получим переменные окружения # получим переменные окружения
@ -34,13 +26,13 @@ def reset_to_initial_state():
# проходимся по всем модулям (id, title, is_SIZ, status, model) # проходимся по всем модулям (id, title, is_SIZ, status, model)
processed_modules = [] processed_modules = []
custom_modules = response.json()
for module in custom_modules: for module in custom_modules:
# инициализируем переменные контейнера # инициализируем переменные контейнера
container_name = f"{all_envs['COMPOSE_PROJECT_NAME']}_custom_module{module['id']}" container_name = f"{all_envs['COMPOSE_PROJECT_NAME']}_custom_module{module['id']}"
# останавливаем контейнер в отдельном процессе # останавливаем контейнер в отдельном процессе
p = Process(target=stop_container, p = Process(target=stop_container,
args=( args=(
module['id'],
container_name, container_name,
) )
) )
@ -53,8 +45,9 @@ def reset_to_initial_state():
def create_custom_containers(): def create_custom_containers():
# получим информацию о кастомных модулей # получим информацию о кастомных модулей
custom_modules = get_all_modules() response = requests.get(_ALL_MODULES_URL)
if not custom_modules: if response.status_code != 200:
manager_logger.warning(f"Не удалось получить информацию о кастомных модулях. Код: {response.status_code}")
return return
# получим переменные окружения # получим переменные окружения
@ -66,6 +59,8 @@ def create_custom_containers():
# проходимся по всем модулям (id, title, is_SIZ, status, model) # проходимся по всем модулям (id, title, is_SIZ, status, model)
processed_modules = [] processed_modules = []
custom_modules = response.json()
print(custom_modules)
for module in custom_modules: for module in custom_modules:
if module["status"] in ["остановлен", "не создан"] and module["model"]["weights"].strip(): if module["status"] in ["остановлен", "не создан"] and module["model"]["weights"].strip():
# инициализируем переменные контейнера # инициализируем переменные контейнера
@ -75,7 +70,6 @@ def create_custom_containers():
# запускаем контейнер в отдельном процессе # запускаем контейнер в отдельном процессе
p = Process(target=start_container, p = Process(target=start_container,
args=( args=(
module['id'],
image_name, image_name,
build_args, build_args,
container_name, container_name,
@ -92,8 +86,9 @@ def create_custom_containers():
def stop_all_custom_containers(): def stop_all_custom_containers():
# получим информацию о кастомных модулей # получим информацию о кастомных модулей
custom_modules = get_all_modules() response = requests.get(_ALL_MODULES_URL)
if not custom_modules: if response.status_code != 200:
manager_logger.warning(f"Не удалось получить информацию о кастомных модулях. Код: {response.status_code}")
return return
# получим переменные окружения # получим переменные окружения
@ -105,6 +100,7 @@ def stop_all_custom_containers():
# проходимся по всем модулям (id, title, is_SIZ, status, model) # проходимся по всем модулям (id, title, is_SIZ, status, model)
processed_modules = [] processed_modules = []
custom_modules = response.json()
for module in custom_modules: for module in custom_modules:
if module["status"] in ["работает"]: if module["status"] in ["работает"]:
# инициализируем переменные контейнера # инициализируем переменные контейнера
@ -112,7 +108,6 @@ def stop_all_custom_containers():
# останавливаем контейнер в отдельном процессе # останавливаем контейнер в отдельном процессе
p = Process(target=stop_container, p = Process(target=stop_container,
args=( args=(
module['id'],
container_name, container_name,
) )
) )

View file

@ -1,20 +1,10 @@
import requests
import docker import docker
import os
from ..logger import LoggerFactory from ..logger import LoggerFactory
_ALL_MODULES_URL = "https://api.statanly.com:8443/api/custom-modules"
manager_logger = LoggerFactory.get_logger("CustomModuleManager") manager_logger = LoggerFactory.get_logger("CustomModuleManager")
def change_module_status(
module_id: int,
status: str
):
_ = requests.post(
f"http://localhost:{int(os.environ.get('PORT', 5010))}/api/v1.0/interact_with_custom_modules",
data = {"request_type": "change_status", "model_id": module_id, "status": status}
)
def build_image( def build_image(
client: docker.DockerClient, client: docker.DockerClient,
path: str, path: str,
@ -35,7 +25,6 @@ def build_image(
manager_logger.info(chunk['stream'].strip()) manager_logger.info(chunk['stream'].strip())
def start_container( def start_container(
module_id: int,
image_name: str, image_name: str,
build_args: dict, build_args: dict,
container_name: str, container_name: str,
@ -50,11 +39,9 @@ def start_container(
# Соберем контейнер # Соберем контейнер
try: try:
change_module_status(module_id, status = "работает")
build_image(client, **build_args) build_image(client, **build_args)
manager_logger.info(f"Контейнер '{container_name}' успешно собран") manager_logger.info(f"Контейнер '{container_name}' успешно собран")
except Exception as e: except Exception as e:
change_module_status(module_id, status = "не создан")
manager_logger.error(f"Ошибка при сборке контейнера: {e}") manager_logger.error(f"Ошибка при сборке контейнера: {e}")
return return
@ -73,11 +60,9 @@ def start_container(
) )
manager_logger.info(f"Контейнер '{container_name}' с ID: {container.short_id} запустился") manager_logger.info(f"Контейнер '{container_name}' с ID: {container.short_id} запустился")
except Exception as e: except Exception as e:
change_module_status(module_id, status = "остановлен")
manager_logger.error(f"Ошибка при запуске контейнера: {e}") manager_logger.error(f"Ошибка при запуске контейнера: {e}")
def stop_container( def stop_container(
module_id: int,
name: str name: str
): ):
"""Удаление docker контейнеров по имени""" """Удаление docker контейнеров по имени"""
@ -90,6 +75,5 @@ def stop_container(
container.stop() container.stop()
container.remove() container.remove()
manager_logger.info(f"Контейнер '{name}' был остановлен") manager_logger.info(f"Контейнер '{name}' был остановлен")
change_module_status(module_id, status = "остановлен")
except docker.errors.NotFound: except docker.errors.NotFound:
manager_logger.warning(f"Контейнер '{name}' не найден") manager_logger.warning(f"Контейнер '{name}' не найден")