fixes backup slots

This commit is contained in:
Oliver
2025-09-30 16:22:45 -03:00
parent bb271b8d71
commit dde5ec0eab
11 changed files with 164 additions and 39 deletions

View File

@@ -4,5 +4,5 @@
rex "doas sqlite3 /4server/data/contracts.db <<'EOF' rex "doas sqlite3 /4server/data/contracts.db <<'EOF'
ALTER TABLE containers ALTER TABLE containers
ADD COLUMN secret TEXT NOT NULL DEFAULT ''; ADD COLUMN config TEXT NOT NULL DEFAULT '';
EOF" EOF"

View File

@@ -17,17 +17,17 @@ export ODOO_DB_PASSWORD=$(echo "$SECRET" | jq -r '.psql')
echo "PASSWORD $ODOO_DB_PASSWORD" echo "PASSWORD $ODOO_DB_PASSWORD"
echo "Restoring $FILENAME to $1" echo "Restoring $FILENAME to $UUID"
echo "status of container" echo "status of container"
doas docker ps -a --filter "id=$UUID" doas docker ps -a --filter "id=$UUID"
echo "POSTGRES HOST: $POSTGRES_HOST" echo "POSTGRES HOST: $POSTGRES_HOST"
BACKUP="/mnt/backup/$2" BACKUP="/mnt/backup/$2"
TEMPLATE="/mnt/db_images/$2" TEMPLATE="/mnt/db_images/$2"
doas docker exec "${1%}" /bin/bash -c "[ -f $TEMPLATE ]" doas docker exec "$UUID" /bin/bash -c "[ -f $TEMPLATE ]"
if doas docker exec "${1%}" /bin/bash -c "[ -f $BACKUP ]"; then if doas docker exec "$UUID" /bin/bash -c "[ -f $BACKUP ]"; then
FILENAME="$BACKUP" FILENAME="$BACKUP"
elif doas docker exec "${1%}" /bin/bash -c "[ -f $TEMPLATE ]"; then elif doas docker exec "$UUID" /bin/bash -c "[ -f $TEMPLATE ]"; then
FILENAME="$TEMPLATE" FILENAME="$TEMPLATE"
else else
echo "File not exists" echo "File not exists"
@@ -46,19 +46,19 @@ DROP DATABASE IF EXISTS \"$UUID\";
PGPASSWORD="$POSTGRES_ADMIN_PASSWORD" psql \ PGPASSWORD="$POSTGRES_ADMIN_PASSWORD" psql \
-h "$POSTGRES_HOST" -U "$POSTGRES_ADMIN_USER" -p "$POSTGRES_PORT" -d postgres \ -h "$POSTGRES_HOST" -U "$POSTGRES_ADMIN_USER" -p "$POSTGRES_PORT" -d postgres \
-c "ALTER ROLE \"$1\" CREATEDB;" -c "ALTER ROLE \"$UUID\" CREATEDB;"
doas docker exec "${1%}" rm -rf /home/odoo/.local/share/Odoo/filestore doas docker exec "$UUID" rm -rf /home/odoo/.local/share/Odoo/filestore
doas docker exec "${1%}" odoo db --db_host beedb -w "$ODOO_DB_PASSWORD" -r "$1" load "$1" $FILENAME -f doas docker exec "$UUID" odoo db --db_host beedb -w "$ODOO_DB_PASSWORD" -r "$UUID" load "$UUID" $FILENAME -f
PGPASSWORD="$POSTGRES_ADMIN_PASSWORD" psql \ PGPASSWORD="$POSTGRES_ADMIN_PASSWORD" psql \
-h "$POSTGRES_HOST" -U "$POSTGRES_ADMIN_USER" -p "$POSTGRES_PORT" -d postgres \ -h "$POSTGRES_HOST" -U "$POSTGRES_ADMIN_USER" -p "$POSTGRES_PORT" -d postgres \
-c "ALTER ROLE \"$1\" NOCREATEDB;" -c "ALTER ROLE \"$UUID\" NOCREATEDB;"
doas docker exec "${1%}" cp -r /root/.local/share/Odoo/filestore /home/odoo/.local/share/Odoo/filestore doas docker exec "$UUID" cp -r /root/.local/share/Odoo/filestore /home/odoo/.local/share/Odoo/filestore
doas docker exec "${1%}" chown -R odoo:odoo /home/odoo/.local/share/Odoo/filestore doas docker exec "$UUID" chown -R odoo:odoo /home/odoo/.local
docker restart "${1%}" docker restart "$UUID"

