- Refactor in bot package.
This commit is contained in:
parent
79ac6df738
commit
be1e2575f9
27 changed files with 233 additions and 1663 deletions
37
add-req.sh
37
add-req.sh
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$SCRIPT_DIR"
|
||||
OUTPUT_FILE="$SCRIPT_DIR/prompt.out"
|
||||
OUTPUT_FILE="/tmp/prompt.out"
|
||||
|
||||
rm -f "$OUTPUT_FILE"
|
||||
echo "Consolidated LLM Context" > "$OUTPUT_FILE"
|
||||
|
|
@ -10,7 +10,6 @@ echo "Consolidated LLM Context" > "$OUTPUT_FILE"
|
|||
prompts=(
|
||||
"./prompts/dev/shared.md"
|
||||
"./Cargo.toml"
|
||||
"./prompts/dev/generation.md"
|
||||
)
|
||||
|
||||
for file in "${prompts[@]}"; do
|
||||
|
|
@ -24,19 +23,19 @@ dirs=(
|
|||
#"auth"
|
||||
#"automation"
|
||||
#"basic"
|
||||
#"bot"
|
||||
"bot"
|
||||
#"channels"
|
||||
"config"
|
||||
#"context"
|
||||
"context"
|
||||
#"email"
|
||||
#"file"
|
||||
#"llm"
|
||||
"file"
|
||||
"llm"
|
||||
#"llm_legacy"
|
||||
#"org"
|
||||
"session"
|
||||
"shared"
|
||||
#"tests"
|
||||
#"tools"
|
||||
"tools"
|
||||
#"web_automation"
|
||||
#"whatsapp"
|
||||
)
|
||||
|
|
@ -59,25 +58,10 @@ done
|
|||
# Additional specific files
|
||||
files=(
|
||||
"$PROJECT_ROOT/src/main.rs"
|
||||
"$PROJECT_ROOT/scripts/containers/proxy.sh"
|
||||
"$PROJECT_ROOT/scripts/containers/directory.sh"
|
||||
"$PROJECT_ROOT/scripts/containers/bot.sh"
|
||||
"$PROJECT_ROOT/scripts/containers/system.sh"
|
||||
"$PROJECT_ROOT/scripts/containers/social.sh"
|
||||
"$PROJECT_ROOT/scripts/containers/alm-ci.sh"
|
||||
"$PROJECT_ROOT/scripts/containers/drive.sh"
|
||||
"$PROJECT_ROOT/scripts/containers/tables.sh"
|
||||
"$PROJECT_ROOT/scripts/containers/dns.sh"
|
||||
"$PROJECT_ROOT/scripts/containers/doc-editor.sh"
|
||||
"$PROJECT_ROOT/scripts/containers/host.sh"
|
||||
"$PROJECT_ROOT/scripts/containers/vector-db.sh"
|
||||
"$PROJECT_ROOT/scripts/containers/cache.sh"
|
||||
"$PROJECT_ROOT/scripts/containers/desktop.sh"
|
||||
"$PROJECT_ROOT/scripts/containers/meeting.sh"
|
||||
"$PROJECT_ROOT/scripts/containers/email.sh"
|
||||
"$PROJECT_ROOT/scripts/containers/alm.sh"
|
||||
"$PROJECT_ROOT/scripts/containers/table-editor.sh"
|
||||
"$PROJECT_ROOT/scripts/containers/webmail.sh"
|
||||
"$PROJECT_ROOT/src/basic/keywords/mod.rs"
|
||||
"$PROJECT_ROOT/src/basic/keywords/get.rs"
|
||||
"$PROJECT_ROOT/src/basic/keywords/find.rs"
|
||||
"$PROJECT_ROOT/src/basic/keywords/hear_talk.rs"
|
||||
|
||||
)
|
||||
|
||||
|
|
@ -108,3 +92,4 @@ echo "Context size: $FILE_SIZE bytes"
|
|||
|
||||
cat "$OUTPUT_FILE" | xclip -selection clipboard
|
||||
echo "Content copied to clipboard (xclip)"
|
||||
rm -f "$OUTPUT_FILE"
|
||||
|
|
|
|||
|
|
@ -1,16 +0,0 @@
|
|||
do not comment or echo anything
|
||||
|
||||
keep lines condensed
|
||||
always call it <kind> not own name. Eg.: proxy instead of Caddy. alm instead of forgejo.
|
||||
use KISS priciple
|
||||
|
||||
use local /opt/gbo/{logs, data, conf} exposed as
|
||||
HOST_BASE="/opt/gbo/tenants/$PARAM_TENANT/<kind>"
|
||||
HOST_DATA="$HOST_BASE/data"
|
||||
HOST_CONF="$HOST_BASE/conf"
|
||||
HOST_LOGS="$HOST_BASE/logs"
|
||||
instead of using app original paths.
|
||||
and use /opt/gbo/bin to put local binaries of installations
|
||||
during sh exection, never touch files in /opt/gbo/{logs, data, conf}
|
||||
use wget
|
||||
use gbuser as system user
|
||||
|
|
@ -1,173 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Configuration
|
||||
ALM_CI_NAME="CI"
|
||||
ALM_CI_LABELS="gbo"
|
||||
FORGEJO_RUNNER_VERSION="v6.3.1"
|
||||
FORGEJO_RUNNER_BINARY="forgejo-runner-6.3.1-linux-amd64"
|
||||
CONTAINER_IMAGE="images:debian/12"
|
||||
|
||||
# Paths
|
||||
HOST_BASE="/opt/gbo/tenants/$PARAM_TENANT/alm-ci"
|
||||
HOST_DATA="$HOST_BASE/data"
|
||||
HOST_CONF="$HOST_BASE/conf"
|
||||
HOST_LOGS="$HOST_BASE/logs"
|
||||
BIN_PATH="/opt/gbo/bin"
|
||||
CONTAINER_NAME="${PARAM_TENANT}-alm-ci"
|
||||
|
||||
# Create host directories
|
||||
mkdir -p "$HOST_DATA" "$HOST_CONF" "$HOST_LOGS" || exit 1
|
||||
chmod -R 750 "$HOST_BASE" || exit 1
|
||||
|
||||
# Launch container
|
||||
if ! lxc launch "$CONTAINER_IMAGE" "$CONTAINER_NAME" -c security.privileged=true; then
|
||||
echo "Failed to launch container"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Wait for container to be ready
|
||||
for i in {1..10}; do
|
||||
if lxc exec "$CONTAINER_NAME" -- bash -c "true"; then
|
||||
break
|
||||
fi
|
||||
sleep 3
|
||||
done
|
||||
|
||||
|
||||
# Container setup
|
||||
lxc exec "$CONTAINER_NAME" -- bash -c "
|
||||
set -e
|
||||
|
||||
useradd --system --no-create-home --shell /bin/false $CONTAINER_NAME
|
||||
|
||||
# Update and install dependencies
|
||||
apt-get update && apt-get install -y wget git || { echo 'Package installation failed'; exit 1; }
|
||||
|
||||
sudo apt update
|
||||
sudo apt install -y curl gnupg ca-certificates git
|
||||
apt-get update && apt-get install -y \
|
||||
build-essential cmake git pkg-config libjpeg-dev libtiff-dev \
|
||||
libpng-dev libavcodec-dev libavformat-dev libswscale-dev \
|
||||
libv4l-dev libatlas-base-dev gfortran python3-dev cpulimit \
|
||||
expect libxtst-dev libpng-dev
|
||||
|
||||
sudo apt-get install -y libcairo2-dev libpango1.0-dev libgif-dev librsvg2-dev
|
||||
sudo apt install xvfb -y
|
||||
|
||||
sudo apt install -y \
|
||||
libnss3 \
|
||||
libatk1.0-0 \
|
||||
libatk-bridge2.0-0 \
|
||||
libcups2 \
|
||||
libdrm2 \
|
||||
libxkbcommon0 \
|
||||
libxcomposite1 \
|
||||
libxdamage1 \
|
||||
libxfixes3 \
|
||||
libxrandr2 \
|
||||
libgbm1 \
|
||||
libasound2 \
|
||||
libpangocairo-1.0-0
|
||||
|
||||
export OPENCV4NODEJS_DISABLE_AUTOBUILD=1
|
||||
export OPENCV_LIB_DIR=/usr/lib/x86_64-linux-gnu
|
||||
|
||||
sudo apt install -y curl gnupg ca-certificates git
|
||||
|
||||
# Install Node.js 22.x
|
||||
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo bash -
|
||||
sudo apt install -y nodejs
|
||||
npm install -g pnpm@latest
|
||||
|
||||
# Install rust 1.85
|
||||
apt-get install -y libssl-dev pkg-config
|
||||
sudo apt-get install -y \
|
||||
apt-transport-https \
|
||||
software-properties-common \
|
||||
gnupg \
|
||||
cmake \
|
||||
build-essential \
|
||||
clang \
|
||||
libclang-dev \
|
||||
libz-dev \
|
||||
libssl-dev \
|
||||
pkg-config
|
||||
|
||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- --default-toolchain 1.85.1 -y
|
||||
source ~/.cargo/env
|
||||
rustc --version
|
||||
|
||||
|
||||
# Install Xvfb and other dependencies
|
||||
sudo apt install -y xvfb libgbm-dev lxd-client
|
||||
|
||||
# Create directories
|
||||
mkdir -p \"$BIN_PATH\" /opt/gbo/data /opt/gbo/conf /opt/gbo/logs || { echo 'Directory creation failed'; exit 1; }
|
||||
|
||||
# Download and install forgejo-runner
|
||||
wget -O \"$BIN_PATH/forgejo-runner\" \"https://code.forgejo.org/forgejo/runner/releases/download/$FORGEJO_RUNNER_VERSION/$FORGEJO_RUNNER_BINARY\" || { echo 'Download failed'; exit 1; }
|
||||
chmod +x \"$BIN_PATH/forgejo-runner\" || { echo 'chmod failed'; exit 1; }
|
||||
|
||||
cd \"$BIN_PATH\"
|
||||
|
||||
# Register runner
|
||||
\"$BIN_PATH/forgejo-runner\" register --no-interactive \\
|
||||
--name \"$ALM_CI_NAME\" \\
|
||||
--instance \"$PARAM_ALM_CI_INSTANCE\" \\
|
||||
--token \"$PARAM_ALM_CI_TOKEN\" \\
|
||||
--labels \"$ALM_CI_LABELS\" || { echo 'Runner registration failed'; exit 1; }
|
||||
|
||||
chown -R $CONTAINER_NAME:$CONTAINER_NAME /opt/gbo/bin /opt/gbo/data /opt/gbo/conf /opt/gbo/logs
|
||||
|
||||
"
|
||||
|
||||
# Set permissions
|
||||
echo "[CONTAINER] Setting permissions..."
|
||||
EMAIL_UID=$(lxc exec "$PARAM_TENANT"-alm-ci -- id -u $CONTAINER_NAME)
|
||||
EMAIL_GID=$(lxc exec "$PARAM_TENANT"-alm-ci -- id -g $CONTAINER_NAME)
|
||||
HOST_EMAIL_UID=$((100000 + EMAIL_UID))
|
||||
HOST_EMAIL_GID=$((100000 + EMAIL_GID))
|
||||
sudo chown -R "$HOST_EMAIL_UID:$HOST_EMAIL_GID" "$HOST_BASE"
|
||||
|
||||
|
||||
# Add directory mappings
|
||||
lxc config device add "$CONTAINER_NAME" almdata disk source="$HOST_DATA" path=/opt/gbo/data || exit 1
|
||||
lxc config device add "$CONTAINER_NAME" almconf disk source="$HOST_CONF" path=/opt/gbo/conf || exit 1
|
||||
lxc config device add "$CONTAINER_NAME" almlogs disk source="$HOST_LOGS" path=/opt/gbo/logs || exit 1
|
||||
|
||||
|
||||
lxc exec "$CONTAINER_NAME" -- bash -c "
|
||||
# Create systemd service
|
||||
cat > /etc/systemd/system/alm-ci.service <<EOF
|
||||
[Unit]
|
||||
Description=ALM CI Runner
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=$CONTAINER_NAME
|
||||
Group=$CONTAINER_NAME
|
||||
ExecStart=$BIN_PATH/forgejo-runner daemon
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
StandardOutput=append:/opt/gbo/logs/output.log
|
||||
StandardError=append:/opt/gbo/logs/error.log
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
# Enable and start service
|
||||
systemctl daemon-reload || { echo 'daemon-reload failed'; exit 1; }
|
||||
systemctl enable alm-ci || { echo 'enable service failed'; exit 1; }
|
||||
systemctl start alm-ci || { echo 'start service failed'; exit 1; }
|
||||
"
|
||||
|
||||
|
||||
LXC_BOT="/opt/gbo/tenants/$PARAM_TENANT/bot/data"
|
||||
LXC_PROXY="/opt/gbo/tenants/$PARAM_TENANT/proxy/data/websites"
|
||||
LXC_SYSTEM="/opt/gbo/tenants/$PARAM_TENANT/system/bin"
|
||||
|
||||
lxc config device add "$CONTAINER_NAME" almbot disk source="$LXC_BOT" path=/opt/gbo/bin/bot
|
||||
lxc config device add "$CONTAINER_NAME" almproxy disk source="$LXC_PROXY" path=/opt/gbo/bin/proxy
|
||||
lxc config device add "$CONTAINER_NAME" almsystem disk source="$LXC_SYSTEM" path=/opt/gbo/bin/syst em || exit 1
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
HOST_BASE="/opt/gbo/tenants/$PARAM_TENANT/alm"
|
||||
HOST_DATA="$HOST_BASE/data"
|
||||
HOST_CONF="$HOST_BASE/conf"
|
||||
HOST_LOGS="$HOST_BASE/logs"
|
||||
ALM_PATH=/opt/gbo/bin
|
||||
|
||||
mkdir -p "$HOST_DATA" "$HOST_CONF" "$HOST_LOGS"
|
||||
chmod -R 750 "$HOST_BASE"
|
||||
|
||||
lxc launch images:debian/12 "$PARAM_TENANT"-alm -c security.privileged=true
|
||||
sleep 15
|
||||
|
||||
lxc exec "$PARAM_TENANT"-alm -- bash -c "
|
||||
apt-get update && apt-get install -y git git-lfs wget
|
||||
mkdir -p /opt/gbo/bin
|
||||
wget https://codeberg.org/forgejo/forgejo/releases/download/v10.0.2/forgejo-10.0.2-linux-amd64 -O $ALM_PATH/forgejo
|
||||
chmod +x $ALM_PATH/forgejo
|
||||
useradd --system --no-create-home --shell /bin/false alm
|
||||
"
|
||||
|
||||
FORGEJO_UID=$(lxc exec "$PARAM_TENANT"-alm -- id -u alm)
|
||||
FORGEJO_GID=$(lxc exec "$PARAM_TENANT"-alm -- id -g alm)
|
||||
HOST_FORGEJO_UID=$((100000 + FORGEJO_UID))
|
||||
HOST_FORGEJO_GID=$((100000 + FORGEJO_GID))
|
||||
chown -R "$HOST_FORGEJO_UID:$HOST_FORGEJO_GID" "$HOST_BASE"
|
||||
|
||||
lxc config device add "$PARAM_TENANT"-alm almdata disk source="$HOST_DATA" path=/opt/gbo/data
|
||||
lxc config device add "$PARAM_TENANT"-alm almconf disk source="$HOST_CONF" path=/opt/gbo/conf
|
||||
lxc config device add "$PARAM_TENANT"-alm almlogs disk source="$HOST_LOGS" path=/opt/gbo/logs
|
||||
|
||||
lxc exec "$PARAM_TENANT"-alm -- bash -c "
|
||||
mkdir -p /opt/gbo/data /opt/gbo/conf /opt/gbo/logs
|
||||
chown -R alm:alm /opt/gbo
|
||||
|
||||
|
||||
cat > /etc/systemd/system/alm.service <<EOF
|
||||
[Unit]
|
||||
Description=alm
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
User=alm
|
||||
Group=alm
|
||||
WorkingDirectory=/opt/gbo/data
|
||||
ExecStart=/opt/gbo/bin/forgejo web --config /opt/gbo/conf/app.ini
|
||||
Restart=always
|
||||
Environment=USER=alm HOME=/opt/gbo/data
|
||||
StandardOutput=append:/opt/gbo/logs/stdout.log
|
||||
StandardError=append:/opt/gbo/logs/stderr.log
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable alm
|
||||
systemctl start alm
|
||||
"
|
||||
|
||||
lxc config device remove "$PARAM_TENANT"-alm alm-proxy 2>/dev/null || true
|
||||
lxc config device add "$PARAM_TENANT"-alm alm-proxy proxy \
|
||||
listen=tcp:0.0.0.0:"$PARAM_ALM_PORT" \
|
||||
connect=tcp:127.0.0.1:"$PARAM_ALM_PORT"
|
||||
|
|
@ -1,113 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
HOST_BASE="/opt/gbo/tenants/$PARAM_TENANT/bot"
|
||||
HOST_DATA="$HOST_BASE/data"
|
||||
HOST_CONF="$HOST_BASE/conf"
|
||||
HOST_LOGS="$HOST_BASE/logs"
|
||||
|
||||
mkdir -p "$HOST_DATA" "$HOST_CONF" "$HOST_LOGS"
|
||||
chmod -R 750 "$HOST_BASE"
|
||||
|
||||
lxc launch images:debian/12 "$PARAM_TENANT"-bot -c security.privileged=true
|
||||
sleep 15
|
||||
|
||||
lxc exec "$PARAM_TENANT"-bot -- bash -c "
|
||||
|
||||
apt-get update && apt-get install -y \
|
||||
build-essential cmake git pkg-config libjpeg-dev libtiff-dev \
|
||||
libpng-dev libavcodec-dev libavformat-dev libswscale-dev \
|
||||
libv4l-dev libatlas-base-dev gfortran python3-dev cpulimit \
|
||||
expect libxtst-dev libpng-dev
|
||||
|
||||
sudo apt-get install -y libcairo2-dev libpango1.0-dev libgif-dev librsvg2-dev
|
||||
sudo apt install xvfb -y
|
||||
|
||||
sudo apt install -y \
|
||||
libnss3 \
|
||||
libatk1.0-0 \
|
||||
libatk-bridge2.0-0 \
|
||||
libcups2 \
|
||||
libdrm2 \
|
||||
libxkbcommon0 \
|
||||
libxcomposite1 \
|
||||
libxdamage1 \
|
||||
libxfixes3 \
|
||||
libxrandr2 \
|
||||
libgbm1 \
|
||||
libasound2 \
|
||||
libpangocairo-1.0-0
|
||||
|
||||
export OPENCV4NODEJS_DISABLE_AUTOBUILD=1
|
||||
export OPENCV_LIB_DIR=/usr/lib/x86_64-linux-gnu
|
||||
|
||||
useradd --system --no-create-home --shell /bin/false gbuser
|
||||
"
|
||||
|
||||
BOT_UID=$(lxc exec "$PARAM_TENANT"-bot -- id -u gbuser)
|
||||
BOT_GID=$(lxc exec "$PARAM_TENANT"-bot -- id -g gbuser)
|
||||
HOST_BOT_UID=$((100000 + BOT_UID))
|
||||
HOST_BOT_GID=$((100000 + BOT_GID))
|
||||
chown -R "$HOST_BOT_UID:$HOST_BOT_GID" "$HOST_BASE"
|
||||
|
||||
lxc config device add "$PARAM_TENANT"-bot botdata disk source="$HOST_DATA" path=/opt/gbo/data
|
||||
lxc config device add "$PARAM_TENANT"-bot botconf disk source="$HOST_CONF" path=/opt/gbo/conf
|
||||
lxc config device add "$PARAM_TENANT"-bot botlogs disk source="$HOST_LOGS" path=/opt/gbo/logs
|
||||
|
||||
lxc exec "$PARAM_TENANT"-bot -- bash -c '
|
||||
mkdir -p /opt/gbo/data /opt/gbo/conf /opt/gbo/logs
|
||||
|
||||
sudo apt update
|
||||
sudo apt install -y curl gnupg ca-certificates git
|
||||
|
||||
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo bash -
|
||||
sudo apt install -y nodejs
|
||||
|
||||
sudo apt install -y xvfb libgbm-dev
|
||||
|
||||
wget https://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/google-chrome-stable_128.0.6613.119-1_amd64.deb
|
||||
sudo apt install ./google-chrome-stable_128.0.6613.119-1_amd64.deb
|
||||
|
||||
cd /opt/gbo/data
|
||||
git clone https://alm.pragmatismo.com.br/generalbots/botserver.git
|
||||
cd botserver
|
||||
npm install
|
||||
|
||||
./node_modules/.bin/tsc
|
||||
cd packages/default.gbui
|
||||
npm install
|
||||
npm run build
|
||||
|
||||
chown -R gbuser:gbuser /opt/gbo
|
||||
|
||||
# Create systemd service
|
||||
sudo tee /etc/systemd/system/bot.service > /dev/null <<EOF
|
||||
[Unit]
|
||||
Description=Bot Server
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
User=gbuser
|
||||
Group=gbuser
|
||||
Environment="DISPLAY=:99"
|
||||
ExecStartPre=/bin/bash -c "/usr/bin/Xvfb :99 -screen 0 1024x768x24 -ac +extension GLX +render -noreset &"
|
||||
WorkingDirectory=/opt/gbo/data/botserver
|
||||
ExecStart=/usr/bin/node /opt/gbo/data/botserver/boot.mjs
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
StandardOutput=append:/opt/gbo/logs/stdout.log
|
||||
StandardError=append:/opt/gbo/logs/stderr.log
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
# Reload and start service
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable bot.service
|
||||
sudo systemctl start bot.service
|
||||
'
|
||||
|
||||
lxc config device remove "$PARAM_TENANT"-bot bot-proxy 2>/dev/null || true
|
||||
lxc config device add "$PARAM_TENANT"-bot bot-proxy proxy \
|
||||
listen=tcp:0.0.0.0:"$PARAM_BOT_PORT" \
|
||||
connect=tcp:127.0.0.1:"$PARAM_BOT_PORT"
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/valkey.gpg
|
||||
echo "deb [signed-by=/usr/share/keyrings/valkey.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/valkey.list
|
||||
sudo apt update
|
||||
sudo apt install valkey-server
|
||||
|
||||
sudo systemctl enable valkey-server
|
||||
sudo systemctl start valkey-server
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
HOST_BASE="/opt/gbo/tenants/$PARAM_TENANT/desktop"
|
||||
HOST_DATA="$HOST_BASE/data"
|
||||
HOST_CONF="$HOST_BASE/conf"
|
||||
HOST_LOGS="$HOST_BASE/logs"
|
||||
|
||||
mkdir -p "$HOST_DATA" "$HOST_CONF" "$HOST_LOGS"
|
||||
chmod -R 750 "$HOST_BASE"
|
||||
|
||||
lxc launch images:debian/12 "$PARAM_TENANT"-desktop -c security.privileged=true
|
||||
sleep 15
|
||||
|
||||
lxc exec "$PARAM_TENANT"-desktop -- bash -c "
|
||||
|
||||
apt-get update
|
||||
apt-get install -y xvfb xrdp xfce4 xfce4-goodies
|
||||
cat > /etc/xrdp/startwm.sh <<EOF
|
||||
#!/bin/sh
|
||||
if [ -r /etc/default/locale ]; then
|
||||
. /etc/default/locale
|
||||
export LANG LANGUAGE
|
||||
fi
|
||||
startxfce4
|
||||
EOF
|
||||
chmod +x /etc/xrdp/startwm.sh
|
||||
systemctl restart xrdp
|
||||
systemctl enable xrdp
|
||||
|
||||
# For the root user (since you're logging in as root)
|
||||
echo "exec startxfce4" > /root/.xsession
|
||||
chmod +x /root/.xsession
|
||||
|
||||
apt install -y curl apt-transport-https gnupg
|
||||
curl -s https://brave-browser-apt-release.s3.brave.com/brave-core.asc | gpg --dearmor > /usr/share/keyrings/brave-browser-archive-keyring.gpg
|
||||
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/brave-browser-archive-keyring.gpg] https://brave-browser-apt-release.s3.brave.com/ stable main" > /etc/apt/sources.list.d/brave-browser-release.list
|
||||
apt update && apt install -y brave-browser
|
||||
|
||||
sudo apt install gnome-tweaks
|
||||
/etc/environment
|
||||
GTK_IM_MODULE=cedilla
|
||||
QT_IM_MODULE=cedilla
|
||||
|
||||
"
|
||||
port=3389
|
||||
lxc config device remove "$PARAM_TENANT"-desktop "port-$port" 2>/dev/null || true
|
||||
lxc config device add "$PARAM_TENANT"-desktop "port-$port" proxy listen=tcp:0.0.0.0:$port connect=tcp:127.0.0.1:$port
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
HOST_BASE="/opt/gbo/tenants/$PARAM_TENANT/directory"
|
||||
HOST_DATA="$HOST_BASE/data"
|
||||
HOST_CONF="$HOST_BASE/conf"
|
||||
HOST_LOGS="$HOST_BASE/logs"
|
||||
|
||||
sudo mkdir -p "$HOST_DATA" "$HOST_CONF" "$HOST_LOGS"
|
||||
sudo chmod -R 750 "$HOST_BASE"
|
||||
|
||||
lxc launch images:debian/12 "$PARAM_TENANT"-directory -c security.privileged=true
|
||||
sleep 15
|
||||
|
||||
lxc exec "$PARAM_TENANT"-directory -- bash -c "
|
||||
apt-get update && apt-get install -y wget libcap2-bin
|
||||
wget -c https://github.com/zitadel/zitadel/releases/download/v2.71.2/zitadel-linux-amd64.tar.gz -O - | tar -xz -C /tmp
|
||||
mkdir -p /opt/gbo/bin
|
||||
mv /tmp/zitadel-linux-amd64/zitadel /opt/gbo/bin/zitadel
|
||||
chmod +x /opt/gbo/bin/zitadel
|
||||
sudo setcap 'cap_net_bind_service=+ep' /opt/gbo/bin/zitadel
|
||||
|
||||
useradd --system --no-create-home --shell /bin/false gbuser
|
||||
mkdir -p /opt/gbo/data /opt/gbo/conf /opt/gbo/logs
|
||||
chown -R gbuser:gbuser /opt/gbo/data /opt/gbo/conf /opt/gbo/logs /opt/gbo/bin
|
||||
"
|
||||
|
||||
GBUSER_UID=$(lxc exec "$PARAM_TENANT"-directory -- id -u gbuser)
|
||||
GBUSER_GID=$(lxc exec "$PARAM_TENANT"-directory -- id -g gbuser)
|
||||
HOST_GBUSER_UID=$((100000 + GBUSER_UID))
|
||||
HOST_GBUSER_GID=$((100000 + GBUSER_GID))
|
||||
sudo chown -R "$HOST_GBUSER_UID:$HOST_GBUSER_GID" "$HOST_BASE"
|
||||
|
||||
lxc config device add "$PARAM_TENANT"-directory directorydata disk source="$HOST_DATA" path=/opt/gbo/data
|
||||
lxc config device add "$PARAM_TENANT"-directory directoryconf disk source="$HOST_CONF" path=/opt/gbo/conf
|
||||
lxc config device add "$PARAM_TENANT"-directory directorylogs disk source="$HOST_LOGS" path=/opt/gbo/logs
|
||||
|
||||
lxc exec "$PARAM_TENANT"-directory -- bash -c "
|
||||
chown -R gbuser:gbuser /opt/gbo/data /opt/gbo/conf /opt/gbo/logs /opt/gbo/bin
|
||||
|
||||
cat > /etc/systemd/system/directory.service <<EOF
|
||||
[Unit]
|
||||
Description=Directory Service
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=gbuser
|
||||
Group=gbuser
|
||||
ExecStart=/opt/gbo/bin/zitadel start --masterkey $PARAM_DIRECTORY_MASTERKEY --config /opt/gbo/conf/config.yaml --tlsMode external
|
||||
WorkingDirectory=/opt/gbo/bin
|
||||
StandardOutput=append:/opt/gbo/logs/output.log
|
||||
StandardError=append:/opt/gbo/logs/error.log
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable directory
|
||||
systemctl start directory
|
||||
"
|
||||
|
||||
lxc config device remove "$PARAM_TENANT"-directory directory-proxy 2>/dev/null || true
|
||||
lxc config device add "$PARAM_TENANT"-directory directory-proxy proxy \
|
||||
listen=tcp:0.0.0.0:"$PARAM_DIRECTORY_PORT" \
|
||||
connect=tcp:127.0.0.1:"$PARAM_DIRECTORY_PORT"
|
||||
|
|
@ -1,88 +0,0 @@
|
|||
#!/bin/bash
|
||||
HOST_BASE="/opt/gbo/tenants/$PARAM_TENANT/dns"
|
||||
HOST_CONF="$HOST_BASE/conf"
|
||||
HOST_DATA="$HOST_BASE/data"
|
||||
HOST_LOGS="$HOST_BASE/logs"
|
||||
mkdir -p "$HOST_BASE" "$HOST_CONF" "$HOST_DATA" "$HOST_LOGS"
|
||||
chmod -R 750 "$HOST_BASE"
|
||||
|
||||
lxc network set lxdbr0 user.dns.nameservers $PARAM_DNS_INTERNAL_IP,8.8.8.8,1.1.1.1
|
||||
lxc network set lxdbr0 dns.mode managed
|
||||
|
||||
# Clear existing rules
|
||||
sudo iptables -F
|
||||
|
||||
# Allow DNS traffic
|
||||
sudo iptables -A INPUT -p udp --dport 53 -j ACCEPT
|
||||
sudo iptables -A INPUT -p tcp --dport 53 -j ACCEPT
|
||||
sudo iptables -A FORWARD -p udp --dport 53 -j ACCEPT
|
||||
sudo iptables -A FORWARD -p tcp --dport 53 -j ACCEPT
|
||||
|
||||
# Enable NAT
|
||||
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
|
||||
|
||||
# Save rules (if using iptables-persistent)
|
||||
sudo netfilter-persistent save
|
||||
|
||||
lxc launch images:debian/12 "${PARAM_TENANT}-dns" -c security.privileged=true
|
||||
until lxc exec "${PARAM_TENANT}-dns" -- true; do sleep 3; done
|
||||
|
||||
lxc config device remove pragmatismo-dns dns-udp
|
||||
lxc config device remove pragmatismo-dns dns-tcp
|
||||
|
||||
# Forward HOST's public IP:53 → CONTAINER's 0.0.0.0:53
|
||||
lxc config device add pragmatismo-dns dns-udp proxy listen=udp:$GB_PUBLIC_IP:53 connect=udp:0.0.0.0:53
|
||||
lxc config device add pragmatismo-dns dns-tcp proxy listen=tcp:$GB_PUBLIC_IP:53 connect=tcp:0.0.0.0:53
|
||||
|
||||
|
||||
lxc exec "${PARAM_TENANT}-dns" -- bash -c "
|
||||
mkdir /opt/gbo
|
||||
mkdir /opt/gbo/{bin,conf,data,logs}
|
||||
|
||||
echo 'nameserver 8.8.8.8' > /etc/resolv.conf
|
||||
|
||||
|
||||
apt-get upgrade -y && apt-get install -y wget
|
||||
wget -qO /opt/gbo/bin/coredns https://github.com/coredns/coredns/releases/download/v1.12.4/coredns_1.12.4_linux_amd64.tgz
|
||||
tar -xzf /opt/gbo/bin/coredns -C /opt/gbo/bin/
|
||||
useradd --system --no-create-home --shell /bin/false gbuser
|
||||
setcap cap_net_bind_service=+ep /opt/gbo/bin/coredns
|
||||
|
||||
|
||||
cat > /etc/systemd/system/dns.service <<EOF2
|
||||
[Unit]
|
||||
Description=DNS
|
||||
After=network.target
|
||||
[Service]
|
||||
User=gbuser
|
||||
ExecStart=/opt/gbo/bin/coredns -conf /opt/gbo/conf/Corefile
|
||||
Restart=always
|
||||
StandardOutput=append:/opt/gbo/logs/stdout.log
|
||||
StandardError=append:/opt/gbo/logs/stderr.log
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF2
|
||||
|
||||
systemctl stop systemd-resolved
|
||||
systemctl disable systemd-resolved
|
||||
rm /etc/resolv.conf
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable dns
|
||||
"
|
||||
|
||||
GBUSER_UID=$(lxc exec "${PARAM_TENANT}-dns" -- id -u gbuser)
|
||||
HOST_UID=$((100000 + GBUSER_UID))
|
||||
chown -R "$HOST_UID:$HOST_UID" "$HOST_BASE"
|
||||
|
||||
lxc exec "${PARAM_TENANT}-dns" -- bash -c "
|
||||
chown -R gbuser:gbuser /opt/gbo
|
||||
|
||||
"
|
||||
|
||||
lxc config device add "${PARAM_TENANT}-dns" dnsdata disk source="$HOST_DATA" path=/opt/gbo/data
|
||||
lxc config device add "${PARAM_TENANT}-dns" dnsconf disk source="$HOST_CONF" path=/opt/gbo/conf
|
||||
lxc config device add "${PARAM_TENANT}-dns" dnslogs disk source="$HOST_LOGS" path=/opt/gbo/logs
|
||||
|
||||
lxc exec "${PARAM_TENANT}-dns" -- systemctl start dns
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
HOST_BASE="/opt/gbo/tenants/$PARAM_TENANT/doc-editor"
|
||||
|
||||
lxc launch images:debian/12 "${PARAM_TENANT}-doc-editor" \
|
||||
-c security.privileged=true \
|
||||
-c limits.cpu=2 \
|
||||
-c limits.memory=4096MB \
|
||||
|
||||
sleep 10
|
||||
|
||||
lxc exec "$PARAM_TENANT"-doc-editor -- bash -c "
|
||||
|
||||
cd /usr/share/keyrings
|
||||
wget https://collaboraoffice.com/downloads/gpg/collaboraonline-release-keyring.gpg
|
||||
|
||||
cat << EOF > /etc/apt/sources.list.d/collaboraonline.sources
|
||||
Types: deb
|
||||
URIs: https://www.collaboraoffice.com/repos/CollaboraOnline/24.04/customer-deb-$customer_hash
|
||||
Suites: ./
|
||||
Signed-By: /usr/share/keyrings/collaboraonline-release-keyring.gpg
|
||||
EOF
|
||||
|
||||
apt update && apt install coolwsd collabora-online-brand
|
||||
"
|
||||
|
||||
lxc config device remove "$PARAM_TENANT"-doc-editor doc-proxy 2>/dev/null || true
|
||||
lxc config device add "$PARAM_TENANT"-doc-editor doc-proxy proxy \
|
||||
listen=tcp:0.0.0.0:"$PARAM_DOC_PORT" \
|
||||
connect=tcp:127.0.0.1:9980
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
#!/bin/bash
|
||||
STORAGE_PATH="/opt/gbo/tenants/$PARAM_TENANT/drive/data"
|
||||
LOGS_PATH="/opt/gbo/tenants/$PARAM_TENANT/drive/logs"
|
||||
|
||||
mkdir -p "${STORAGE_PATH}" "${LOGS_PATH}"
|
||||
chmod -R 770 "${STORAGE_PATH}" "${LOGS_PATH}"
|
||||
chown -R 100999:100999 "${STORAGE_PATH}" "${LOGS_PATH}"
|
||||
|
||||
lxc launch images:debian/12 "${PARAM_TENANT}-drive" -c security.privileged=true
|
||||
sleep 15
|
||||
|
||||
lxc config device add "${PARAM_TENANT}-drive" storage disk source="${STORAGE_PATH}" path=/data
|
||||
lxc config device add "${PARAM_TENANT}-drive" logs disk source="${LOGS_PATH}" path=/var/log/minio
|
||||
|
||||
lxc exec "${PARAM_TENANT}-drive" -- bash -c '
|
||||
apt-get update && apt-get install -y wget
|
||||
wget https://dl.min.io/server/minio/release/linux-amd64/minio -O /usr/local/bin/minio
|
||||
chmod +x /usr/local/bin/minio
|
||||
|
||||
wget https://dl.min.io/client/mc/release/linux-amd64/mc -O /usr/local/bin/mc
|
||||
chmod +x /usr/local/bin/mc
|
||||
|
||||
|
||||
useradd -r -s /bin/false minio-user || true
|
||||
mkdir -p /var/log/minio /data
|
||||
chown -R minio-user:minio-user /var/log/minio /data
|
||||
|
||||
cat > /etc/systemd/system/minio.service <<EOF
|
||||
[Unit]
|
||||
Description=MinIO
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=minio-user
|
||||
Group=minio-user
|
||||
Environment="MINIO_ROOT_USER='"${PARAM_DRIVE_USER}"'"
|
||||
Environment="MINIO_ROOT_PASSWORD='"${PARAM_DRIVE_PASSWORD}"'"
|
||||
ExecStart=/usr/local/bin/minio server --address ":'"${PARAM_DRIVE_PORT}"'" --console-address ":'"${PARAM_PORT}"'" /data
|
||||
StandardOutput=append:/var/log/minio/output.log
|
||||
StandardError=append:/var/log/minio/error.log
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable minio
|
||||
systemctl start minio
|
||||
'
|
||||
|
||||
lxc config device remove "${PARAM_TENANT}-drive" minio-proxy 2>/dev/null || true
|
||||
lxc config device add "${PARAM_TENANT}-drive" minio-proxy proxy \
|
||||
listen=tcp:0.0.0.0:"${PARAM_DRIVE_API_PORT}" \
|
||||
connect=tcp:127.0.0.1:"${PARAM_DRIVE_API_PORT}"
|
||||
|
||||
lxc config device remove "${PARAM_TENANT}-drive" console-proxy 2>/dev/null || true
|
||||
lxc config device add "${PARAM_TENANT}-drive" console-proxy proxy \
|
||||
listen=tcp:0.0.0.0:"${PARAM_DRIVE_PORT}" \
|
||||
connect=tcp:127.0.0.1:"${PARAM_DRIVE_PORT}"
|
||||
|
|
@ -1,107 +0,0 @@
|
|||
#!/bin/bash
|
||||
PUBLIC_INTERFACE="eth0" # Your host's public network interface
|
||||
|
||||
# Configure firewall
|
||||
echo "[HOST] Configuring firewall..."
|
||||
sudo iptables -A FORWARD -i $PUBLIC_INTERFACE -o lxcbr0 -p tcp -m multiport --dports 25,80,110,143,465,587,993,995,4190 -j ACCEPT
|
||||
sudo iptables -A FORWARD -i lxcbr0 -o $PUBLIC_INTERFACE -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||
sudo iptables -t nat -A POSTROUTING -o $PUBLIC_INTERFACE -j MASQUERADE
|
||||
|
||||
# IPv6 firewall
|
||||
sudo ip6tables -A FORWARD -i $PUBLIC_INTERFACE -o lxcbr0 -p tcp -m multiport --dports 25,80,110,143,465,587,993,995,4190 -j ACCEPT
|
||||
sudo ip6tables -A FORWARD -i lxcbr0 -o $PUBLIC_INTERFACE -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||
|
||||
# Save iptables rules permanently (adjust based on your distro)
|
||||
if command -v iptables-persistent >/dev/null; then
|
||||
sudo iptables-save | sudo tee /etc/iptables/rules.v4
|
||||
sudo ip6tables-save | sudo tee /etc/iptables/rules.v6
|
||||
fi
|
||||
|
||||
|
||||
# ------------------------- CONTAINER SETUP -------------------------
|
||||
|
||||
# Create directory structure
|
||||
echo "[CONTAINER] Creating directories..."
|
||||
HOST_BASE="/opt/email"
|
||||
HOST_DATA="$HOST_BASE/data"
|
||||
HOST_CONF="$HOST_BASE/conf"
|
||||
HOST_LOGS="$HOST_BASE/logs"
|
||||
|
||||
sudo mkdir -p "$HOST_DATA" "$HOST_CONF" "$HOST_LOGS"
|
||||
sudo chmod -R 750 "$HOST_BASE"
|
||||
|
||||
# Launch container
|
||||
echo "[CONTAINER] Launching LXC container..."
|
||||
lxc launch images:debian/12 "$PARAM_TENANT"-email -c security.privileged=true
|
||||
sleep 15
|
||||
|
||||
echo "[CONTAINER] Installing Stalwart Mail..."
|
||||
lxc exec "$PARAM_TENANT"-email -- bash -c "
|
||||
|
||||
echo "nameserver $PARAM_DNS_INTERNAL_IP" > /etc/resolv.conf
|
||||
|
||||
apt install resolvconf -y
|
||||
apt-get update && apt-get install -y wget libcap2-bin
|
||||
wget -O /tmp/stalwart.tar.gz https://github.com/stalwartlabs/stalwart/releases/download/v0.13.1/stalwart-x86_64-unknown-linux-gnu.tar.gz
|
||||
|
||||
tar -xzf /tmp/stalwart.tar.gz -C /tmp
|
||||
mkdir -p /opt/gbo/bin
|
||||
mv /tmp/stalwart /opt/gbo/bin/stalwart
|
||||
chmod +x /opt/gbo/bin/stalwart
|
||||
sudo setcap 'cap_net_bind_service=+ep' /opt/gbo/bin/stalwart
|
||||
rm /tmp/stalwart.tar.gz
|
||||
|
||||
useradd --system --no-create-home --shell /bin/false email
|
||||
mkdir -p /opt/gbo/data /opt/gbo/conf /opt/gbo/logs
|
||||
chown -R email:email /opt/gbo/data /opt/gbo/conf /opt/gbo/logs /opt/gbo/bin
|
||||
"
|
||||
|
||||
# Set permissions
|
||||
echo "[CONTAINER] Setting permissions..."
|
||||
EMAIL_UID=$(lxc exec "$PARAM_TENANT"-email -- id -u email)
|
||||
EMAIL_GID=$(lxc exec "$PARAM_TENANT"-email -- id -g email)
|
||||
HOST_EMAIL_UID=$((100000 + EMAIL_UID))
|
||||
HOST_EMAIL_GID=$((100000 + EMAIL_GID))
|
||||
sudo chown -R "$HOST_EMAIL_UID:$HOST_EMAIL_GID" "$HOST_BASE"
|
||||
|
||||
# Mount directories
|
||||
echo "[CONTAINER] Mounting directories..."
|
||||
lxc config device add "$PARAM_TENANT"-email emaildata disk source="$HOST_DATA" path=/opt/gbo/data
|
||||
lxc config device add "$PARAM_TENANT"-email emailconf disk source="$HOST_CONF" path=/opt/gbo/conf
|
||||
lxc config device add "$PARAM_TENANT"-email emaillogs disk source="$HOST_LOGS" path=/opt/gbo/logs
|
||||
|
||||
# Create systemd service
|
||||
echo "[CONTAINER] Creating email service..."
|
||||
lxc exec "$PARAM_TENANT"-email -- bash -c "
|
||||
chown -R email:email /opt/gbo/data /opt/gbo/conf /opt/gbo/logs /opt/gbo/bin
|
||||
|
||||
cat > /etc/systemd/system/email.service <<EOF
|
||||
[Unit]
|
||||
Description=Email Service
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=email
|
||||
Group=email
|
||||
ExecStart=/opt/gbo/bin/stalwart --config /opt/gbo/conf/config.toml
|
||||
WorkingDirectory=/opt/gbo/bin
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable email
|
||||
systemctl start email
|
||||
"
|
||||
|
||||
# FIXED: IPv4 + IPv6 proxy devices
|
||||
for port in 25 80 110 143 465 587 993 995 4190; do
|
||||
lxc config device remove "$PARAM_TENANT"-email "port-$port" 2>/dev/null || true
|
||||
lxc config device add "$PARAM_TENANT"-email "port-$port" proxy \
|
||||
listen=tcp:0.0.0.0:$port \
|
||||
listen=tcp:[::]:$port \
|
||||
connect=tcp:127.0.0.1:$port
|
||||
done
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
sudo apt install sshfs -y
|
||||
lxc init
|
||||
lxc storage create default dir
|
||||
lxc profile device add default root disk path=/ pool=default
|
||||
|
||||
sudo apt update && sudo apt install -y bridge-utils
|
||||
|
||||
# Enable IP forwarding
|
||||
echo "[HOST] Enabling IP forwarding..."
|
||||
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf
|
||||
sudo sysctl -p
|
||||
|
||||
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2404/x86_64/cuda-keyring_1.1-1_all.deb
|
||||
sudo dpkg -i cuda-keyring_1.1-1_all.deb
|
||||
sudo apt-get update
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
sudo apt purge '^nvidia-*' # Clean existing drivers
|
||||
sudo add-apt-repository ppa:graphics-drivers/ppa
|
||||
sudo apt update
|
||||
sudo apt install nvidia-driver-470-server # Most stable for Kepler GPUs
|
||||
|
||||
wget https://developer.download.nvidia.com/compute/cuda/11.0.3/local_installers/cuda_11.0.3_450.51.06_linux.run
|
||||
sudo sh cuda_11.0.3_450.51.06_linux.run --override
|
||||
|
|
@ -1,89 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
HOST_BASE="/opt/gbo/tenants/$PARAM_TENANT/meeting"
|
||||
HOST_DATA="$HOST_BASE/data"
|
||||
HOST_CONF="$HOST_BASE/conf"
|
||||
HOST_LOGS="$HOST_BASE/logs"
|
||||
|
||||
mkdir -p "$HOST_DATA" "$HOST_CONF" "$HOST_LOGS"
|
||||
chmod -R 750 "$HOST_BASE"
|
||||
|
||||
lxc launch images:debian/12 "$PARAM_TENANT"-meeting -c security.privileged=true
|
||||
sleep 15
|
||||
|
||||
lxc exec "$PARAM_TENANT"-meeting -- bash -c "
|
||||
|
||||
apt-get update && apt-get install -y wget coturn
|
||||
mkdir -p /opt/gbo/bin
|
||||
cd /opt/gbo/bin
|
||||
wget -q https://github.com/livekit/livekit/releases/download/v1.8.4/livekit_1.8.4_linux_amd64.tar.gz
|
||||
tar -xzf livekit*.tar.gz
|
||||
rm livekit_1.8.4_linux_amd64.tar.gz
|
||||
chmod +x livekit-server
|
||||
|
||||
while netstat -tuln | grep -q \":$PARAM_MEETING_TURN_PORT \"; do
|
||||
((PARAM_MEETING_TURN_PORT++))
|
||||
done
|
||||
|
||||
useradd --system --no-create-home --shell /bin/false gbuser
|
||||
|
||||
"
|
||||
|
||||
MEETING_UID=$(lxc exec "$PARAM_TENANT"-meeting -- id -u gbuser)
|
||||
MEETING_GID=$(lxc exec "$PARAM_TENANT"-meeting -- id -g gbuser)
|
||||
HOST_MEETING_UID=$((100000 + MEETING_UID))
|
||||
HOST_MEETING_GID=$((100000 + MEETING_GID))
|
||||
chown -R "$HOST_MEETING_UID:$HOST_MEETING_GID" "$HOST_BASE"
|
||||
|
||||
lxc config device add "$PARAM_TENANT"-meeting meetingdata disk source="$HOST_DATA" path=/opt/gbo/data
|
||||
lxc config device add "$PARAM_TENANT"-meeting meetingconf disk source="$HOST_CONF" path=/opt/gbo/conf
|
||||
lxc config device add "$PARAM_TENANT"-meeting meetinglogs disk source="$HOST_LOGS" path=/opt/gbo/logs
|
||||
|
||||
lxc exec "$PARAM_TENANT"-meeting -- bash -c "
|
||||
|
||||
mkdir -p /opt/gbo/data /opt/gbo/conf /opt/gbo/logs
|
||||
chown -R gbuser:gbuser /opt/gbo/data /opt/gbo/conf /opt/gbo/logs
|
||||
|
||||
sudo chown gbuser:gbuser /var/run/turnserver.pid
|
||||
|
||||
|
||||
cat > /etc/systemd/system/meeting.service <<EOF
|
||||
[Unit]
|
||||
Description=LiveKit Server
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
User=gbuser
|
||||
Group=gbuser
|
||||
ExecStart=/opt/gbo/bin/livekit-server --config /opt/gbo/conf/config.yaml
|
||||
Restart=always
|
||||
Environment=TURN_PORT=$PARAM_MEETING_TURN_PORT
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
cat > /etc/systemd/system/meeting-turn.service <<EOF
|
||||
[Unit]
|
||||
Description=TURN Server
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
User=gbuser
|
||||
Group=gbuser
|
||||
ExecStart=/usr/bin/turnserver -c /opt/gbo/conf/turnserver.conf
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable meeting meeting-turn
|
||||
systemctl start meeting meeting-turn
|
||||
"
|
||||
|
||||
lxc config device remove "$PARAM_TENANT"-meeting meeting-proxy 2>/dev/null || true
|
||||
lxc config device add "$PARAM_TENANT"-meeting meeting-proxy proxy \
|
||||
listen=tcp:0.0.0.0:"$PARAM_MEETING_PORT" \
|
||||
connect=tcp:127.0.0.1:"$PARAM_MEETING_PORT"
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
#!/bin/bash
|
||||
HOST_BASE="/opt/gbo/tenants/$PARAM_TENANT/proxy"
|
||||
HOST_DATA="$HOST_BASE/data"
|
||||
HOST_CONF="$HOST_BASE/conf"
|
||||
HOST_LOGS="$HOST_BASE/logs"
|
||||
mkdir -p "$HOST_BASE" "$HOST_DATA" "$HOST_CONF" "$HOST_LOGS"
|
||||
chmod 750 "$HOST_BASE" "$HOST_DATA" "$HOST_CONF" "$HOST_LOGS"
|
||||
|
||||
lxc launch images:debian/12 "$PARAM_TENANT"-proxy -c security.privileged=true
|
||||
sleep 15
|
||||
|
||||
lxc exec "$PARAM_TENANT"-proxy -- bash -c "
|
||||
mkdir -p /opt/gbo/{bin,data,conf,logs}
|
||||
apt-get update && apt-get install -y wget libcap2-bin
|
||||
wget -q https://github.com/caddyserver/caddy/releases/download/v2.10.0-beta.3/caddy_2.10.0-beta.3_linux_amd64.tar.gz
|
||||
tar -xzf caddy_2.10.0-beta.3_linux_amd64.tar.gz -C /opt/gbo/bin
|
||||
rm caddy_2.10.0-beta.3_linux_amd64.tar.gz
|
||||
chmod 750 /opt/gbo/bin/caddy
|
||||
setcap 'cap_net_bind_service=+ep' /opt/gbo/bin/caddy
|
||||
useradd --create-home --system --shell /usr/sbin/nologin gbuser
|
||||
chown -R gbuser:gbuser /opt/gbo/{bin,data,conf,logs}
|
||||
"
|
||||
|
||||
lxc config device add "$PARAM_TENANT"-proxy data disk source="$HOST_DATA" path=/opt/gbo/data
|
||||
lxc config device add "$PARAM_TENANT"-proxy conf disk source="$HOST_CONF" path=/opt/gbo/conf
|
||||
lxc config device add "$PARAM_TENANT"-proxy logs disk source="$HOST_LOGS" path=/opt/gbo/logs
|
||||
|
||||
lxc exec "$PARAM_TENANT"-proxy -- bash -c "
|
||||
cat > /etc/systemd/system/proxy.service <<EOF
|
||||
[Unit]
|
||||
Description=Proxy
|
||||
After=network.target
|
||||
[Service]
|
||||
User=gbuser
|
||||
Group=gbuser
|
||||
Environment=XDG_DATA_HOME=/opt/gbo/data
|
||||
ExecStart=/opt/gbo/bin/caddy run --config /opt/gbo/conf/config --adapter caddyfile
|
||||
AmbientCapabilities=CAP_NET_BIND_SERVICE
|
||||
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
systemctl daemon-reload
|
||||
|
||||
chown -R gbuser:gbuser /opt/gbo/{bin,data,conf,logs}
|
||||
|
||||
systemctl enable proxy
|
||||
"
|
||||
|
||||
for port in 80 443; do
|
||||
lxc config device remove "$PARAM_TENANT"-proxy "port-$port" 2>/dev/null || true
|
||||
lxc config device add "$PARAM_TENANT"-proxy "port-$port" proxy listen=tcp:0.0.0.0:$port connect=tcp:127.0.0.1:$port
|
||||
done
|
||||
|
||||
lxc config set "$PARAM_TENANT"-proxy security.syscalls.intercept.mknod true
|
||||
lxc config set "$PARAM_TENANT"-proxy security.syscalls.intercept.setxattr true
|
||||
|
|
@ -1 +0,0 @@
|
|||
https://www.brasil247.com/mundo/meta-quer-automatizar-totalmente-publicidade-com-ia-ate-2026-diz-wsj
|
||||
|
|
@ -1,94 +0,0 @@
|
|||
#!/bin/bash
|
||||
HOST_BASE="/opt/gbo/tenants/$PARAM_TENANT/system"
|
||||
HOST_DATA="$HOST_BASE/data"
|
||||
HOST_CONF="$HOST_BASE/conf"
|
||||
HOST_LOGS="$HOST_BASE/logs"
|
||||
HOST_BIN="$HOST_BASE/bin"
|
||||
BIN_PATH="/opt/gbo/bin"
|
||||
CONTAINER_NAME="${PARAM_TENANT}-system"
|
||||
|
||||
# Create host directories
|
||||
mkdir -p "$HOST_DATA" "$HOST_CONF" "$HOST_LOGS" || exit 1
|
||||
chmod -R 750 "$HOST_BASE" || exit 1
|
||||
|
||||
|
||||
lxc launch images:debian/12 $CONTAINER_NAME -c security.privileged=true
|
||||
sleep 15
|
||||
|
||||
lxc exec $CONTAINER_NAME -- bash -c '
|
||||
|
||||
apt-get update && apt-get install -y wget curl unzip git
|
||||
|
||||
|
||||
useradd -r -s /bin/false gbuser || true
|
||||
mkdir -p /opt/gbo/logs /opt/gbo/bin /opt/gbo/data /opt/gbo/conf
|
||||
chown -R gbuser:gbuser /opt/gbo/
|
||||
|
||||
wget https://github.com/ggml-org/llama.cpp/releases/download/b6148/llama-b6148-bin-ubuntu-x64.zip
|
||||
mkdir llm
|
||||
mv llama-b6148-bin-ubuntu-x64.zip llm
|
||||
cd llm
|
||||
unzip llama-b6148-bin-ubuntu-x64.zip
|
||||
mv build/bin/* .
|
||||
rm build/bin -r
|
||||
rm llama-b6148-bin-ubuntu-x64.zip
|
||||
|
||||
sudo apt install lib-pq
|
||||
wget https://huggingface.co/bartowski/DeepSeek-R1-Distill-Qwen-1.5B-GGUF/resolve/main/DeepSeek-R1-Distill-Qwen-1.5B-Q3_K_M.gguf
|
||||
wget https://huggingface.co/CompendiumLabs/bge-small-en-v1.5-gguf/resolve/main/bge-small-en-v1.5-f32.gguf
|
||||
|
||||
sudo curl -fsSLo /usr/share/keyrings/brave-browser-beta-archive-keyring.gpg https://brave-browser-apt-beta.s3.brave.com/brave-browser-beta-archive-keyring.gpg
|
||||
sudo curl -fsSLo /etc/apt/sources.list.d/brave-browser-beta.sources https://brave-browser-apt-beta.s3.brave.com/brave-browser.sources
|
||||
sudo apt update
|
||||
|
||||
sudo apt install brave-browser-beta
|
||||
|
||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
|
||||
source "$HOME/.cargo/env"
|
||||
git clone https://alm.pragmatismo.com.br/generalbots/gbserver
|
||||
|
||||
apt install -y build-essential \
|
||||
pkg-config \
|
||||
libssl-dev \
|
||||
gcc-multilib \
|
||||
g++-multilib \
|
||||
clang \
|
||||
lld \
|
||||
binutils-dev \
|
||||
libudev-dev \
|
||||
libdbus-1-dev
|
||||
|
||||
|
||||
cat > /etc/systemd/system/system.service <<EOF
|
||||
[Unit]
|
||||
Description=General Bots System Service
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=gbuser
|
||||
Group=gbuser
|
||||
ExecStart=/opt/gbo/bin/gbserver
|
||||
StandardOutput=append:/opt/gbo/logs/output.log
|
||||
StandardError=append:/opt/gbo/logs/error.log
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable system
|
||||
systemctl start system
|
||||
'
|
||||
|
||||
lxc config device add $CONTAINER_NAME bin disk source="${HOST_BIN}" path=/opt/gbo/bin
|
||||
lxc config device add $CONTAINER_NAME data disk source="${HOST_DATA}" path=/opt/gbo/data
|
||||
lxc config device add $CONTAINER_NAME conf disk source="${HOST_CONF}" path=/opt/gbo/conf
|
||||
lxc config device add $CONTAINER_NAME logs disk source="${HOST_LOGS}" path=/opt/gbo/logs
|
||||
lxc config device add $CONTAINER_NAME system-proxy disk source="/opt/gbo/tenants/$PARAM_TENANT/proxy" path=/opt/gbo/refs/proxy
|
||||
|
||||
|
||||
lxc config device remove $CONTAINER_NAME proxy 2>/dev/null || true
|
||||
lxc config device add $CONTAINER_NAME proxy proxy \
|
||||
listen=tcp:0.0.0.0:"${PARAM_SYSTEM_PORT}" \
|
||||
connect=tcp:127.0.0.1:"${PARAM_SYSTEM_PORT}"
|
||||
|
|
@ -1,86 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Fixed container name
|
||||
CONTAINER_NAME="$PARAM_TENANT-table-editor"
|
||||
|
||||
TABLE_EDITOR_PORT="5757"
|
||||
|
||||
# Paths
|
||||
HOST_BASE="/opt/gbo/tenants/$PARAM_TENANT/table-editor"
|
||||
HOST_DATA="$HOST_BASE/data"
|
||||
HOST_CONF="$HOST_BASE/conf"
|
||||
HOST_LOGS="$HOST_BASE/logs"
|
||||
BIN_PATH="/opt/gbo/bin"
|
||||
|
||||
# Create host directories
|
||||
mkdir -p "$HOST_DATA" "$HOST_CONF" "$HOST_LOGS"
|
||||
chmod -R 750 "$HOST_BASE"
|
||||
|
||||
# Launch container
|
||||
lxc launch images:debian/12 "$CONTAINER_NAME" -c security.privileged=true
|
||||
|
||||
# Wait for container to be ready
|
||||
sleep 10
|
||||
|
||||
# Container setup
|
||||
lxc exec "$CONTAINER_NAME" -- bash -c "
|
||||
useradd --system --no-create-home --shell /bin/false gbuser
|
||||
apt-get update
|
||||
apt-get install -y wget curl
|
||||
|
||||
# Create directories
|
||||
mkdir -p \"$BIN_PATH\" /opt/gbo/data /opt/gbo/conf /opt/gbo/logs
|
||||
|
||||
# Download and install NocoDB binary
|
||||
cd \"$BIN_PATH\"
|
||||
curl http://get.nocodb.com/linux-x64 -o nocodb -L
|
||||
chmod +x nocodb
|
||||
"
|
||||
|
||||
# Set permissions
|
||||
TE_UID=$(lxc exec "$CONTAINER_NAME" -- id -u gbuser)
|
||||
TE_GID=$(lxc exec "$CONTAINER_NAME" -- id -g gbuser)
|
||||
HOST_TE_UID=$((100000 + TE_UID))
|
||||
HOST_TE_GID=$((100000 + TE_GID))
|
||||
chown -R "$HOST_TE_UID:$HOST_TE_GID" "$HOST_BASE"
|
||||
|
||||
# Add directory mappings
|
||||
lxc config device add "$CONTAINER_NAME" tedata disk source="$HOST_DATA" path=/opt/gbo/data
|
||||
lxc config device add "$CONTAINER_NAME" teconf disk source="$HOST_CONF" path=/opt/gbo/conf
|
||||
lxc config device add "$CONTAINER_NAME" telogs disk source="$HOST_LOGS" path=/opt/gbo/logs
|
||||
|
||||
|
||||
|
||||
|
||||
# Create systemd service
|
||||
lxc exec "$CONTAINER_NAME" -- bash -c "
|
||||
cat > /etc/systemd/system/table-editor.service <<EOF
|
||||
[Unit]
|
||||
Description=NocoDB Table Editor
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=gbuser
|
||||
Group=gbuser
|
||||
WorkingDirectory=$BIN_PATH
|
||||
Environment=PORT=${PARAM_TABLE_EDITOR_PORT}
|
||||
Environment=DATABASE_URL=postgres://${PARAM_TABLES_USER}:${PARAM_TABLES_PASSWORD}@${PARAM_TABLES_HOST}:${PARAM_TABLES_PORT}/${PARAM_TABLE_EDITOR_DATABASE}
|
||||
ExecStart=$BIN_PATH/nocodb
|
||||
Restart=always
|
||||
StandardOutput=append:/opt/gbo/logs/out.log
|
||||
StandardError=append:/opt/gbo/logs/err.log
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable table-editor
|
||||
systemctl start table-editor
|
||||
"
|
||||
|
||||
|
||||
|
||||
# Expose the NocoDB port
|
||||
lxc config device add "$CONTAINER_NAME" http proxy listen=tcp:0.0.0.0:$TABLE_EDITOR_PORT connect=tcp:127.0.0.1:$TABLE_EDITOR_PORT
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
|
||||
HOST_BASE="/opt/gbo/tenants/$PARAM_TENANT/tables"
|
||||
HOST_DATA="$HOST_BASE/data"
|
||||
HOST_CONF="$HOST_BASE/conf"
|
||||
HOST_LOGS="$HOST_BASE/logs"
|
||||
|
||||
mkdir -p "$HOST_DATA" "$HOST_CONF" "$HOST_LOGS"
|
||||
|
||||
lxc launch images:debian/12 "$PARAM_TENANT"-tables -c security.privileged=true
|
||||
|
||||
until lxc exec "$PARAM_TENANT"-tables -- test -f /bin/bash; do
|
||||
sleep 5
|
||||
done
|
||||
sleep 10
|
||||
|
||||
lxc exec "$PARAM_TENANT"-tables -- bash -c "
|
||||
set -e
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
apt-get update
|
||||
apt-get install -y wget gnupg2 sudo lsb-release curl
|
||||
|
||||
sudo apt install -y postgresql-common
|
||||
sudo /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh
|
||||
apt install -y postgresql
|
||||
|
||||
# TODO: Open listener on *.
|
||||
|
||||
until sudo -u postgres psql -p $PARAM_TABLES_PORT -c '\q' 2>/dev/null; do
|
||||
echo \"Waiting for PostgreSQL to start on port $PARAM_TABLES_PORT...\"
|
||||
sleep 3
|
||||
done
|
||||
|
||||
sudo -u postgres psql -p $PARAM_TABLES_PORT -c \"CREATE USER $PARAM_TENANT WITH PASSWORD '$PARAM_TABLES_PASSWORD';\"
|
||||
sudo -u postgres psql -p $PARAM_TABLES_PORT -c \"CREATE DATABASE ${PARAM_TENANT}_db OWNER $PARAM_TENANT;\"
|
||||
sudo -u postgres psql -p $PARAM_TABLES_PORT -c \"GRANT ALL PRIVILEGES ON DATABASE ${PARAM_TENANT}_db TO $PARAM_TENANT;\"
|
||||
|
||||
"
|
||||
|
||||
|
||||
lxc config device remove "$PARAM_TENANT"-tables postgres-proxy 2>/dev/null || true
|
||||
lxc config device add "$PARAM_TENANT"-tables postgres-proxy proxy \
|
||||
listen=tcp:0.0.0.0:"$PARAM_TABLES_PORT" \
|
||||
connect=tcp:127.0.0.1:"$PARAM_TABLES_PORT"
|
||||
|
||||
echo "PostgreSQL setup completed successfully!"
|
||||
echo "Database: ${PARAM_TENANT}_db"
|
||||
echo "User: $PARAM_TENANT"
|
||||
echo "Password: $PARAM_TABLES_PASSWORD"
|
||||
echo "Port: $PARAM_TABLES_PORT"
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
#!/bin/bash
|
||||
wget https://github.com/qdrant/qdrant/releases/latest/download/qdrant-x86_64-unknown-linux-gnu.tar.gz
|
||||
tar -xzf qdrant-x86_64-unknown-linux-gnu.tar.gz
|
||||
./qdrant
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
HOST_BASE="/opt/gbo/tenants/$PARAM_TENANT/webmail"
|
||||
HOST_DATA="$HOST_BASE/data"
|
||||
HOST_CONF="$HOST_BASE/conf"
|
||||
HOST_LOGS="$HOST_BASE/logs"
|
||||
|
||||
PARAM_RC_VERSION="1.6.6"
|
||||
|
||||
mkdir -p "$HOST_DATA" "$HOST_CONF" "$HOST_LOGS"
|
||||
chmod -R 750 "$HOST_BASE"
|
||||
|
||||
lxc launch images:debian/12 "$PARAM_TENANT"-webmail -c security.privileged=true
|
||||
sleep 15
|
||||
|
||||
RC_PATH="/opt/gbo/data"
|
||||
|
||||
lxc exec "$PARAM_TENANT"-webmail -- bash -c '
|
||||
# Install prerequisites
|
||||
apt install -y ca-certificates apt-transport-https lsb-release gnupg wget
|
||||
|
||||
# Add the Sury PHP repository (official for Debian)
|
||||
wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg
|
||||
sh -c '\''echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list'\''
|
||||
|
||||
# Update and install PHP 8.1
|
||||
apt update
|
||||
apt install -y \
|
||||
php8.1 \
|
||||
php8.1-fpm \
|
||||
php8.1-imap \
|
||||
php8.1-pgsql \
|
||||
php8.1-mbstring \
|
||||
php8.1-xml \
|
||||
php8.1-curl \
|
||||
php8.1-zip \
|
||||
php8.1-cli \
|
||||
php8.1-intl \
|
||||
php8.1-dom
|
||||
|
||||
# Restart PHP-FPM
|
||||
systemctl restart php8.1-fpm
|
||||
|
||||
mkdir -p '"$RC_PATH"'
|
||||
wget -q https://github.com/roundcube/roundcubemail/releases/download/'"$PARAM_RC_VERSION"'/roundcubemail-'"$PARAM_RC_VERSION"'-complete.tar.gz
|
||||
tar -xzf roundcubemail-*.tar.gz
|
||||
mv roundcubemail-'"$PARAM_RC_VERSION"'/* '"$RC_PATH"'
|
||||
rm -rf roundcubemail-*
|
||||
|
||||
mkdir -p /opt/gbo/logs
|
||||
|
||||
chmod 750 '"$RC_PATH"'
|
||||
find '"$RC_PATH"' -type d -exec chmod 750 {} \;
|
||||
find '"$RC_PATH"' -type f -exec chmod 640 {} \;
|
||||
|
||||
'
|
||||
|
||||
WEBMAIL_UID=$(lxc exec "$PARAM_TENANT"-webmail -- id -u www-data)
|
||||
WEBMAIL_GID=$(lxc exec "$PARAM_TENANT"-webmail -- id -g www-data)
|
||||
HOST_WEBMAIL_UID=$((100000 + WEBMAIL_UID))
|
||||
HOST_WEBMAIL_GID=$((100000 + WEBMAIL_GID))
|
||||
chown -R "$HOST_WEBMAIL_UID:$HOST_WEBMAIL_GID" "$HOST_BASE"
|
||||
|
||||
lxc config device add "$PARAM_TENANT"-webmail webmaildata disk source="$HOST_DATA" path="$RC_PATH"
|
||||
lxc config device add "$PARAM_TENANT"-webmail webmaillogs disk source="$HOST_LOGS" path=/opt/gbo/logs
|
||||
|
||||
lxc exec "$PARAM_TENANT"-webmail -- bash -c "
|
||||
chown -R www-data:www-data '"$RC_PATH"' /opt/gbo/logs
|
||||
cat > /etc/systemd/system/webmail.service <<EOF
|
||||
[Unit]
|
||||
Description=Roundcube Webmail
|
||||
After=network.target php8.1-fpm.service
|
||||
|
||||
[Service]
|
||||
User=www-data
|
||||
Group=www-data
|
||||
WorkingDirectory=$RC_PATH
|
||||
ExecStart=/usr/bin/php -S 0.0.0.0:$PARAM_WEBMAIL_PORT -t $RC_PATH/wwwroot/public_html
|
||||
Restart=always
|
||||
StandardOutput=append:/opt/gbo/logs/stdout.log
|
||||
StandardError=append:/opt/gbo/logs/stderr.log
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable webmail
|
||||
systemctl restart php8.1-fpm
|
||||
systemctl start webmail
|
||||
"
|
||||
|
||||
# Check if port is available before adding proxy
|
||||
if lsof -i :$PARAM_WEBMAIL_PORT >/dev/null; then
|
||||
echo "Port $PARAM_WEBMAIL_PORT is already in use. Please choose a different port."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
lxc config device remove "$PARAM_TENANT"-webmail webmail-proxy 2>/dev/null || true
|
||||
lxc config device add "$PARAM_TENANT"-webmail webmail-proxy proxy \
|
||||
listen=tcp:0.0.0.0:"$PARAM_WEBMAIL_PORT" \
|
||||
connect=tcp:127.0.0.1:"$PARAM_WEBMAIL_PORT"
|
||||
|
|
@ -1,14 +1,18 @@
|
|||
use actix_web::{web, HttpResponse, Result};
|
||||
use argon2::{
|
||||
password_hash::{rand_core::OsRng, PasswordHash, PasswordHasher, PasswordVerifier, SaltString},
|
||||
Argon2,
|
||||
};
|
||||
use diesel::pg::PgConnection;
|
||||
use diesel::prelude::*;
|
||||
use log::{error, warn};
|
||||
use redis::Client;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::shared;
|
||||
use crate::shared::state::AppState;
|
||||
|
||||
pub struct AuthService {
|
||||
pub conn: PgConnection,
|
||||
|
|
@ -141,3 +145,91 @@ impl AuthService {
|
|||
Ok(user)
|
||||
}
|
||||
}
|
||||
|
||||
#[actix_web::get("/api/auth")]
|
||||
async fn auth_handler(
|
||||
data: web::Data<AppState>,
|
||||
web::Query(params): web::Query<HashMap<String, String>>,
|
||||
) -> Result<HttpResponse> {
|
||||
let _token = params.get("token").cloned().unwrap_or_default();
|
||||
let user_id = Uuid::parse_str("00000000-0000-0000-0000-000000000000").unwrap();
|
||||
let bot_id = if let Ok(bot_guid) = std::env::var("BOT_GUID") {
|
||||
match Uuid::parse_str(&bot_guid) {
|
||||
Ok(uuid) => uuid,
|
||||
Err(e) => {
|
||||
warn!("Invalid BOT_GUID from env: {}", e);
|
||||
return Ok(HttpResponse::BadRequest()
|
||||
.json(serde_json::json!({"error": "Invalid BOT_GUID"})));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
warn!("BOT_GUID not set in environment, using nil UUID");
|
||||
Uuid::nil()
|
||||
};
|
||||
|
||||
let session = {
|
||||
let mut sm = data.session_manager.lock().await;
|
||||
match sm.get_or_create_user_session(user_id, bot_id, "Auth Session") {
|
||||
Ok(Some(s)) => s,
|
||||
Ok(None) => {
|
||||
error!("Failed to create session");
|
||||
return Ok(HttpResponse::InternalServerError()
|
||||
.json(serde_json::json!({"error": "Failed to create session"})));
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Failed to create session: {}", e);
|
||||
return Ok(HttpResponse::InternalServerError()
|
||||
.json(serde_json::json!({"error": e.to_string()})));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let session_id_clone = session.id.clone();
|
||||
let auth_script_path = "./templates/annoucements.gbai/annoucements.gbdialog/auth.bas";
|
||||
let auth_script = match std::fs::read_to_string(auth_script_path) {
|
||||
Ok(content) => content,
|
||||
Err(_) => r#"SET_USER "00000000-0000-0000-0000-000000000001""#.to_string(),
|
||||
};
|
||||
|
||||
let script_service = crate::basic::ScriptService::new(Arc::clone(&data), session.clone());
|
||||
match script_service
|
||||
.compile(&auth_script)
|
||||
.and_then(|ast| script_service.run(&ast))
|
||||
{
|
||||
Ok(result) => {
|
||||
if result.to_string() == "false" {
|
||||
error!("Auth script returned false, authentication failed");
|
||||
return Ok(HttpResponse::Unauthorized()
|
||||
.json(serde_json::json!({"error": "Authentication failed"})));
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Failed to run auth script: {}", e);
|
||||
return Ok(HttpResponse::InternalServerError()
|
||||
.json(serde_json::json!({"error": "Auth failed"})));
|
||||
}
|
||||
}
|
||||
|
||||
let session = {
|
||||
let mut sm = data.session_manager.lock().await;
|
||||
match sm.get_session_by_id(session_id_clone) {
|
||||
Ok(Some(s)) => s,
|
||||
Ok(None) => {
|
||||
error!("Failed to retrieve session");
|
||||
return Ok(HttpResponse::InternalServerError()
|
||||
.json(serde_json::json!({"error": "Failed to retrieve session"})));
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Failed to retrieve session: {}", e);
|
||||
return Ok(HttpResponse::InternalServerError()
|
||||
.json(serde_json::json!({"error": e.to_string()})));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Ok(HttpResponse::Ok().json(serde_json::json!({
|
||||
"user_id": session.user_id,
|
||||
"session_id": session.id,
|
||||
"status": "authenticated"
|
||||
})))
|
||||
}
|
||||
|
|
|
|||
343
src/bot/mod.rs
343
src/bot/mod.rs
|
|
@ -7,7 +7,6 @@ use chrono::Utc;
|
|||
use log::{debug, error, info, warn};
|
||||
use serde_json;
|
||||
use std::collections::HashMap;
|
||||
use std::fs;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::mpsc;
|
||||
use uuid::Uuid;
|
||||
|
|
@ -857,186 +856,6 @@ async fn websocket_handler(
|
|||
Ok(res)
|
||||
}
|
||||
|
||||
#[actix_web::get("/api/auth")]
|
||||
async fn auth_handler(
|
||||
data: web::Data<AppState>,
|
||||
web::Query(params): web::Query<HashMap<String, String>>,
|
||||
) -> Result<HttpResponse> {
|
||||
let _token = params.get("token").cloned().unwrap_or_default();
|
||||
let user_id = Uuid::parse_str("00000000-0000-0000-0000-000000000000").unwrap();
|
||||
let bot_id = if let Ok(bot_guid) = std::env::var("BOT_GUID") {
|
||||
match Uuid::parse_str(&bot_guid) {
|
||||
Ok(uuid) => uuid,
|
||||
Err(e) => {
|
||||
warn!("Invalid BOT_GUID from env: {}", e);
|
||||
return Ok(HttpResponse::BadRequest()
|
||||
.json(serde_json::json!({"error": "Invalid BOT_GUID"})));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
warn!("BOT_GUID not set in environment, using nil UUID");
|
||||
Uuid::nil()
|
||||
};
|
||||
|
||||
let session = {
|
||||
let mut sm = data.session_manager.lock().await;
|
||||
match sm.get_or_create_user_session(user_id, bot_id, "Auth Session") {
|
||||
Ok(Some(s)) => s,
|
||||
Ok(None) => {
|
||||
error!("Failed to create session");
|
||||
return Ok(HttpResponse::InternalServerError()
|
||||
.json(serde_json::json!({"error": "Failed to create session"})));
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Failed to create session: {}", e);
|
||||
return Ok(HttpResponse::InternalServerError()
|
||||
.json(serde_json::json!({"error": e.to_string()})));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let session_id_clone = session.id.clone();
|
||||
let auth_script_path = "./templates/annoucements.gbai/annoucements.gbdialog/auth.bas";
|
||||
let auth_script = match std::fs::read_to_string(auth_script_path) {
|
||||
Ok(content) => content,
|
||||
Err(_) => r#"SET_USER "00000000-0000-0000-0000-000000000001""#.to_string(),
|
||||
};
|
||||
|
||||
let script_service = crate::basic::ScriptService::new(Arc::clone(&data), session.clone());
|
||||
match script_service
|
||||
.compile(&auth_script)
|
||||
.and_then(|ast| script_service.run(&ast))
|
||||
{
|
||||
Ok(result) => {
|
||||
if result.to_string() == "false" {
|
||||
error!("Auth script returned false, authentication failed");
|
||||
return Ok(HttpResponse::Unauthorized()
|
||||
.json(serde_json::json!({"error": "Authentication failed"})));
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Failed to run auth script: {}", e);
|
||||
return Ok(HttpResponse::InternalServerError()
|
||||
.json(serde_json::json!({"error": "Auth failed"})));
|
||||
}
|
||||
}
|
||||
|
||||
let session = {
|
||||
let mut sm = data.session_manager.lock().await;
|
||||
match sm.get_session_by_id(session_id_clone) {
|
||||
Ok(Some(s)) => s,
|
||||
Ok(None) => {
|
||||
error!("Failed to retrieve session");
|
||||
return Ok(HttpResponse::InternalServerError()
|
||||
.json(serde_json::json!({"error": "Failed to retrieve session"})));
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Failed to retrieve session: {}", e);
|
||||
return Ok(HttpResponse::InternalServerError()
|
||||
.json(serde_json::json!({"error": e.to_string()})));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Ok(HttpResponse::Ok().json(serde_json::json!({
|
||||
"user_id": session.user_id,
|
||||
"session_id": session.id,
|
||||
"status": "authenticated"
|
||||
})))
|
||||
}
|
||||
|
||||
#[actix_web::get("/api/whatsapp/webhook")]
|
||||
async fn whatsapp_webhook_verify(
|
||||
data: web::Data<AppState>,
|
||||
web::Query(params): web::Query<HashMap<String, String>>,
|
||||
) -> Result<HttpResponse> {
|
||||
let empty = String::new();
|
||||
let mode = params.get("hub.mode").unwrap_or(&empty);
|
||||
let token = params.get("hub.verify_token").unwrap_or(&empty);
|
||||
let challenge = params.get("hub.challenge").unwrap_or(&empty);
|
||||
info!(
|
||||
"Verification params - mode: {}, token: {}, challenge: {}",
|
||||
mode, token, challenge
|
||||
);
|
||||
|
||||
match data.whatsapp_adapter.verify_webhook(mode, token, challenge) {
|
||||
Ok(challenge_response) => Ok(HttpResponse::Ok().body(challenge_response)),
|
||||
Err(_) => {
|
||||
warn!("WhatsApp webhook verification failed");
|
||||
Ok(HttpResponse::Forbidden().body("Verification failed"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[actix_web::post("/api/voice/start")]
|
||||
async fn voice_start(
|
||||
data: web::Data<AppState>,
|
||||
info: web::Json<serde_json::Value>,
|
||||
) -> Result<HttpResponse> {
|
||||
let session_id = info
|
||||
.get("session_id")
|
||||
.and_then(|s| s.as_str())
|
||||
.unwrap_or("");
|
||||
let user_id = info
|
||||
.get("user_id")
|
||||
.and_then(|u| u.as_str())
|
||||
.unwrap_or("user");
|
||||
info!(
|
||||
"Voice session start request - session: {}, user: {}",
|
||||
session_id, user_id
|
||||
);
|
||||
|
||||
match data
|
||||
.voice_adapter
|
||||
.start_voice_session(session_id, user_id)
|
||||
.await
|
||||
{
|
||||
Ok(token) => {
|
||||
info!(
|
||||
"Voice session started successfully for session {}",
|
||||
session_id
|
||||
);
|
||||
Ok(HttpResponse::Ok().json(serde_json::json!({"token": token, "status": "started"})))
|
||||
}
|
||||
Err(e) => {
|
||||
error!(
|
||||
"Failed to start voice session for session {}: {}",
|
||||
session_id, e
|
||||
);
|
||||
Ok(HttpResponse::InternalServerError()
|
||||
.json(serde_json::json!({"error": e.to_string()})))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[actix_web::post("/api/voice/stop")]
|
||||
async fn voice_stop(
|
||||
data: web::Data<AppState>,
|
||||
info: web::Json<serde_json::Value>,
|
||||
) -> Result<HttpResponse> {
|
||||
let session_id = info
|
||||
.get("session_id")
|
||||
.and_then(|s| s.as_str())
|
||||
.unwrap_or("");
|
||||
match data.voice_adapter.stop_voice_session(session_id).await {
|
||||
Ok(()) => {
|
||||
info!(
|
||||
"Voice session stopped successfully for session {}",
|
||||
session_id
|
||||
);
|
||||
Ok(HttpResponse::Ok().json(serde_json::json!({"status": "stopped"})))
|
||||
}
|
||||
Err(e) => {
|
||||
error!(
|
||||
"Failed to stop voice session for session {}: {}",
|
||||
session_id, e
|
||||
);
|
||||
Ok(HttpResponse::InternalServerError()
|
||||
.json(serde_json::json!({"error": e.to_string()})))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[actix_web::post("/api/start")]
|
||||
async fn start_session(
|
||||
data: web::Data<AppState>,
|
||||
|
|
@ -1110,130 +929,6 @@ async fn start_session(
|
|||
}
|
||||
}
|
||||
|
||||
#[actix_web::post("/api/sessions")]
|
||||
async fn create_session(data: web::Data<AppState>) -> Result<HttpResponse> {
|
||||
let user_id = Uuid::parse_str("00000000-0000-0000-0000-000000000001").unwrap();
|
||||
let bot_id = if let Ok(bot_guid) = std::env::var("BOT_GUID") {
|
||||
match Uuid::parse_str(&bot_guid) {
|
||||
Ok(uuid) => uuid,
|
||||
Err(e) => {
|
||||
warn!("Invalid BOT_GUID from env: {}", e);
|
||||
return Ok(HttpResponse::BadRequest()
|
||||
.json(serde_json::json!({"error": "Invalid BOT_GUID"})));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
warn!("BOT_GUID not set in environment, using nil UUID");
|
||||
Uuid::nil()
|
||||
};
|
||||
|
||||
let session = {
|
||||
let mut session_manager = data.session_manager.lock().await;
|
||||
match session_manager.get_or_create_user_session(user_id, bot_id, "New Conversation") {
|
||||
Ok(Some(s)) => s,
|
||||
Ok(None) => {
|
||||
error!("Failed to create session");
|
||||
return Ok(HttpResponse::InternalServerError()
|
||||
.json(serde_json::json!({"error": "Failed to create session"})));
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Failed to create session: {}", e);
|
||||
return Ok(HttpResponse::InternalServerError()
|
||||
.json(serde_json::json!({"error": e.to_string()})));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Ok(HttpResponse::Ok().json(serde_json::json!({
|
||||
"session_id": session.id,
|
||||
"title": "New Conversation",
|
||||
"created_at": Utc::now()
|
||||
})))
|
||||
}
|
||||
|
||||
#[actix_web::get("/api/sessions")]
|
||||
async fn get_sessions(data: web::Data<AppState>) -> Result<HttpResponse> {
|
||||
let user_id = Uuid::parse_str("00000000-0000-0000-0000-000000000001").unwrap();
|
||||
let orchestrator = BotOrchestrator::new(Arc::clone(&data));
|
||||
match orchestrator.get_user_sessions(user_id).await {
|
||||
Ok(sessions) => Ok(HttpResponse::Ok().json(sessions)),
|
||||
Err(e) => {
|
||||
error!("Failed to get sessions: {}", e);
|
||||
Ok(HttpResponse::InternalServerError()
|
||||
.json(serde_json::json!({"error": e.to_string()})))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[actix_web::get("/api/sessions/{session_id}")]
|
||||
async fn get_session_history(
|
||||
data: web::Data<AppState>,
|
||||
path: web::Path<String>,
|
||||
) -> Result<HttpResponse> {
|
||||
let session_id = path.into_inner();
|
||||
let user_id = Uuid::parse_str("00000000-0000-0000-0000-000000000001").unwrap();
|
||||
|
||||
match Uuid::parse_str(&session_id) {
|
||||
Ok(session_uuid) => {
|
||||
let orchestrator = BotOrchestrator::new(Arc::clone(&data));
|
||||
match orchestrator
|
||||
.get_conversation_history(session_uuid, user_id)
|
||||
.await
|
||||
{
|
||||
Ok(history) => {
|
||||
info!(
|
||||
"Retrieved {} history entries for session {}",
|
||||
history.len(),
|
||||
session_id
|
||||
);
|
||||
Ok(HttpResponse::Ok().json(history))
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Failed to get session history for {}: {}", session_id, e);
|
||||
Ok(HttpResponse::InternalServerError()
|
||||
.json(serde_json::json!({"error": e.to_string()})))
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(_) => {
|
||||
warn!("Invalid session ID format: {}", session_id);
|
||||
Ok(HttpResponse::BadRequest().json(serde_json::json!({"error": "Invalid session ID"})))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[actix_web::post("/api/set_mode")]
|
||||
async fn set_mode_handler(
|
||||
data: web::Data<AppState>,
|
||||
info: web::Json<HashMap<String, String>>,
|
||||
) -> Result<HttpResponse> {
|
||||
let default_user = "default_user".to_string();
|
||||
let default_bot = "default_bot".to_string();
|
||||
let default_mode = "0".to_string();
|
||||
let user_id = info.get("user_id").unwrap_or(&default_user);
|
||||
let bot_id = info.get("bot_id").unwrap_or(&default_bot);
|
||||
let mode_str = info.get("mode").unwrap_or(&default_mode);
|
||||
let mode = mode_str.parse::<i32>().unwrap_or(0);
|
||||
|
||||
info!(
|
||||
"Setting mode - user: {}, bot: {}, mode: {}",
|
||||
user_id, bot_id, mode
|
||||
);
|
||||
|
||||
let orchestrator = BotOrchestrator::new(Arc::clone(&data));
|
||||
if let Err(e) = orchestrator
|
||||
.set_user_answer_mode(user_id, bot_id, mode)
|
||||
.await
|
||||
{
|
||||
error!("Failed to set answer mode: {}", e);
|
||||
return Ok(
|
||||
HttpResponse::InternalServerError().json(serde_json::json!({"error": e.to_string()}))
|
||||
);
|
||||
}
|
||||
|
||||
Ok(HttpResponse::Ok().json(serde_json::json!({"status": "mode_updated"})))
|
||||
}
|
||||
|
||||
#[actix_web::post("/api/warn")]
|
||||
async fn send_warning_handler(
|
||||
data: web::Data<AppState>,
|
||||
|
|
@ -1264,41 +959,3 @@ async fn send_warning_handler(
|
|||
|
||||
Ok(HttpResponse::Ok().json(serde_json::json!({"status": "warning_sent"})))
|
||||
}
|
||||
|
||||
#[actix_web::get("/")]
|
||||
async fn index() -> Result<HttpResponse> {
|
||||
match fs::read_to_string("web/index.html") {
|
||||
Ok(html) => Ok(HttpResponse::Ok().content_type("text/html").body(html)),
|
||||
Err(e) => {
|
||||
error!("Failed to load index page: {}", e);
|
||||
Ok(HttpResponse::InternalServerError().body("Failed to load index page"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[actix_web::get("/static/{filename:.*}")]
|
||||
async fn static_files(req: HttpRequest) -> Result<HttpResponse> {
|
||||
let filename = req.match_info().query("filename");
|
||||
let path = format!("web/static/{}", filename);
|
||||
match fs::read(&path) {
|
||||
Ok(content) => {
|
||||
debug!(
|
||||
"Static file {} loaded successfully, size: {} bytes",
|
||||
filename,
|
||||
content.len()
|
||||
);
|
||||
let content_type = match filename {
|
||||
f if f.ends_with(".js") => "application/javascript",
|
||||
f if f.ends_with(".css") => "text/css",
|
||||
f if f.ends_with(".png") => "image/png",
|
||||
f if f.ends_with(".jpg") | f.ends_with(".jpeg") => "image/jpeg",
|
||||
_ => "text/plain",
|
||||
};
|
||||
Ok(HttpResponse::Ok().content_type(content_type).body(content))
|
||||
}
|
||||
Err(e) => {
|
||||
warn!("Static file not found: {} - {}", filename, e);
|
||||
Ok(HttpResponse::NotFound().body("File not found"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
14
src/main.rs
14
src/main.rs
|
|
@ -18,18 +18,17 @@ mod email;
|
|||
mod file;
|
||||
mod llm;
|
||||
mod llm_legacy;
|
||||
mod meet;
|
||||
mod org;
|
||||
mod package_manager;
|
||||
mod session;
|
||||
mod shared;
|
||||
mod tools;
|
||||
mod web_server;
|
||||
mod whatsapp;
|
||||
use crate::auth::auth_handler;
|
||||
use crate::automation::AutomationService;
|
||||
use crate::bot::{
|
||||
auth_handler, create_session, get_session_history, get_sessions, index, set_mode_handler,
|
||||
start_session, static_files, voice_start, voice_stop, websocket_handler,
|
||||
whatsapp_webhook_verify,
|
||||
};
|
||||
use crate::bot::{start_session, websocket_handler};
|
||||
use crate::channels::{VoiceAdapter, WebChannelAdapter};
|
||||
use crate::config::AppConfig;
|
||||
#[cfg(feature = "email")]
|
||||
|
|
@ -40,7 +39,11 @@ use crate::file::{init_drive, upload_file};
|
|||
use crate::llm_legacy::llm_local::{
|
||||
chat_completions_local, embeddings_local, ensure_llama_servers_running,
|
||||
};
|
||||
use crate::meet::{voice_start, voice_stop};
|
||||
use crate::session::{create_session, get_session_history, get_sessions};
|
||||
use crate::shared::state::AppState;
|
||||
use crate::web_server::{index, static_files};
|
||||
use crate::whatsapp::whatsapp_webhook_verify;
|
||||
use crate::whatsapp::WhatsAppAdapter;
|
||||
|
||||
#[actix_web::main]
|
||||
|
|
@ -269,7 +272,6 @@ async fn main() -> std::io::Result<()> {
|
|||
.service(get_sessions)
|
||||
.service(start_session)
|
||||
.service(get_session_history)
|
||||
.service(set_mode_handler)
|
||||
.service(chat_completions_local)
|
||||
.service(embeddings_local);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
use crate::bot::BotOrchestrator;
|
||||
use crate::shared::models::UserSession;
|
||||
use crate::shared::state::AppState;
|
||||
use actix_web::{web, HttpResponse, Result};
|
||||
use chrono::Utc;
|
||||
use diesel::prelude::*;
|
||||
use diesel::PgConnection;
|
||||
|
|
@ -333,3 +336,95 @@ impl SessionManager {
|
|||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[actix_web::post("/api/sessions")]
|
||||
async fn create_session(data: web::Data<AppState>) -> Result<HttpResponse> {
|
||||
let user_id = Uuid::parse_str("00000000-0000-0000-0000-000000000001").unwrap();
|
||||
let bot_id = if let Ok(bot_guid) = std::env::var("BOT_GUID") {
|
||||
match Uuid::parse_str(&bot_guid) {
|
||||
Ok(uuid) => uuid,
|
||||
Err(e) => {
|
||||
warn!("Invalid BOT_GUID from env: {}", e);
|
||||
return Ok(HttpResponse::BadRequest()
|
||||
.json(serde_json::json!({"error": "Invalid BOT_GUID"})));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
warn!("BOT_GUID not set in environment, using nil UUID");
|
||||
Uuid::nil()
|
||||
};
|
||||
|
||||
let session = {
|
||||
let mut session_manager = data.session_manager.lock().await;
|
||||
match session_manager.get_or_create_user_session(user_id, bot_id, "New Conversation") {
|
||||
Ok(Some(s)) => s,
|
||||
Ok(None) => {
|
||||
error!("Failed to create session");
|
||||
return Ok(HttpResponse::InternalServerError()
|
||||
.json(serde_json::json!({"error": "Failed to create session"})));
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Failed to create session: {}", e);
|
||||
return Ok(HttpResponse::InternalServerError()
|
||||
.json(serde_json::json!({"error": e.to_string()})));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Ok(HttpResponse::Ok().json(serde_json::json!({
|
||||
"session_id": session.id,
|
||||
"title": "New Conversation",
|
||||
"created_at": Utc::now()
|
||||
})))
|
||||
}
|
||||
|
||||
#[actix_web::get("/api/sessions")]
|
||||
async fn get_sessions(data: web::Data<AppState>) -> Result<HttpResponse> {
|
||||
let user_id = Uuid::parse_str("00000000-0000-0000-0000-000000000001").unwrap();
|
||||
let orchestrator = BotOrchestrator::new(Arc::clone(&data));
|
||||
match orchestrator.get_user_sessions(user_id).await {
|
||||
Ok(sessions) => Ok(HttpResponse::Ok().json(sessions)),
|
||||
Err(e) => {
|
||||
error!("Failed to get sessions: {}", e);
|
||||
Ok(HttpResponse::InternalServerError()
|
||||
.json(serde_json::json!({"error": e.to_string()})))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[actix_web::get("/api/sessions/{session_id}")]
|
||||
async fn get_session_history(
|
||||
data: web::Data<AppState>,
|
||||
path: web::Path<String>,
|
||||
) -> Result<HttpResponse> {
|
||||
let session_id = path.into_inner();
|
||||
let user_id = Uuid::parse_str("00000000-0000-0000-0000-000000000001").unwrap();
|
||||
|
||||
match Uuid::parse_str(&session_id) {
|
||||
Ok(session_uuid) => {
|
||||
let orchestrator = BotOrchestrator::new(Arc::clone(&data));
|
||||
match orchestrator
|
||||
.get_conversation_history(session_uuid, user_id)
|
||||
.await
|
||||
{
|
||||
Ok(history) => {
|
||||
info!(
|
||||
"Retrieved {} history entries for session {}",
|
||||
history.len(),
|
||||
session_id
|
||||
);
|
||||
Ok(HttpResponse::Ok().json(history))
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Failed to get session history for {}: {}", session_id, e);
|
||||
Ok(HttpResponse::InternalServerError()
|
||||
.json(serde_json::json!({"error": e.to_string()})))
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(_) => {
|
||||
warn!("Invalid session ID format: {}", session_id);
|
||||
Ok(HttpResponse::BadRequest().json(serde_json::json!({"error": "Invalid session ID"})))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use actix_web::{web, HttpResponse, Result};
|
||||
use async_trait::async_trait;
|
||||
use log::info;
|
||||
use log::{info, warn};
|
||||
use reqwest::Client;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
|
|
@ -7,6 +8,7 @@ use std::sync::Arc;
|
|||
use tokio::sync::Mutex;
|
||||
|
||||
use crate::shared::models::BotResponse;
|
||||
use crate::shared::state::AppState;
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct WhatsAppMessage {
|
||||
|
|
@ -198,3 +200,26 @@ impl crate::channels::ChannelAdapter for WhatsAppAdapter {
|
|||
.await
|
||||
}
|
||||
}
|
||||
|
||||
#[actix_web::get("/api/whatsapp/webhook")]
|
||||
async fn whatsapp_webhook_verify(
|
||||
data: web::Data<AppState>,
|
||||
web::Query(params): web::Query<HashMap<String, String>>,
|
||||
) -> Result<HttpResponse> {
|
||||
let empty = String::new();
|
||||
let mode = params.get("hub.mode").unwrap_or(&empty);
|
||||
let token = params.get("hub.verify_token").unwrap_or(&empty);
|
||||
let challenge = params.get("hub.challenge").unwrap_or(&empty);
|
||||
info!(
|
||||
"Verification params - mode: {}, token: {}, challenge: {}",
|
||||
mode, token, challenge
|
||||
);
|
||||
|
||||
match data.whatsapp_adapter.verify_webhook(mode, token, challenge) {
|
||||
Ok(challenge_response) => Ok(HttpResponse::Ok().body(challenge_response)),
|
||||
Err(_) => {
|
||||
warn!("WhatsApp webhook verification failed");
|
||||
Ok(HttpResponse::Forbidden().body("Verification failed"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,4 +4,4 @@ TALK resume
|
|||
|
||||
let text = GET "default.gbdrive/default.pdf"
|
||||
SET_CONTEXT "Este é o documento que você deve usar para responder dúvidas: " + text
|
||||
TALK "Olá, pode me perguntar sobre qualquer coisa desta circular..."
|
||||
TALK "Olá, pode me perguntar sobre qualquer coisa destas circulares..."
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue