#!/bin/sh
# One-time fleet provisioning on the VPS. Run as root from /opt/ardegazu-__NAME__
# after the code is in place (rsync or git pull) and `npm install` has run.
#
# sh deploy/install-fleet.sh # a fleet of one: __NAME__
# sh deploy/install-fleet.sh __NAME__ alta treia # a bigger fleet
#
# Creates the shared user, per-instance state dirs and seeds, cross-links the
# sibling friend links into every config, installs the units, and starts the
# fleet staggered. Existing seeds are kept — they ARE the bots' identities.
set -eu
BOTS="${*:-__NAME__}"
STATE=/var/lib/ardegazu-__NAME__
ETC=/etc/ardegazu-__NAME__
OPT=/opt/ardegazu-__NAME__
id ardegazu-__NAME__ >/dev/null 2>&1 || useradd -r -s /usr/sbin/nologin ardegazu-__NAME__
mkdir -p "$ETC" "$STATE/models"
# seeds + friend links (link.js creates a missing seed, keeps an existing one)
LINKS=""
for b in $BOTS; do
mkdir -p "$STATE/$b"
link=$(node "$OPT/dist/fleet/link.js" "$STATE/$b/seed" "$b")
echo "$b: $link"
LINKS="$LINKS $b=$link"
done
# the matchmaker needs partners: enable it only for a fleet of two or more
# (games stays [] until a learned/hostable game is added — see the docs)
N=0
for b in $BOTS; do N=$((N + 1)); done
MM=false
[ "$N" -ge 2 ] && MM=true
# per-instance configs: every bot lists the other bots' links as siblings
for b in $BOTS; do
sibs=""
for kv in $LINKS; do
n=${kv%%=*}; l=${kv#*=}
[ "$n" = "$b" ] && continue
frag="#${l#*#}"
sibs="$sibs\"$frag\","
done
sibs=${sibs%,}
cat > "$ETC/$b.json" << EOF
{
"name": "$b",
"dataDir": "$STATE/$b",
"origin": "https://chat.ardegazu.ro",
"social": { "enabled": true, "autoAcceptFriends": true, "autoJoinInvites": true },
"rooms": [],
"fleet": {
"siblings": [$sibs],
"matchmaker": { "enabled": $MM, "games": [], "maxConcurrentSelfPlay": 1, "partners": 4 }
},
"learning": { "modelDir": "$STATE/models" }
}
EOF
done
cp "$OPT/deploy/ardegazu-__NAME__@.service" /etc/systemd/system/
# trainer units ship only while the bot learns (dropping RL deletes them)
TRAINER=false
if [ -f "$OPT/deploy/ardegazu-__NAME__-trainer.service" ]; then
TRAINER=true
cp "$OPT/deploy/ardegazu-__NAME__-trainer.service" /etc/systemd/system/
cp "$OPT/deploy/ardegazu-__NAME__-trainer.timer" /etc/systemd/system/
[ -f "$ETC/trainer.json" ] || cat > "$ETC/trainer.json" << EOF
{
"modelDir": "$STATE/models",
"episodeDirs": ["$STATE/*/episodes"]
}
EOF
fi
chown -R ardegazu-__NAME__:ardegazu-__NAME__ "$STATE"
chmod 0775 "$STATE/models"
systemctl daemon-reload
for b in $BOTS; do
systemctl enable --now "ardegazu-__NAME__@$b"
echo "started ardegazu-__NAME__@$b"
sleep 20
done
[ "$TRAINER" = true ] && systemctl enable --now ardegazu-__NAME__-trainer.timer
echo "fleet up — journalctl -u 'ardegazu-__NAME__@*' -f"