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'
ALTER TABLE containers
ADD COLUMN secret TEXT NOT NULL DEFAULT '';
ADD COLUMN config TEXT NOT NULL DEFAULT '';
EOF"

View File

@@ -17,17 +17,17 @@ export ODOO_DB_PASSWORD=$(echo "$SECRET" | jq -r '.psql')
echo "PASSWORD $ODOO_DB_PASSWORD"
echo "Restoring $FILENAME to $1"
echo "Restoring $FILENAME to $UUID"
echo "status of container"
doas docker ps -a --filter "id=$UUID"
echo "POSTGRES HOST: $POSTGRES_HOST"
BACKUP="/mnt/backup/$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"
elif doas docker exec "${1%}" /bin/bash -c "[ -f $TEMPLATE ]"; then
elif doas docker exec "$UUID" /bin/bash -c "[ -f $TEMPLATE ]"; then
FILENAME="$TEMPLATE"
else
echo "File not exists"
@@ -46,19 +46,19 @@ DROP DATABASE IF EXISTS \"$UUID\";
PGPASSWORD="$POSTGRES_ADMIN_PASSWORD" psql \
-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 \
-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 "${1%}" chown -R odoo:odoo /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 "$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
# ---------------------- 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 ----------------------
@app.get("/", include_in_schema=False)
def redirect_to_odoo():
@@ -116,20 +146,14 @@ def redirect_to_odoo():
@app.post("/container/update", dependencies=[Depends(verify_api_key)])
def update_container(request: ContainerModel):
env_str = json.dumps(request.env) if isinstance(request.env, dict) else request.env
secret_str = json.dumps(request.secret) if isinstance(request.secret, dict) else request.secret
# Convert dict fields to JSON strings
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)
if existing:
execute_db("""
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:
if not existing:
# If record does not exist, insert a new one with all given fields
execute_db("""
INSERT INTO containers (UUID, email, expires, tags, env, affiliate, image, history,
comment, domains, status, created, bump, secret)
@@ -139,7 +163,32 @@ def update_container(request: ContainerModel):
request.affiliate, request.image, request.history, request.comment,
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)])

View File

@@ -1,15 +1,48 @@
#!/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
# 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"
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
doas chmod 666 /BACKUP/$UUID/*
# 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
echo "Deleting old backup: $file"
rm -f "$file"
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 'CREATED=' || created 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';
")
# Debug: print loaded environment variables
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}"
export ODOO_DB_PASSWORD=$(echo "$SECRET" | jq -r '.psql')
echo "ENV: $HDD $DOMAIN_COUNT $BACKUP_SLOTS $CONTAINERDBID"
BASEURL="${BASEURL:-/4server/data/$UUID}"
DATA_DIR="$BASEURL/odoo/"
@@ -23,6 +25,7 @@ BACKUP_DIR="/BACKUP/$UUID"
GIT_DIR="$BASEURL/git-server/"
INSTALL_DIR="$BASEURL/install/"
SSH_DIR="$BASEURL/.ssh/"
ETC_DIR="$BASEURL/etc/"
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 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 rm "$UUID" 2>/dev/null
@@ -53,11 +58,17 @@ doas docker run -d --name "$UUID" \
-v "$GIT_DIR:/git-server" \
-v "$INSTALL_DIR:/mnt/install" \
-v "$SSH_DIR:/etc/sshkey" \
-v "$ETC_DIR:/mnt/etc" \
-p "$PORT:22" \
-e HOST="beedb" \
-e USER="$ODOO_DB_USER" \
-e PASSWORD="$ODOO_DB_PASSWORD" \
-e UUID="$UUID" \
-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 "traefic.http.routers.$UUID.entrypoints=web, websecure" \
@@ -67,4 +78,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/*
check_and_create_db

View File

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

View File

@@ -80,6 +80,10 @@ http:
address: http://bouncer-traefik:8080/api/v1/forwardAuth
trustForwardHeader: true
cors-headers:
headers:
accessControlAllowCredentials: true
routers:
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.