Compare commits
2 commits
9632552cff
...
86385261fe
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
86385261fe | ||
|
|
c1603b5e12 |
5 changed files with 108 additions and 29 deletions
13
master-node/docker-compose.yaml
Normal file
13
master-node/docker-compose.yaml
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
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
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
import os
|
||||
import requests
|
||||
import configparser
|
||||
import datetime
|
||||
|
||||
|
|
@ -77,6 +78,9 @@ app.config["SESSION_TYPE"] = "filesystem"
|
|||
@app.before_first_request
|
||||
def startup():
|
||||
# Приведем систему в начальное состояние
|
||||
# TODO: запуск плейбука, который проверит кодовую базу
|
||||
# желательно, чтобы он скопировал код и указал путь к корневой директории
|
||||
# в переменной окружения ML_PATH
|
||||
reset_to_initial_state()
|
||||
app_logger.info("master-node запущена!")
|
||||
|
||||
|
|
@ -111,6 +115,47 @@ def run_ansible():
|
|||
app_logger.error(data)
|
||||
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
|
||||
# --------------------------
|
||||
|
|
@ -125,14 +170,12 @@ def run_ansible():
|
|||
# AUTO.check_cluster_state()
|
||||
# app_logger.debug("Finished with auto cluster state")
|
||||
|
||||
#@scheduler.task(
|
||||
# "interval",
|
||||
# id="cluster_state",
|
||||
# seconds=30,
|
||||
# misfire_grace_time=900
|
||||
#)
|
||||
#def custom_modules():
|
||||
# create_custom_containers()
|
||||
scheduler.task(
|
||||
"interval",
|
||||
id="cluster_state",
|
||||
seconds=30,
|
||||
misfire_grace_time=900
|
||||
)(create_custom_containers)
|
||||
|
||||
if __name__ == "__main__":
|
||||
port = int(os.environ.get("PORT", 5010))
|
||||
|
|
|
|||
|
|
@ -16,8 +16,10 @@ def load_env_files(
|
|||
|
||||
def get_env_vars():
|
||||
# Проверяем наличие кодовой базы
|
||||
# TODO: ansible playbook
|
||||
ml_path = "/path-to-ml"
|
||||
try:
|
||||
ml_path = os.environ["ML_PATH"]
|
||||
except KeyError:
|
||||
raise RuntimeError("Не указан путь к кодовой базе мл модулей")
|
||||
|
||||
# Получаем переменные
|
||||
env_files = [f"{ml_path}/.env", f"{ml_path}/docker/.env.dev", f"{ml_path}/docker/.env.compose_vars"]
|
||||
|
|
|
|||
|
|
@ -1,21 +1,29 @@
|
|||
from multiprocessing import Process
|
||||
import os
|
||||
import requests
|
||||
|
||||
from .manager_methods import start_container, stop_container
|
||||
from .get_env_vars import get_env_vars
|
||||
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")
|
||||
|
||||
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():
|
||||
# получим информацию о кастомных модулей
|
||||
response = requests.get(_ALL_MODULES_URL)
|
||||
if response.status_code != 200:
|
||||
manager_logger.warning(f"Не удалось получить информацию о кастомных модулях. Код: {response.status_code}")
|
||||
return
|
||||
custom_modules = get_all_modules()
|
||||
if not custom_modules:
|
||||
return
|
||||
|
||||
# получим переменные окружения
|
||||
try:
|
||||
|
|
@ -26,13 +34,13 @@ def reset_to_initial_state():
|
|||
|
||||
# проходимся по всем модулям (id, title, is_SIZ, status, model)
|
||||
processed_modules = []
|
||||
custom_modules = response.json()
|
||||
for module in custom_modules:
|
||||
# инициализируем переменные контейнера
|
||||
container_name = f"{all_envs['COMPOSE_PROJECT_NAME']}_custom_module{module['id']}"
|
||||
# останавливаем контейнер в отдельном процессе
|
||||
p = Process(target=stop_container,
|
||||
args=(
|
||||
module['id'],
|
||||
container_name,
|
||||
)
|
||||
)
|
||||
|
|
@ -45,10 +53,9 @@ def reset_to_initial_state():
|
|||
|
||||
def create_custom_containers():
|
||||
# получим информацию о кастомных модулей
|
||||
response = requests.get(_ALL_MODULES_URL)
|
||||
if response.status_code != 200:
|
||||
manager_logger.warning(f"Не удалось получить информацию о кастомных модулях. Код: {response.status_code}")
|
||||
return
|
||||
custom_modules = get_all_modules()
|
||||
if not custom_modules:
|
||||
return
|
||||
|
||||
# получим переменные окружения
|
||||
try:
|
||||
|
|
@ -59,8 +66,6 @@ def create_custom_containers():
|
|||
|
||||
# проходимся по всем модулям (id, title, is_SIZ, status, model)
|
||||
processed_modules = []
|
||||
custom_modules = response.json()
|
||||
print(custom_modules)
|
||||
for module in custom_modules:
|
||||
if module["status"] in ["остановлен", "не создан"] and module["model"]["weights"].strip():
|
||||
# инициализируем переменные контейнера
|
||||
|
|
@ -70,6 +75,7 @@ def create_custom_containers():
|
|||
# запускаем контейнер в отдельном процессе
|
||||
p = Process(target=start_container,
|
||||
args=(
|
||||
module['id'],
|
||||
image_name,
|
||||
build_args,
|
||||
container_name,
|
||||
|
|
@ -86,10 +92,9 @@ def create_custom_containers():
|
|||
|
||||
def stop_all_custom_containers():
|
||||
# получим информацию о кастомных модулей
|
||||
response = requests.get(_ALL_MODULES_URL)
|
||||
if response.status_code != 200:
|
||||
manager_logger.warning(f"Не удалось получить информацию о кастомных модулях. Код: {response.status_code}")
|
||||
return
|
||||
custom_modules = get_all_modules()
|
||||
if not custom_modules:
|
||||
return
|
||||
|
||||
# получим переменные окружения
|
||||
try:
|
||||
|
|
@ -100,7 +105,6 @@ def stop_all_custom_containers():
|
|||
|
||||
# проходимся по всем модулям (id, title, is_SIZ, status, model)
|
||||
processed_modules = []
|
||||
custom_modules = response.json()
|
||||
for module in custom_modules:
|
||||
if module["status"] in ["работает"]:
|
||||
# инициализируем переменные контейнера
|
||||
|
|
@ -108,6 +112,7 @@ def stop_all_custom_containers():
|
|||
# останавливаем контейнер в отдельном процессе
|
||||
p = Process(target=stop_container,
|
||||
args=(
|
||||
module['id'],
|
||||
container_name,
|
||||
)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,20 @@
|
|||
import requests
|
||||
import docker
|
||||
import os
|
||||
|
||||
from ..logger import LoggerFactory
|
||||
|
||||
_ALL_MODULES_URL = "https://api.statanly.com:8443/api/custom-modules"
|
||||
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(
|
||||
client: docker.DockerClient,
|
||||
path: str,
|
||||
|
|
@ -25,6 +35,7 @@ def build_image(
|
|||
manager_logger.info(chunk['stream'].strip())
|
||||
|
||||
def start_container(
|
||||
module_id: int,
|
||||
image_name: str,
|
||||
build_args: dict,
|
||||
container_name: str,
|
||||
|
|
@ -39,9 +50,11 @@ def start_container(
|
|||
|
||||
# Соберем контейнер
|
||||
try:
|
||||
change_module_status(module_id, status = "работает")
|
||||
build_image(client, **build_args)
|
||||
manager_logger.info(f"Контейнер '{container_name}' успешно собран")
|
||||
except Exception as e:
|
||||
change_module_status(module_id, status = "не создан")
|
||||
manager_logger.error(f"Ошибка при сборке контейнера: {e}")
|
||||
return
|
||||
|
||||
|
|
@ -60,9 +73,11 @@ def start_container(
|
|||
)
|
||||
manager_logger.info(f"Контейнер '{container_name}' с ID: {container.short_id} запустился")
|
||||
except Exception as e:
|
||||
change_module_status(module_id, status = "остановлен")
|
||||
manager_logger.error(f"Ошибка при запуске контейнера: {e}")
|
||||
|
||||
def stop_container(
|
||||
module_id: int,
|
||||
name: str
|
||||
):
|
||||
"""Удаление docker контейнеров по имени"""
|
||||
|
|
@ -75,5 +90,6 @@ def stop_container(
|
|||
container.stop()
|
||||
container.remove()
|
||||
manager_logger.info(f"Контейнер '{name}' был остановлен")
|
||||
change_module_status(module_id, status = "остановлен")
|
||||
except docker.errors.NotFound:
|
||||
manager_logger.warning(f"Контейнер '{name}' не найден")
|
||||
Loading…
Reference in a new issue