working
This commit is contained in:
@@ -5,6 +5,8 @@ if [ "$#" -ne 2 ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
host_vars_dir="/app/host_vars"
|
||||
|
||||
keys=(NEBULA_CA API_KEY HOSTNAME NEBULA_CRT NEBULA_KEY SSH_PRIVATE SSH_PUBLIC)
|
||||
|
||||
NEBULA_CA=$(<"$host_vars_dir/ca.crt")
|
||||
@@ -14,8 +16,6 @@ remotefile="$2"
|
||||
remotetmp_base="/var/tmp/4server"
|
||||
|
||||
while read -r host; do
|
||||
echo "Processing host: $host"
|
||||
|
||||
host_env_file="$host_vars_dir/$host/$host.env"
|
||||
|
||||
if [ ! -f "$host_env_file" ]; then
|
||||
|
||||
@@ -3,5 +3,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
rex "doas sqlite3 /4server/data/contracts.db <<'EOF'
|
||||
ALTER TABLE containers RENAME COLUMN secrets TO secret;
|
||||
ALTER TABLE containers
|
||||
ADD COLUMN secret TEXT NOT NULL DEFAULT '';
|
||||
EOF"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
|
||||
dump_config (){
|
||||
echo "========== Odoo Container Configuration =========="
|
||||
echo "UUID: $UUID"
|
||||
|
||||
@@ -6,16 +6,23 @@ if [ ! -n "$2" ]; then
|
||||
fi
|
||||
|
||||
UUID=$1
|
||||
echo "UUID: $UUID"
|
||||
|
||||
source /4server/sbin/helpers
|
||||
|
||||
get_contract_info
|
||||
|
||||
|
||||
export ODOO_DB_PASSWORD=$(echo "$SECRET" | jq -r '.psql')
|
||||
|
||||
echo "PASSWORD $ODOO_DB_PASSWORD"
|
||||
|
||||
echo "Restoring $FILENAME to $1"
|
||||
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"
|
||||
echo "TEMPLATE"
|
||||
doas docker exec "${1%}" /bin/bash -c "[ -f $TEMPLATE ]"
|
||||
|
||||
if doas docker exec "${1%}" /bin/bash -c "[ -f $BACKUP ]"; then
|
||||
@@ -28,32 +35,30 @@ else
|
||||
fi
|
||||
|
||||
|
||||
### DELETE DATABASE
|
||||
### DELETE AND CREATE DATABASE
|
||||
PGPASSWORD="$POSTGRES_ADMIN_PASSWORD" psql -h "$POSTGRES_HOST" -U "$POSTGRES_ADMIN_USER" -d postgres -c "
|
||||
SELECT pg_terminate_backend(pid) FROM pg_stat_activity
|
||||
WHERE datname = '$UUID' AND pid <> pg_backend_pid();
|
||||
"
|
||||
PGPASSWORD="$POSTGRES_ADMIN_PASSWORD" psql -h "$POSTGRES_HOST" -U "$POSTGRES_ADMIN_USER" -d postgres -c "
|
||||
DROP DATABASE IF EXISTS \"$UUID\";
|
||||
"
|
||||
|
||||
PGPASSWORD="$POSTGRES_ADMIN_PASSWORD" psql \
|
||||
-h "$POSTGRES_HOST" -U "$POSTGRES_ADMIN_USER" -p "$POSTGRES_PORT" -d postgres \
|
||||
-c "DROP DATABASE IF EXISTS \"$UUID\";"
|
||||
-c "ALTER ROLE \"$1\" CREATEDB;"
|
||||
|
||||
|
||||
doas docker exec "${1%}" rm -rf /home/odoo/.local/share/Odoo/filestore
|
||||
|
||||
echo "deleting old restore artifacts"
|
||||
doas docker exec "${1%}" rm -rf /root/.local/
|
||||
doas docker exec "${1%}" odoo db --db_host beedb -w "$ODOO_DB_PASSWORD" -r "$1" load "$1" $FILENAME -f
|
||||
|
||||
if [[ "$1" == *"_"* ]]; then
|
||||
echo "Neutralize DB"
|
||||
doas docker exec "${1%_}" odoo db --db_host beedb -w "${1%_}" -r "$1" load "$1" $FILENAME -f --neutralize
|
||||
else
|
||||
echo "No Neutralize DB"
|
||||
doas docker exec "${1%}" odoo db --db_host beedb -w "${1%_}" -r "$1" load "$1" $FILENAME -f
|
||||
fi
|
||||
|
||||
|
||||
|
||||
doas docker exec "${1%}" cp -r /root/.local/. /var/lib/odoo/.local/
|
||||
doas docker exec "${1%}" chown -R odoo:odoo /var/lib/odoo/.local/
|
||||
|
||||
### transfer ownership
|
||||
PGPASSWORD="$POSTGRES_ADMIN_PASSWORD" psql \
|
||||
-h "$POSTGRES_HOST" -U "$POSTGRES_ADMIN_USER" -p "$POSTGRES_PORT" -d postgres \
|
||||
-c "ALTER DATABASE \"$UUID\" OWNER TO \"$UUID\";"
|
||||
-c "ALTER ROLE \"$1\" 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
|
||||
|
||||
docker restart "${1%}"
|
||||
|
||||
27
app/sbin/api
27
app/sbin/api
@@ -35,7 +35,14 @@ def run_command(cmd: list[str]) -> str:
|
||||
"""Run a shell command and return stdout or raise HTTPException on error."""
|
||||
result = subprocess.run(cmd, capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
raise HTTPException(status_code=500, detail=result.stderr.strip() or "Unknown error")
|
||||
error_msg = (
|
||||
f"Command failed\n"
|
||||
f"Command: {' '.join(cmd)}\n"
|
||||
f"Return code: {result.returncode}\n"
|
||||
f"Stdout: {result.stdout.strip()}\n"
|
||||
f"Stderr: {result.stderr.strip() or 'None'}"
|
||||
)
|
||||
raise HTTPException(status_code=500, detail=error_msg)
|
||||
return result.stdout.strip()
|
||||
|
||||
|
||||
@@ -155,16 +162,18 @@ def nuke_container(request: UUIDRequest):
|
||||
|
||||
@app.post("/container/info", dependencies=[Depends(verify_api_key)])
|
||||
def info_container(request: Optional[UUIDRequest] = None):
|
||||
# Fields to select
|
||||
fields = [
|
||||
"ID", "UUID", "email", "expires", "tags", "env", "affiliate",
|
||||
"image", "history", "comment", "domains", "status", "created"
|
||||
]
|
||||
field_str = ", ".join(fields)
|
||||
|
||||
# Execute query
|
||||
if request:
|
||||
rows = execute_db(
|
||||
f"SELECT {field_str} FROM containers WHERE UUID=?",
|
||||
(request.UUID,),
|
||||
(str(request.UUID),),
|
||||
fetch=True
|
||||
)
|
||||
else:
|
||||
@@ -173,15 +182,21 @@ def info_container(request: Optional[UUIDRequest] = None):
|
||||
fetch=True
|
||||
)
|
||||
|
||||
# Map rows to dicts with field names
|
||||
containers = [dict(zip(fields, row)) for row in rows]
|
||||
# Map rows to dicts safely
|
||||
containers = []
|
||||
for row in rows:
|
||||
if isinstance(row, dict):
|
||||
# Already a dict (e.g., some DB wrappers)
|
||||
containers.append(row)
|
||||
else:
|
||||
# Tuple/list -> map with fields
|
||||
containers.append(dict(zip(fields, row)))
|
||||
|
||||
# Wrap in N8N JSON format
|
||||
# Wrap in n8n JSON format
|
||||
n8n_items = [{"json": container} for container in containers]
|
||||
|
||||
return n8n_items
|
||||
|
||||
|
||||
@app.post("/container/bump", dependencies=[Depends(verify_api_key)])
|
||||
def bump_container(request: UUIDRequest):
|
||||
today = datetime.utcnow().strftime("%Y-%m-%d")
|
||||
|
||||
15
app/sbin/backup/ODOO_19
Executable file
15
app/sbin/backup/ODOO_19
Executable file
@@ -0,0 +1,15 @@
|
||||
#!/bin/bash
|
||||
|
||||
source /4server/sbin/helpers
|
||||
get_contract_info
|
||||
export ODOO_DB_PASSWORD=$(echo "$SECRET" | jq -r '.psql')
|
||||
echo "PASSWORD $ODOO_DB_PASSWORD UUID $UUID"
|
||||
|
||||
|
||||
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/*
|
||||
|
||||
|
||||
36
app/sbin/backupContainer
Executable file
36
app/sbin/backupContainer
Executable file
@@ -0,0 +1,36 @@
|
||||
#!/bin/bash
|
||||
# Usage: ./start_by_uuid.sh <uuid>
|
||||
# Example: ./start_by_uuid.sh abc-001-xxxx-xxxx-xxxx
|
||||
exec > /4server/data/log/backupContainer.log 2>&1
|
||||
echo "$(date '+%Y-%m-%d %H:%M') Backup container $1"
|
||||
|
||||
source /4server/sbin/helpers
|
||||
|
||||
BIN_PATH="/4server/sbin"
|
||||
|
||||
UUID="$1"
|
||||
|
||||
if [[ -z "$UUID" ]]; then
|
||||
echo "Usage: $0 <uuid>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
get_contract_info
|
||||
|
||||
# Extract the second part of UUID (split by "-")
|
||||
SECOND_PART=$(echo "$UUID" | cut -d'-' -f2)
|
||||
|
||||
# Decide which script to run
|
||||
case "$SECOND_PART" in
|
||||
001)
|
||||
"$BIN_PATH/backup/n8n"
|
||||
;;
|
||||
003)
|
||||
"$BIN_PATH/backup/ODOO_19"
|
||||
;;
|
||||
*)
|
||||
echo "Unknown UUID type: $SECOND_PART"
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
|
||||
34
app/sbin/checkCalls
Executable file
34
app/sbin/checkCalls
Executable file
@@ -0,0 +1,34 @@
|
||||
#!/bin/bash
|
||||
|
||||
cd /4server/data/
|
||||
|
||||
while :
|
||||
do
|
||||
|
||||
for dir in ???-???-*; do
|
||||
if [ -d "${dir}/cc" ]; then
|
||||
if [ -f "${dir}/cc/backup" ]; then
|
||||
echo "BACKUP for: ${dir%/}"
|
||||
/4server/sbin/backupContainer ${dir%/} 2
|
||||
rm "${dir}/cc/backup"
|
||||
fi
|
||||
|
||||
if [ -f "${dir}/cc/restart" ]; then
|
||||
echo "Restart for: ${dir%/}"
|
||||
/4server/sbin/startContainer ${dir%/}
|
||||
rm "${dir}/cc/restart"
|
||||
fi
|
||||
|
||||
if [ -f "${dir}/cc/restore" ]; then
|
||||
FILENAME=$(head -n 1 "${dir}/cc/restore")
|
||||
echo "Restore for: ${dir%/} - $FILENAME"
|
||||
/4server/sbin/ODOO_19/restore ${dir%/} $FILENAME
|
||||
rm "${dir}/cc/restore"
|
||||
fi
|
||||
|
||||
fi
|
||||
done
|
||||
|
||||
sleep 60
|
||||
|
||||
done
|
||||
@@ -1,5 +1,12 @@
|
||||
#!/bin/bash
|
||||
|
||||
POSTGRES_HOST="${POSTGRES_HOST:-beedb}"
|
||||
POSTGRES_PORT="${POSTGRES_PORT:-5432}"
|
||||
POSTGRES_ADMIN_USER="${POSTGRES_ADMIN_USER:-1gtT0sf8klB9lDbYZD9}"
|
||||
POSTGRES_ADMIN_PASSWORD="${POSTGRES_ADMIN_PASSWORD:-ZpSwWNafyy9GhY2gzHw}"
|
||||
|
||||
|
||||
|
||||
get_contract_info() {
|
||||
|
||||
DB_PATH="/4server/data/contracts.db"
|
||||
|
||||
@@ -2,19 +2,16 @@
|
||||
|
||||
# Load functions
|
||||
source /4server/sbin/ODOO_19/ODOO_19.lib
|
||||
source /4server/sbin/helpers
|
||||
|
||||
# Config variables
|
||||
UUID="${UUID:-default}"
|
||||
BRANCH="${BRANCH:-main}"
|
||||
STAGING="${STAGING:-false}"
|
||||
BRANCH="${BRANCH:-release}"
|
||||
|
||||
POSTGRES_HOST="${POSTGRES_HOST:-beedb}"
|
||||
POSTGRES_PORT="${POSTGRES_PORT:-5432}"
|
||||
POSTGRES_ADMIN_USER="${POSTGRES_ADMIN_USER:-1gtT0sf8klB9lDbYZD9}"
|
||||
POSTGRES_ADMIN_PASSWORD="${POSTGRES_ADMIN_PASSWORD:-ZpSwWNafyy9GhY2gzHw}"
|
||||
ODOO_DB_USER="${UUID}"
|
||||
export ODOO_DB_PASSWORD=$(echo "$SECRET" | jq -r '.psql')
|
||||
|
||||
|
||||
BASEURL="${BASEURL:-/4server/data/$UUID}"
|
||||
DATA_DIR="$BASEURL/odoo/"
|
||||
CUSTOM_DIR="$BASEURL/git/$UUID/custom/"
|
||||
@@ -24,10 +21,8 @@ CONFIG_DIR="$BASEURL/config/"
|
||||
CC_DIR="$BASEURL/cc/"
|
||||
BACKUP_DIR="/BACKUP/$UUID"
|
||||
GIT_DIR="$BASEURL/git-server/"
|
||||
ETC_DIR="$BASEURL/etc/"
|
||||
INSTALL_DIR="$BASEURL/install/"
|
||||
SSH_DIR="$BASEURL/.ssh/"
|
||||
HUGO_DIR="$BASEURL/git-server/local/hugo"
|
||||
|
||||
SERVER_IP=$(ip -4 addr show eth0 | awk '/inet/ {print $2}' | cut -d/ -f1)
|
||||
|
||||
@@ -35,36 +30,34 @@ DOMAIN_LABEL=$(check_domains "$UUID.odoo4projects.com" "$SERVER_IP")
|
||||
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))
|
||||
|
||||
doas docker stop "$UUID" 2>/dev/null
|
||||
doas docker rm "$UUID" 2>/dev/null
|
||||
|
||||
EXTRA_DOCKER_PARAMETER=""
|
||||
if [ -d "$HUGO_DIR" ]; then
|
||||
EXTRA_DOCKER_PARAMETER="-v $HUGO_DIR:/mnt/hugo"
|
||||
fi
|
||||
|
||||
doas docker run -d --name "$UUID" \
|
||||
--network 4server_4projects \
|
||||
--restart=always \
|
||||
$EXTRA_DOCKER_PARAMETER \
|
||||
-v "$DATA_DIR/odoo-web-data:/var/lib/odoo" \
|
||||
-v "$DATA_DIR/odoo-web-data:/home/odoo/.local/share/Odoo" \
|
||||
-v "$CUSTOM_DIR:/mnt/addons/custom" \
|
||||
-v "$ENTERPRISE_DIR:/mnt/addons/enterprise" \
|
||||
-v "$LOGS_DIR:/mnt/logs" \
|
||||
-v "$CC_DIR:/mnt/cc" \
|
||||
-v "$BACKUP_DIR:/mnt/backup" \
|
||||
-v "$CONFIG_DIR:/etc/odoo" \
|
||||
-v "$GIT_DIR:/git-server" \
|
||||
-v "$ETC_DIR:/mnt/etc" \
|
||||
-v "$INSTALL_DIR:/mnt/install" \
|
||||
-v "$SSH_DIR:/etc/sshkey" \
|
||||
-p "$PORT:22" \
|
||||
-e HOST="$POSTGRES_HOST" \
|
||||
-e HOST="beedb" \
|
||||
-e USER="$ODOO_DB_USER" \
|
||||
-e PASSWORD="$ODOO_DB_PASSWORD" \
|
||||
-e STAGING="$STAGING" \
|
||||
-e UUID="$UUID" \
|
||||
--label "$DOMAIN_LABEL" \
|
||||
--label "traefik.http.services.$UUID.loadbalancer.server.port=8069" \
|
||||
--label "traefic.http.routers.$UUID.entrypoints=web, websecure" \
|
||||
|
||||
@@ -25,7 +25,7 @@ case "$SECOND_PART" in
|
||||
001)
|
||||
"$BIN_PATH/start/n8n"
|
||||
;;
|
||||
002)
|
||||
003)
|
||||
"$BIN_PATH/start/ODOO_19"
|
||||
;;
|
||||
*)
|
||||
|
||||
24
app/templates/init.d/checkCalls
Executable file
24
app/templates/init.d/checkCalls
Executable file
@@ -0,0 +1,24 @@
|
||||
#!/sbin/openrc-run
|
||||
|
||||
name="checkCalls"
|
||||
description="check container service calls"
|
||||
|
||||
# Command uses Python inside the venv
|
||||
command="/4server/sbin/checkCalls"
|
||||
command_args=""
|
||||
pidfile="/run/${RC_SVCNAME}.pid"
|
||||
command_background="yes"
|
||||
|
||||
respawn_delay=5 # seconds to wait before restart
|
||||
respawn_max=0 # 0 = unlimited restarts
|
||||
|
||||
# Load environment variables if needed
|
||||
output_log="/4server/data/log/checkCalls.log"
|
||||
error_log="/4server/data/log/checkCalls.log"
|
||||
|
||||
depend() {
|
||||
need net
|
||||
use logger dns
|
||||
after firewall
|
||||
}
|
||||
|
||||
@@ -46,6 +46,13 @@ rex doas chown root:root /etc/init.d/api
|
||||
rex doas rc-update add api default
|
||||
rex doas rc-service api restart
|
||||
|
||||
#INSTALL checkCalls SERVICE
|
||||
template templates/init.d/checkCalls /etc/init.d/checkCalls
|
||||
rex doas chmod 0755 /etc/init.d/checkCalls
|
||||
rex doas chown root:root /etc/init.d/checkCalls
|
||||
rex doas rc-update add checkCalls default
|
||||
rex doas rc-service checkCalls restart
|
||||
|
||||
|
||||
### Infrastructure
|
||||
##### Docker
|
||||
|
||||
Binary file not shown.
15
start
15
start
@@ -1,2 +1,15 @@
|
||||
#!/bin/bash
|
||||
docker compose run alpine /bin/bash
|
||||
|
||||
SERVICE_NAME="alpine"
|
||||
|
||||
# Check if the container is running
|
||||
RUNNING=$(docker compose ps -q $SERVICE_NAME)
|
||||
|
||||
if [ -z "$RUNNING" ]; then
|
||||
echo "Container not running. Starting..."
|
||||
docker compose up -d $SERVICE_NAME
|
||||
fi
|
||||
|
||||
# Connect to the running container
|
||||
docker compose exec -it $SERVICE_NAME sh
|
||||
|
||||
|
||||
Reference in New Issue
Block a user