View File

@@ -108,6 +108,36 @@ class UUIDRequest(BaseModel):
UUID: str UUID: str
# ---------------------- Routes ----------------------
@app.get("/", include_in_schema=False)
def redirect_to_odoo():
return RedirectResponse(url="https://ODOO4PROJECTS.com")
from fastapi import FastAPI, Depends
from fastapi.responses import RedirectResponse
from pydantic import BaseModel
from typing import Optional, Dict, Any
import json
app = FastAPI()
# ---------------------- Models ----------------------
class ContainerModel(BaseModel):
UUID: str
email: Optional[str] = None
expires: Optional[str] = None
tags: Optional[str] = None
env: Optional[Dict[str, Any]] = None
affiliate: Optional[str] = None
image: Optional[str] = None
history: Optional[str] = None
comment: Optional[str] = None
domains: Optional[str] = None
status: Optional[str] = None
created: Optional[str] = None
bump: Optional[str] = None
secret: Optional[Dict[str, Any]] = None
# ---------------------- Routes ---------------------- # ---------------------- Routes ----------------------
@app.get("/", include_in_schema=False) @app.get("/", include_in_schema=False)
def redirect_to_odoo(): def redirect_to_odoo():
@@ -116,20 +146,14 @@ def redirect_to_odoo():
@app.post("/container/update", dependencies=[Depends(verify_api_key)]) @app.post("/container/update", dependencies=[Depends(verify_api_key)])
def update_container(request: ContainerModel): def update_container(request: ContainerModel):
env_str = json.dumps(request.env) if isinstance(request.env, dict) else request.env # Convert dict fields to JSON strings
secret_str = json.dumps(request.secret) if isinstance(request.secret, dict) else request.secret env_str = json.dumps(request.env) if isinstance(request.env, dict) else None
secret_str = json.dumps(request.secret) if isinstance(request.secret, dict) else None
# Fetch existing record
existing = execute_db("SELECT * FROM containers WHERE UUID = ?", (request.UUID,), fetch=True) existing = execute_db("SELECT * FROM containers WHERE UUID = ?", (request.UUID,), fetch=True)
if existing: if not existing:
execute_db(""" # If record does not exist, insert a new one with all given fields
UPDATE containers SET email=?, expires=?, tags=?, env=?, affiliate=?, image=?,
history=?, comment=?, domains=?, status=?, created=?, bump=?, secret=?
WHERE UUID=?
""", (
request.email, request.expires, request.tags, env_str, request.affiliate,
request.image, request.history, request.comment, request.domains, request.status,
request.created, request.bump, secret_str, request.UUID
))
else:
execute_db(""" execute_db("""
INSERT INTO containers (UUID, email, expires, tags, env, affiliate, image, history, INSERT INTO containers (UUID, email, expires, tags, env, affiliate, image, history,
comment, domains, status, created, bump, secret) comment, domains, status, created, bump, secret)
@@ -139,7 +163,32 @@ def update_container(request: ContainerModel):
request.affiliate, request.image, request.history, request.comment, request.affiliate, request.image, request.history, request.comment,
request.domains, request.status, request.created, request.bump, secret_str request.domains, request.status, request.created, request.bump, secret_str
)) ))
return {"message": "Container updated or created"} return {"UUID": request.UUID, "status": "created"}
# Existing record found, do partial update
existing = existing[0] # Assuming fetch returns list of dicts
updates = {}
params = []
# Only add fields that are not None in the request
for field in ContainerModel.__fields__:
if field == "UUID":
continue
value = getattr(request, field)
if value is not None:
if field in ["env", "secret"]:
value = json.dumps(value)
updates[field] = value
params.append(value)
if updates:
# Build SQL dynamically
set_clause = ", ".join(f"{k}=?" for k in updates.keys())
params.append(request.UUID) # UUID for WHERE clause
execute_db(f"UPDATE containers SET {set_clause} WHERE UUID=?", tuple(params))
return {"UUID": request.UUID, "status": "updated", "fields_updated": list(updates.keys())}
return {"UUID": request.UUID, "status": "no_change"}
@app.post("/container/start", dependencies=[Depends(verify_api_key)]) @app.post("/container/start", dependencies=[Depends(verify_api_key)])

View File

