diff --git a/alpine/config b/alpine/config index 550ae76..eebb0f3 100644 --- a/alpine/config +++ b/alpine/config @@ -24,3 +24,12 @@ Host mumbai User 4server IdentityFile /app/host_vars/mumbai/mumbai +Host meppel + Hostname 192.168.9.21 + User 4server + IdentityFile /app/host_vars/meppel/meppel + +Host saopaulo + Hostname 192.168.9.11 + User 4server + IdentityFile /app/host_vars/saopaulo/saopaulo diff --git a/alpine/known_hosts b/alpine/known_hosts index 2876357..8ed9072 100644 --- a/alpine/known_hosts +++ b/alpine/known_hosts @@ -8,3 +8,9 @@ 192.168.9.16 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCXNdN2lYWg9k3r5B9QISWCAWvAzzDj/aO5EeYPimDcz383Qliq0xW+FjJvgw2fY/Aoljwd6pGY3pJPN1aM3i4Qxt22S6emsFkGm89/GOdEu9ZkB+ln0fL8uPJTdjQklkhGb8YIF4aD8OMkMNXn7Ale+TiJJuWWmh7UAQITM5EqX1Wq+uAM/2ixpKo3dQU8L6pzeGi5yQUzHB3eyckSnFjCrSS/hW6lsKyhoaSYn+cAiuhbWEwP4lv9um6Cl2rLZYcysJTTs1DP7gJL3eyytnQ83R8MEX5/qY2zSVFCaNPguF7hlC7MgdR90naqlzm40XzYXHloDIg92+kGZGdR6jcKy7QasHuQLeXXJEk63jl64IJwRJPNnrVGszEDwIz0nBzVX/Yot2R/uAjhJRdR5d9tlZbMILkng6I/BVdJhqnJzuBottZpfu0qaBakIecDbLiJeU+AbAQffzWesyAmlHaLLLCHgwLdNaVjCltx6/RebF8HRRO82sdRE8Js6dSAXZ0= 192.168.9.16 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLpXVmQVbrhdfbrTHINQ2lZCxLxgrWbIDoNoxRR7EuqI5qNr2LQhqmTVZpNUIvj7PhdGPN4hry9jMfC39Dwa7Eo= +192.168.9.11 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFbAGYglyMYT/IfX9G4n9GhbPf+8T7TyVin/DfP3eKgb +192.168.9.11 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCthnkPJKC1Ij/Fc4fTRubcV8xDSKJ4UrlUYgZ+lO2AZYKhefVZOaDkizqWbjf9c4dqAAEX1lqgDwr3UwEw6hukLLhherCU6tn3Q/nmOQsbKrEGG+kJXnzCi1jYsH4UNQB8Xl18eaLhGZosqCfEVK3LHw2/nMsxLfbrw61qf9Z7/haQOJU2M2W9X3U/yEk4sOCoxguJIoNJ0JZB+X3xO2TXKLCKuaWpckbmHAVuL0c4u0ZfYqF3lCxWLj/iI5SKD/YqajohaVBaoJkmtIkLuuSSFe5gJb22htMgKXoQ0TcxxAvTnHwa92sVSMx7Lp1zQ5RGzN+Dw99FL4HyR4KDPlmVpGPZbNp0LnnggQ0SBmT6F3KarNZLzSW6w2foBkl9XjTEBUjb5cHXK8jq7nEUK26TgirngSAFg7y44NWta6whRX0+/wCanlvgQ1BNYGf4vcw5P+Q8MoGOdepF7b8gQiUn/KhtmnQem/Q1//xDt9MOJkmjBemG9KIso/gqtJkHeps= +192.168.9.11 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBDc6J024++J25z2ZMXQ3Vim+mLVIVs+cZngv8DmtEDfrT/Ptl7+F2IqXRNcZuq1YTjEZO8eQg27iIemPoPT3xa8= +192.168.9.21 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMFuf87ngDaF8D0kzVzzB953ji6ptg/V9t+WPac+DAjO +192.168.9.21 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDtexcutExMflSRPJOwGPuZx49c+ZUMoElNPNntXONOuVZ8jM+zzA/4s+HCj+RWdHMnarLcNJjwRZRq7JWruqmr1EN9eNmvu13cLCKZr6Ape1gt8VmMhvQ9nA7eMx3UdvnWgXjLCfJy+BKh2XVAneM5lOSPMcyQlcACrLQVkse9EKhxhV5nEjXKYxSNetIPK9PxglXznpC8IpuWlXnDH2R8vDhdvBmBFTKOjN5Wa+GrMfElWeQOjyCpNcMVYohvV87VN6FxHQTADFTm2CKy/W7pnM8rI55ZbBIMfvLyhpM+vtFh1sJlIZSFnn+ytMUImNEAgBDI3fCpwZ99zeLViGhQJlBkdCUI+JJK9XJjpcOMNydeWh142RGU6juPuSLOZPqKNc3BpZYgPY0vMDgDWgT9AcYup3rAJ/UnUnhsxiT2h/gx7+t/j9xg01BQF5S6mezaueuavHCh9MvAzXiJXR8zanhl/Hh9BKgIAFrZh71CzP/PYG33BKCe9DXA09aJrf8= +192.168.9.21 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBGlzLZWNjSaDuDd4e66LoBizY5j+QCsifIIxkvX4CrzP/AqAgWDEEgT+pAXBFkNJlBR6TDFJ0bIdwZTbcq8/72E= diff --git a/app/host_vars/hosts b/app/host_vars/hosts index 38f8e88..77c1a70 100644 --- a/app/host_vars/hosts +++ b/app/host_vars/hosts @@ -1 +1 @@ -dev +meppel diff --git a/app/sbin/ODOO_19/dbVersion b/app/sbin/ODOO_19/dbVersion new file mode 100755 index 0000000..ca12723 --- /dev/null +++ b/app/sbin/ODOO_19/dbVersion @@ -0,0 +1,47 @@ +#!/usr/bin/env python3 +import csv +import sys +import zipfile + +if len(sys.argv) < 2: + print("Usage: python3 check_odoo_version.py ") + sys.exit(1) + +zip_path = sys.argv[1] +base_version = None + +with zipfile.ZipFile(zip_path, 'r') as z: + # Assume there is only one .sql file in the zip + sql_files = [f for f in z.namelist() if f.endswith('.sql')] + if not sql_files: + print("No .sql file found in the zip.") + sys.exit(1) + + sql_file_name = sql_files[0] + + with z.open(sql_file_name, 'r') as f: + # Decode bytes to string + lines = (line.decode('utf-8') for line in f) + + # Skip lines until COPY command + for line in lines: + if line.startswith("COPY public.ir_module_module"): + break + + # Read the COPY data until the terminator '\.' + reader = csv.reader(lines, delimiter='\t', quotechar='"', escapechar='\\') + for row in reader: + if row == ['\\.']: # End of COPY + break + if len(row) < 12: + continue + module_name = row[7].strip() # 8th column = name + if module_name == "base": + base_version = row[11].strip() # 12th column = latest_version + break + +if base_version: + print(base_version.split(".")[0]) +else: + print("Base module not found in dump.") + diff --git a/app/sbin/ODOO_19/import b/app/sbin/ODOO_19/import new file mode 100644 index 0000000..27b9d3a --- /dev/null +++ b/app/sbin/ODOO_19/import @@ -0,0 +1,32 @@ +#!/bin/bash + +# Create the tmp directory if it doesn't exist +mkdir -p /4server/tmp/ + +# Save original stdout +exec 3>&1 + +# Redirect all other output to log +exec > /4server/data/log/importDb.log 2>&1 +echo "$(date '+%Y-%m-%d %H:%M') Import file $1" + +# Generate random 8-digit filename +RANDOM_FILE="/4server/tmp/$(printf "%08d" $((RANDOM % 100000000))).zip" + +# Download file from Google Drive using gdown +gdown "$1" -O "$RANDOM_FILE" + +# Execute dbVersion on the downloaded file and capture output +VERSION=$(/4server/sbin/ODOO_19/dbVersion "$RANDOM_FILE") + +# Output JSON to original stdout +cat <&3 +{ + "version":"$VERSION", + "file":"$RANDOM_FILE" +} +EOF + +# Close saved stdout +exec 3>&- + diff --git a/app/sbin/api b/app/sbin/api index a667768..8819f1b 100755 --- a/app/sbin/api +++ b/app/sbin/api @@ -24,7 +24,7 @@ from pathlib import Path DB_PATH = "/4server/data/contracts.db" BIN_PATH = "/4server/sbin" API_KEY = os.getenv("API_KEY", "your-secret-api-key") -VERSION = "API: 0.0.7" +VERSION = "API: 0.0.8" # ---------------------- FastAPI App ---------------------- app = FastAPI() @@ -124,6 +124,13 @@ class CommandRequest(BaseModel): uuid: str method: int +class ImportRequest(BaseModel): + filename: str + +class MoveRequest(BaseModel): + source: str + destination: str + # ---------------------- Routes ---------------------- @app.get("/", include_in_schema=False) @@ -362,6 +369,7 @@ async def get_odoo_log_summary(uuid: str): re.compile(r"ERROR"), # Errors re.compile(r"WARNING"), # Warnings re.compile(r"Traceback"), # Tracebacks + re.compile(r"Error"), ] def is_important_line(line: str) -> bool: @@ -396,6 +404,32 @@ async def get_odoo_log_summary(uuid: str): except Exception as e: raise HTTPException(status_code=500, detail=f"Error reading log files: {e}") +# ------------------------ BACKUP HANDLING ------------------------------------- +@app.post("/backup/import", dependencies=[Depends(verify_api_key)]) +def backup_import(request: ImportRequest): + if not request.filename: + raise HTTPException(status_code=400, detail="Filename is required") + + command = [f"{BIN_PATH}/ODOO_19/import", request.filename] + output = run_command(command) + return {"message": output} + +@app.post("/backup/move", dependencies=[Depends(verify_api_key)]) +def backup_move(request: MoveRequest): + if not request.source or not request.destination: + raise HTTPException(status_code=400, detail="Source and destination are required") + + if not os.path.exists(request.source): + raise HTTPException(status_code=404, detail="Source file does not exist") + + # Use shell command to move the file + command = ["mv", request.source, request.destination] # Linux/macOS + # For Windows, use: command = ["move", request.source, request.destination] + + output = run_command(command) + return {"message": f"Moved {request.source} to {request.destination}", "output": output} + + # ---------------------- Entry Point ---------------------- if __name__ == "__main__": print(VERSION) diff --git a/app/sbin/start/ODOO_17 b/app/sbin/start/ODOO_17 index a7ba6c1..6593ad9 100755 --- a/app/sbin/start/ODOO_17 +++ b/app/sbin/start/ODOO_17 @@ -58,24 +58,30 @@ RULE="${RULE# || }" DOMAIN_LABEL="traefik.http.routers.$UUID.rule=$RULE" echo "[DEBUG] Final Traefik label: $DOMAIN_LABEL" -doas docker exec "$UUID" mkdir -p /var/lib/odoo/.local/share/Odoo/ -doas docker exec "$UUID" ln -s /home/odoo/.local/share/Odoo/filestore /var/lib/odoo/.local/share/Odoo/filestore +docker exec "$UUID" mkdir -p /var/lib/odoo/.local/share/Odoo/ +docker exec "$UUID" ln -s /home/odoo/.local/share/Odoo/filestore /var/lib/odoo/.local/share/Odoo/filestore -doas find "$BASEURL" -type d -exec chmod 777 {} \; +find "$BASEURL" -type d -exec chmod 777 {} \; PORT=$((CONTAINERDBID + 2200)) echo "PORT $PORT" -chmod 777 $ETC_DIR -chmod 77 $ETC_DIR/gitpath -echo "git clone \"ssh://git@${UUID}.odoo4projects.com:${PORT}/git-server/repos/odoo.git\"" > ${ETC_DIR}/gitpath -echo "GIIIT $ETC_DIR $PORT" +mkdir -p ${ETC_DIR} +echo "GITPATH ${ETC_DIR}gitpath" +touch ${ETC_DIR}gitpath -doas docker stop "$UUID" 2>/dev/null -doas docker rm "$UUID" 2>/dev/null +mkdir -p ${GIT_DIR}keys +touch ${GIT_DIR}keys/id_rsa.pub + + +echo "git clone \"ssh://git@${UUID}.odoo4projects.com:${PORT}/git-server/repos/odoo.git\"" > "${ETC_DIR}/gitpath" + + +docker stop "$UUID" 2>/dev/null +docker rm "$UUID" 2>/dev/null EXTRA_DOCKER_PARAMETER="" -doas docker run -d --name "$UUID" \ +docker run -d --name "$UUID" \ --network 4server_4projects \ --restart=always \ $EXTRA_DOCKER_PARAMETER \ @@ -107,12 +113,15 @@ doas docker run -d --name "$UUID" \ --label "traefik.http.routers.$UUID.service=$UUID" \ docker.odoo4projects.com/4projects/odoo_17:$BRANCH -doas docker exec "$UUID" rm /var/lib/odoo/.local/share/Odoo/filestore -doas docker exec "$UUID" ln -s /home/odoo/.local/share/Odoo/filestore /var/lib/odoo/.local/share/Odoo/filestore +docker exec "$UUID" mkdir -p /var/lib/odoo/.local/share/Odoo +docker exec "$UUID" rm -rf /var/lib/odoo/.local/share/Odoo/filestore +docker exec "$UUID" ln -s /home/odoo/.local/share/Odoo/filestore /var/lib/odoo/.local/share/Odoo/filestore -doas docker exec $UUID chown -R odoo:odoo /home/odoo/.local -doas docker exec $UUID chown -R odoo:odoo /mnt/* -doas docker exec $UUID chown -R odoo:odoo /var/lib/odoo/.local/share/Odoo + +docker exec $UUID chown -R odoo:odoo /home/odoo/.local +docker exec $UUID chown -R odoo:odoo /var/lib/odoo/.local/share/Odoo +docker exec $UUID chown -R odoo:odoo /mnt/* +docker exec $UUID chown odoo:odoo /git-server/keys/id_rsa.pub check_and_create_db diff --git a/app/sbin/start/ODOO_18 b/app/sbin/start/ODOO_18 index 0f52a2d..ed6dc1e 100755 --- a/app/sbin/start/ODOO_18 +++ b/app/sbin/start/ODOO_18 @@ -58,24 +58,30 @@ RULE="${RULE# || }" DOMAIN_LABEL="traefik.http.routers.$UUID.rule=$RULE" echo "[DEBUG] Final Traefik label: $DOMAIN_LABEL" -doas docker exec "$UUID" mkdir -p /var/lib/odoo/.local/share/Odoo/ -doas docker exec "$UUID" ln -s /home/odoo/.local/share/Odoo/filestore /var/lib/odoo/.local/share/Odoo/filestore +docker exec "$UUID" mkdir -p /var/lib/odoo/.local/share/Odoo/ +docker exec "$UUID" ln -s /home/odoo/.local/share/Odoo/filestore /var/lib/odoo/.local/share/Odoo/filestore -doas find "$BASEURL" -type d -exec chmod 777 {} \; +find "$BASEURL" -type d -exec chmod 777 {} \; PORT=$((CONTAINERDBID + 2200)) echo "PORT $PORT" -chmod 777 $ETC_DIR -chmod 77 $ETC_DIR/gitpath -echo "git clone \"ssh://git@${UUID}.odoo4projects.com:${PORT}/git-server/repos/odoo.git\"" > ${ETC_DIR}/gitpath -echo "GIIIT $ETC_DIR $PORT" +mkdir -p ${ETC_DIR} +echo "GITPATH ${ETC_DIR}gitpath" +touch ${ETC_DIR}gitpath -doas docker stop "$UUID" 2>/dev/null -doas docker rm "$UUID" 2>/dev/null +mkdir -p ${GIT_DIR}keys +touch ${GIT_DIR}keys/id_rsa.pub + + +echo "git clone \"ssh://git@${UUID}.odoo4projects.com:${PORT}/git-server/repos/odoo.git\"" > "${ETC_DIR}/gitpath" + + +docker stop "$UUID" 2>/dev/null +docker rm "$UUID" 2>/dev/null EXTRA_DOCKER_PARAMETER="" -doas docker run -d --name "$UUID" \ +docker run -d --name "$UUID" \ --network 4server_4projects \ --restart=always \ $EXTRA_DOCKER_PARAMETER \ @@ -107,10 +113,15 @@ doas docker run -d --name "$UUID" \ --label "traefik.http.routers.$UUID.service=$UUID" \ docker.odoo4projects.com/4projects/odoo_18:$BRANCH +docker exec "$UUID" mkdir -p /var/lib/odoo/.local/share/Odoo +docker exec "$UUID" rm -rf /var/lib/odoo/.local/share/Odoo/filestore +docker exec "$UUID" ln -s /home/odoo/.local/share/Odoo/filestore /var/lib/odoo/.local/share/Odoo/filestore -doas docker exec $UUID chown -R odoo:odoo /home/odoo/.local -doas docker exec $UUID chown -R odoo:odoo /mnt/* +docker exec $UUID chown -R odoo:odoo /home/odoo/.local +docker exec $UUID chown -R odoo:odoo /var/lib/odoo/.local/share/Odoo +docker exec $UUID chown -R odoo:odoo /mnt/* +docker exec $UUID chown odoo:odoo /git-server/keys/id_rsa.pub check_and_create_db diff --git a/app/sbin/start/ODOO_19 b/app/sbin/start/ODOO_19 index 863fd88..3c2a5cf 100755 --- a/app/sbin/start/ODOO_19 +++ b/app/sbin/start/ODOO_19 @@ -60,22 +60,26 @@ echo "[DEBUG] Final Traefik label: $DOMAIN_LABEL" -doas find "$BASEURL" -type d -exec chmod 777 {} \; +find "$BASEURL" -type d -exec chmod 777 {} \; PORT=$((CONTAINERDBID + 2200)) echo "PORT $PORT" mkdir -p ${ETC_DIR} echo "GITPATH ${ETC_DIR}gitpath" touch ${ETC_DIR}gitpath +mkdir -p ${GIT_DIR}keys +touch ${GIT_DIR}keys/id_rsa.pub + + echo "git clone \"ssh://git@${UUID}.odoo4projects.com:${PORT}/git-server/repos/odoo.git\"" > "${ETC_DIR}/gitpath" -doas docker stop "$UUID" 2>/dev/null -doas docker rm "$UUID" 2>/dev/null +docker stop "$UUID" 2>/dev/null +docker rm "$UUID" 2>/dev/null EXTRA_DOCKER_PARAMETER="" -doas docker run -d --name "$UUID" \ +docker run -d --name "$UUID" \ --network 4server_4projects \ --restart=always \ $EXTRA_DOCKER_PARAMETER \ @@ -108,9 +112,9 @@ doas docker run -d --name "$UUID" \ docker.odoo4projects.com/4projects/odoo_19:$BRANCH -doas docker exec $UUID chown -R odoo:odoo /home/odoo/.local -doas docker exec $UUID chown -R odoo:odoo /mnt/* - - +docker exec $UUID chown -R odoo:odoo /home/odoo/.local +docker exec $UUID chown -R odoo:odoo /mnt/* +docker exec $UUID chown odoo:odoo /git-server/keys/id_rsa.pub +chmod 777 /4server/data/$UUID/cc check_and_create_db diff --git a/app/sbin/start/n8n b/app/sbin/start/n8n index ce92995..0141719 100755 --- a/app/sbin/start/n8n +++ b/app/sbin/start/n8n @@ -7,10 +7,11 @@ HOSTNAME=$(hostname) mkdir -p /4server/data/${UUID}/n8n mkdir -p /4server/data/${UUID}/data +mkdir -p /4server/data/${UUID}/backup chmod 777 /4server/data/${UUID}/n8n chmod 777 /4server/data/${UUID}/data - +chmod 777 /4server/data/${UUID}/backup # Stop the container if it exists if docker ps -a --format '{{.Names}}' | grep -q "^${UUID}$"; then @@ -35,6 +36,7 @@ docker run -d \ -e GENERIC_TIMEZONE="UTC-3" \ -e N8N_CUSTOM_EXTENSIONS="/usr/local/share/n8n/custom" \ -v "/4server/data/${UUID}/n8n:/home/node/.n8n" \ + -v "/4server/data/${UUID}/backup:/data" \ -v "/4server/data/${UUID}/backup:/backup" \ --label "traefik.enable=true" \ --label "traefik.http.routers.${UUID}.rule=Host(\`${UUID}.odoo4projects.com\`)" \ diff --git a/app/update b/app/update index 839f2fc..220393c 100755 --- a/app/update +++ b/app/update @@ -27,7 +27,7 @@ template templates/repositories /etc/apk/repositories rex "doas apk update && doas apk upgrade" rex doas apk add iperf linux-lts openssh ufw python3 build-base python3-dev linux-headers py3-pip gcc g++ musl-dev libffi-dev make jq rsync mc vim docker docker-compose htop linux-lts sqlite bash postgresql16-client -rex doas pip install --root-user-action ignore --break-system-packages --no-cache-dir "uvicorn[standard]" fastapi pydantic psutil +rex doas pip install --root-user-action ignore --break-system-packages --no-cache-dir "uvicorn[standard]" fastapi pydantic psutil gdown ### own bins echo "Running prsync ./sbin" diff --git a/app/vault/host_vars.img b/app/vault/host_vars.img index 3761672..e9b9937 100644 Binary files a/app/vault/host_vars.img and b/app/vault/host_vars.img differ