Compare commits
No commits in common. "86385261fecf0d16cecd459dc93ece5e1931c366" and "9632552cffc5ac109028c65dd6bdcc7a8fe33a6f" have entirely different histories.
86385261fe
...
9632552cff
5 changed files with 29 additions and 108 deletions
|
|
@ -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
|
|
||||||
|
|
@ -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))
|
||||||
|
|
|
||||||
|
|
@ -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"]
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -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}' не найден")
|
||||||
Loading…
Reference in a new issue