From 1a6faaa104645f9bd101c300e320525b7b78009c Mon Sep 17 00:00:00 2001 From: olaf Date: Wed, 16 Jul 2025 08:50:42 +0000 Subject: [PATCH] separation of production and development environments Adding new migrations for renaming and adding fields to the database schema persistent uuid for simclient --- docker-compose.yml | 4 +- models/models.py | 2 + ...3e2d_rename_location_to_description_in_.py | 36 ++++++++++++++++++ ...9ef909689_add_location_to_client_groups.py | 32 ++++++++++++++++ server/init_db.py | 38 ++++++++++++++----- simclient/requirements.txt | 1 + simclient/simclient.py | 15 +++++++- 7 files changed, 116 insertions(+), 12 deletions(-) create mode 100644 server/alembic/versions/0c47280d3e2d_rename_location_to_description_in_.py create mode 100644 server/alembic/versions/3a09ef909689_add_location_to_client_groups.py diff --git a/docker-compose.yml b/docker-compose.yml index 616d1df..9e398bd 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -23,7 +23,7 @@ services: networks: - infoscreen-net proxy: - image: nginx:1.27 + image: nginx:stable container_name: infoscreen-proxy ports: - "80:80" @@ -38,7 +38,7 @@ services: - infoscreen-net db: - image: mariadb:11.4.7 + image: mariadb:lts container_name: infoscreen-db restart: unless-stopped environment: diff --git a/models/models.py b/models/models.py index 98dc611..0c030e6 100644 --- a/models/models.py +++ b/models/models.py @@ -30,6 +30,7 @@ class ClientGroup(Base): __tablename__ = 'client_groups' id = Column(Integer, primary_key=True, autoincrement=True) name = Column(String(100), unique=True, nullable=False) + description = Column(String(255), nullable=True) # Manuell zu setzen created_at = Column(TIMESTAMP(timezone=True), server_default=func.current_timestamp()) is_active = Column(Boolean, default=True, nullable=False) @@ -46,6 +47,7 @@ class Client(Base): software_version = Column(String(100), nullable=True) macs = Column(String(255), nullable=True) model = Column(String(100), nullable=True) + description = Column(String(255), nullable=True) # Manuell zu setzen registration_time = Column(TIMESTAMP( timezone=True), server_default=func.current_timestamp(), nullable=False) last_alive = Column(TIMESTAMP(timezone=True), server_default=func.current_timestamp( diff --git a/server/alembic/versions/0c47280d3e2d_rename_location_to_description_in_.py b/server/alembic/versions/0c47280d3e2d_rename_location_to_description_in_.py new file mode 100644 index 0000000..0541ee0 --- /dev/null +++ b/server/alembic/versions/0c47280d3e2d_rename_location_to_description_in_.py @@ -0,0 +1,36 @@ +"""Rename location to description in client_groups, add description to clients + +Revision ID: 0c47280d3e2d +Revises: 3a09ef909689 +Create Date: 2025-07-16 08:47:00.355445 + +""" +from typing import Sequence, Union + +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects import mysql + +# revision identifiers, used by Alembic. +revision: str = '0c47280d3e2d' +down_revision: Union[str, None] = '3a09ef909689' +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade() -> None: + """Upgrade schema.""" + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('client_groups', sa.Column('description', sa.String(length=255), nullable=True)) + op.drop_column('client_groups', 'location') + op.add_column('clients', sa.Column('description', sa.String(length=255), nullable=True)) + # ### end Alembic commands ### + + +def downgrade() -> None: + """Downgrade schema.""" + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column('clients', 'description') + op.add_column('client_groups', sa.Column('location', mysql.VARCHAR(length=100), nullable=True)) + op.drop_column('client_groups', 'description') + # ### end Alembic commands ### diff --git a/server/alembic/versions/3a09ef909689_add_location_to_client_groups.py b/server/alembic/versions/3a09ef909689_add_location_to_client_groups.py new file mode 100644 index 0000000..5dcec5c --- /dev/null +++ b/server/alembic/versions/3a09ef909689_add_location_to_client_groups.py @@ -0,0 +1,32 @@ +"""Add location to client_groups + +Revision ID: 3a09ef909689 +Revises: 207f5b190f93 +Create Date: 2025-07-16 08:36:08.535836 + +""" +from typing import Sequence, Union + +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision: str = '3a09ef909689' +down_revision: Union[str, None] = '207f5b190f93' +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade() -> None: + """Upgrade schema.""" + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('client_groups', sa.Column('location', sa.String(length=100), nullable=True)) + # ### end Alembic commands ### + + +def downgrade() -> None: + """Downgrade schema.""" + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column('client_groups', 'location') + # ### end Alembic commands ### diff --git a/server/init_db.py b/server/init_db.py index 51d8832..ab971a8 100644 --- a/server/init_db.py +++ b/server/init_db.py @@ -1,11 +1,11 @@ +import bcrypt +from dotenv import load_dotenv +import os +from models.models import Base, User, UserRole, ClientGroup +from sqlalchemy.orm import sessionmaker +from sqlalchemy import create_engine, text import sys sys.path.insert(0, '/workspace') -from sqlalchemy import create_engine, text -from sqlalchemy.orm import sessionmaker -from models.models import Base, User, UserRole -import os -from dotenv import load_dotenv -import bcrypt # .env laden load_dotenv() @@ -24,7 +24,8 @@ admin_conn_str = f"mysql+pymysql://{DB_USER}:{DB_PASSWORD}@{DB_HOST}/" admin_engine = create_engine(admin_conn_str, echo=True) with admin_engine.connect() as conn: - conn.execute(text(f"CREATE DATABASE IF NOT EXISTS {DB_NAME} CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;")) + conn.execute(text( + f"CREATE DATABASE IF NOT EXISTS {DB_NAME} CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;")) # Jetzt mit Datenbank verbinden db_conn_str = f"mysql+pymysql://{DB_USER}:{DB_PASSWORD}@{DB_HOST}/{DB_NAME}" @@ -33,16 +34,35 @@ engine = create_engine(db_conn_str, echo=True) # Tabellen anlegen # Base.metadata.create_all(engine) # wird von alembic verwaltet + # Session erstellen Session = sessionmaker(bind=engine) session = Session() +# Default-ClientGroup anlegen, falls nicht vorhanden +DEFAULT_GROUP_ID = 1 +DEFAULT_GROUP_NAME = "Nicht zugeordnet" +existing_group = session.query(ClientGroup).filter_by( + id=DEFAULT_GROUP_ID).first() +if not existing_group: + default_group = ClientGroup( + id=DEFAULT_GROUP_ID, name=DEFAULT_GROUP_NAME, is_active=True) + session.add(default_group) + session.commit() + print( + f"Default-ClientGroup '{DEFAULT_GROUP_NAME}' mit id={DEFAULT_GROUP_ID} wurde angelegt.") +else: + print( + f"Default-ClientGroup '{DEFAULT_GROUP_NAME}' mit id={DEFAULT_GROUP_ID} existiert bereits.") + # Prüfen, ob der User bereits existiert -existing_user = session.query(User).filter_by(username=DEFAULT_ADMIN_USERNAME).first() +existing_user = session.query(User).filter_by( + username=DEFAULT_ADMIN_USERNAME).first() if not existing_user: # Passwort hashen - hashed_pw = bcrypt.hashpw(DEFAULT_ADMIN_PASSWORD.encode('utf-8'), bcrypt.gensalt()) + hashed_pw = bcrypt.hashpw( + DEFAULT_ADMIN_PASSWORD.encode('utf-8'), bcrypt.gensalt()) # Neuen User anlegen admin_user = User( diff --git a/simclient/requirements.txt b/simclient/requirements.txt index 8579e8b..3eca880 100644 --- a/simclient/requirements.txt +++ b/simclient/requirements.txt @@ -1 +1,2 @@ paho-mqtt +dotenv diff --git a/simclient/simclient.py b/simclient/simclient.py index a2e16d2..a82fe6d 100644 --- a/simclient/simclient.py +++ b/simclient/simclient.py @@ -142,9 +142,22 @@ def send_discovery(client, client_id, hardware_token, ip_addr): logging.info(f"Discovery-Nachricht gesendet: {discovery_msg}") +def get_persistent_uuid(uuid_path="/data/client_uuid.txt"): + # Prüfe, ob die Datei existiert + if os.path.exists(uuid_path): + with open(uuid_path, "r") as f: + return f.read().strip() + # Generiere neue UUID und speichere sie + new_uuid = str(uuid.uuid4()) + os.makedirs(os.path.dirname(uuid_path), exist_ok=True) + with open(uuid_path, "w") as f: + f.write(new_uuid) + return new_uuid + + def main(): global discovered - client_id = str(uuid.uuid4()) + client_id = get_persistent_uuid() hardware_token = get_hardware_token() ip_addr = get_ip() client = mqtt.Client(protocol=mqtt.MQTTv311, callback_api_version=2)