@@ -1,15 +1,48 @@
#!/bin/bash #!/bin/bash
# Backup Odoo database script
# Author: Your Name
# Description: Dumps Odoo DB, manages backups, and sets permissions
set -euo pipefail # Fail on error, undefined variables, and pipe errors
# Load helper functions
source /4server/sbin/helpers source /4server/sbin/helpers
# Get contract info
get_contract_info get_contract_info
export ODOO_DB_PASSWORD=$(echo "$SECRET" | jq -r '.psql')
echo "PASSWORD $ODOO_DB_PASSWORD UUID $UUID" # Export Odoo database password
export ODOO_DB_PASSWORD
ODOO_DB_PASSWORD=$(echo "$SECRET" | jq -r '.psql')
# Display basic info
echo "UUID: $UUID"
echo "Backup slots: $BACKUP_SLOTS"
# Create backup filename
FILENAME="$(date +"%Y%m%d_%H%M").zip"
BACKUP_DIR="/BACKUP/$UUID"
# Ensure backup directory exists
mkdir -p "$BACKUP_DIR"
# Perform database dump using docker
doas docker exec "$UUID" odoo db \
--db_host beedb \
-r "$UUID" \
-w "$ODOO_DB_PASSWORD" \
--data-dir /home/odoo/.local/share/Odoo/ \
dump "$UUID" "/mnt/backup/$FILENAME"
# Set permissions for backup files
doas chmod 600 "$BACKUP_DIR"/*
doas docker exec "$UUID" chown odoo:odoo -R /mnt/backup
FILENAME=$(date +"%Y%m%d_%H:%M")".zip" # Remove old backups beyond the configured slots
ls -t "$BACKUP_DIR"/[0-9]*.zip 2>/dev/null | tail -n +$((BACKUP_SLOTS + 1)) | while read -r file; do
doas docker exec "$UUID" odoo db --db_host beedb -r "$UUID" -w "$ODOO_DB_PASSWORD" --data-dir /home/odoo/.local/share/Odoo/ dump "$UUID" /mnt/backup/$FILENAME echo "Deleting old backup: $file"
rm -f "$file"
doas chmod 666 /BACKUP/$UUID/* done

14
app/sbin/contractInfo Executable file
View File

@@ -0,0 +1,14 @@
export PATH=/4PROJECTS/bin:$PATH
if [ ! -n "$1" ]; then
echo "Missing Parameters <UUID>"
exit 0
fi
UUID=$1
echo "UUID: $UUID"
source /4server/sbin/helpers
get_contract_info
env

View File

@@ -31,12 +31,13 @@ done < <(sqlite3 "$DB_PATH" "
UNION ALL SELECT 'STATUS=' || status FROM containers WHERE UUID='$UUID' UNION ALL SELECT 'STATUS=' || status FROM containers WHERE UUID='$UUID'
UNION ALL SELECT 'CREATED=' || created FROM containers WHERE UUID='$UUID' UNION ALL SELECT 'CREATED=' || created FROM containers WHERE UUID='$UUID'
UNION ALL SELECT 'SECRET=' || secret FROM containers WHERE UUID='$UUID' UNION ALL SELECT 'SECRET=' || secret FROM containers WHERE UUID='$UUID'
UNION ALL SELECT 'CONTAINERDBID=' || id FROM containers WHERE UUID='$UUID'
UNION ALL SELECT 'BUMP=' || bump FROM containers WHERE UUID='$UUID'; UNION ALL SELECT 'BUMP=' || bump FROM containers WHERE UUID='$UUID';
") ")
# Debug: print loaded environment variables # Debug: print loaded environment variables
env | grep -E 'UUID|EMAIL|EXPIRES|TAGS|ENV|AFFILIATE|IMAGE|HISTORY|COMMENT|DOMAINS|STATUS|CREATED|BUMP|SECRET' env | grep -E 'UUID|EMAIL|EXPIRES|TAGS|ENV|AFFILIATE|IMAGE|HISTORY|COMMENT|DOMAINS|STATUS|CREATED|BUMP|SECRET'
eval $(echo "$ENV" | jq -r 'to_entries | .[] | "export \(.key | ascii_upcase)=\(.value)"')
eval $(echo "$ENV" | jq -r 'to_entries | .[] | "export \(.key)=\(.value)"')
} }

View File

@@ -11,6 +11,8 @@ BRANCH="${BRANCH:-release}"
ODOO_DB_USER="${UUID}" ODOO_DB_USER="${UUID}"
export ODOO_DB_PASSWORD=$(echo "$SECRET" | jq -r '.psql') export ODOO_DB_PASSWORD=$(echo "$SECRET" | jq -r '.psql')
echo "ENV: $HDD $DOMAIN_COUNT $BACKUP_SLOTS $CONTAINERDBID"
BASEURL="${BASEURL:-/4server/data/$UUID}" BASEURL="${BASEURL:-/4server/data/$UUID}"
DATA_DIR="$BASEURL/odoo/" DATA_DIR="$BASEURL/odoo/"
@@ -23,6 +25,7 @@ BACKUP_DIR="/BACKUP/$UUID"
GIT_DIR="$BASEURL/git-server/" GIT_DIR="$BASEURL/git-server/"
INSTALL_DIR="$BASEURL/install/" INSTALL_DIR="$BASEURL/install/"
SSH_DIR="$BASEURL/.ssh/" SSH_DIR="$BASEURL/.ssh/"
ETC_DIR="$BASEURL/etc/"
SERVER_IP=$(ip -4 addr show eth0 | awk '/inet/ {print $2}' | cut -d/ -f1) SERVER_IP=$(ip -4 addr show eth0 | awk '/inet/ {print $2}' | cut -d/ -f1)
@@ -31,9 +34,11 @@ DOMAIN_LABEL="traefik.http.routers.$UUID.rule=Host(\`$UUID.odoo4projects.com\`)"
doas find "$BASEURL" -type d -exec chmod 777 {} \; doas find "$BASEURL" -type d -exec chmod 777 {} \;
doas chmod 777 $BACKUP_DIR
PORT=$((RANDOM%1000+2200)) PORT=$($CONTAINERDBID+2200)
echo "PORT $PORT"
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 stop "$UUID" 2>/dev/null
doas docker rm "$UUID" 2>/dev/null doas docker rm "$UUID" 2>/dev/null
@@ -53,12 +58,18 @@ doas docker run -d --name "$UUID" \
-v "$GIT_DIR:/git-server" \ -v "$GIT_DIR:/git-server" \
-v "$INSTALL_DIR:/mnt/install" \ -v "$INSTALL_DIR:/mnt/install" \
-v "$SSH_DIR:/etc/sshkey" \ -v "$SSH_DIR:/etc/sshkey" \
-v "$ETC_DIR:/mnt/etc" \
-p "$PORT:22" \ -p "$PORT:22" \
-e HOST="beedb" \ -e HOST="beedb" \
-e USER="$ODOO_DB_USER" \ -e USER="$ODOO_DB_USER" \
-e PASSWORD="$ODOO_DB_PASSWORD" \ -e PASSWORD="$ODOO_DB_PASSWORD" \
-e UUID="$UUID" \ -e UUID="$UUID" \
--label "$DOMAIN_LABEL" \ -e HDD="$HDD" \
-e DOMAIN_COUNT="$DOMAIN_COUNT" \
-e BACKUP_SLOTS="$BACKUP_SLOTS" \
-e WORKER="$WORKER" \
-e GIT="$GIT" \
--label "$DOMAIN_LABEL" \
--label "traefik.http.services.$UUID.loadbalancer.server.port=8069" \ --label "traefik.http.services.$UUID.loadbalancer.server.port=8069" \
--label "traefic.http.routers.$UUID.entrypoints=web, websecure" \ --label "traefic.http.routers.$UUID.entrypoints=web, websecure" \
--label "traefik.http.routers.$UUID.tls.certresolver=production" \ --label "traefik.http.routers.$UUID.tls.certresolver=production" \
@@ -67,4 +78,9 @@ doas docker run -d --name "$UUID" \
docker.odoo4projects.com/4projects/odoo_19:$BRANCH 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/*
check_and_create_db check_and_create_db

View File

@@ -1,6 +1,5 @@
#!/usr/bin/env bash #!/usr/bin/env bash
#--label "traefik.http.routers.${UUID}.middlewares=cors-headers@file" \
echo "Start N8N container ${UUID}" echo "Start N8N container ${UUID}"
# Get the hostname of the machine # Get the hostname of the machine

View File

@@ -80,6 +80,10 @@ http:
address: http://bouncer-traefik:8080/api/v1/forwardAuth address: http://bouncer-traefik:8080/api/v1/forwardAuth
trustForwardHeader: true trustForwardHeader: true
cors-headers:
headers:
accessControlAllowCredentials: true
routers: routers:
api-router: api-router:

9
app/update_sbin Executable file
View File

@@ -0,0 +1,9 @@
#!/bin/bash
echo "Running prsync ./sbin"
prsync -h "/app/host_vars/hosts" -avz ./sbin/ /4server/sbin/
rex doas rc-service api restart
rex doas rc-service checkCalls restart

Binary file not shown.