mirror of
https://github.com/ManfredAabye/opensimMULTITOOLS-II.git
synced 2026-08-14 08:52:24 +00:00
1198 lines
37 KiB
Bash
1198 lines
37 KiB
Bash
#!/usr/bin/env bash
|
||
set -euo pipefail
|
||
|
||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||
# shellcheck source=/dev/null
|
||
source "$SCRIPT_DIR/osmtool_core.sh"
|
||
|
||
usage() {
|
||
cat <<'EOF'
|
||
Usage:
|
||
osmtool_install.sh [--workdir <path>] --action <init-config|server-check|prepare-ubuntu|install-opensim-deps|install-dotnet8|install-opensim|configure-opensim|configure-database|compile-janus|configure-janus|install-janus>
|
||
[--opensim-dir <path>] [--opensim-repo <url>] [--opensim-branch <name>] [--repo-mode <update|fresh>]
|
||
[--tsassets-dir <path>] [--currency-dir <path>] [--data-backup-dir <path>]
|
||
[--deploy-binaries <true|false>] [--legacy-patch-dir <path>]
|
||
[--db-root-user <name>] [--db-root-pass <value>] [--db-user <name>] [--db-pass <value>]
|
||
[--janus-prefix <path>] [--janus-src <path>] [--public-host <host>] [--http-port <port>]
|
||
[--admin-port <port>] [--rtp-range <from-to>] [--enable-admin <true|false>]
|
||
[--api-secret <value>] [--admin-secret <value>]
|
||
|
||
Actions:
|
||
init-config Create/update shared osmtool configuration interactively
|
||
server-check Validate server readiness and required dependencies
|
||
prepare-ubuntu Basic apt update/upgrade and base packages
|
||
install-opensim-deps Install OpenSim runtime dependencies
|
||
install-dotnet8 Install .NET SDK 8.0 for OpenSim build/runtime
|
||
install-opensim Clone/update, enrich, build and optionally deploy OpenSim
|
||
configure-opensim Generate required runtime ini files from example templates
|
||
configure-database Create MariaDB databases/users/grants for robust and sim* runtimes
|
||
compile-janus Build and install Janus Gateway
|
||
configure-janus Configure Janus for OpenSim usage
|
||
install-janus Compile + configure Janus in one run
|
||
|
||
Examples:
|
||
osmtool_install.sh --action server-check --workdir /opt
|
||
osmtool_install.sh --action configure-opensim --profile grid-sim --workdir /opt
|
||
osmtool_install.sh --action configure-database --workdir /opt --db-user opensim --db-pass secret
|
||
EOF
|
||
print_usage_common
|
||
}
|
||
|
||
has_dotnet8_sdk() {
|
||
if ! command -v dotnet >/dev/null 2>&1; then
|
||
return 1
|
||
fi
|
||
|
||
dotnet --list-sdks 2>/dev/null | awk '{print $1}' | grep -Eq '^8\.'
|
||
}
|
||
|
||
package_available_in_apt() {
|
||
local pkg="$1"
|
||
apt-cache show "$pkg" >/dev/null 2>&1
|
||
}
|
||
|
||
resolve_package_token() {
|
||
local token="$1"
|
||
local candidate
|
||
local IFS='|'
|
||
read -r -a candidates <<< "$token"
|
||
|
||
for candidate in "${candidates[@]}"; do
|
||
if dpkg -s "$candidate" >/dev/null 2>&1; then
|
||
echo "$candidate"
|
||
return 0
|
||
fi
|
||
done
|
||
|
||
for candidate in "${candidates[@]}"; do
|
||
if package_available_in_apt "$candidate"; then
|
||
echo "$candidate"
|
||
return 0
|
||
fi
|
||
done
|
||
|
||
return 1
|
||
}
|
||
|
||
ensure_user_writable_dir() {
|
||
local dir="$1"
|
||
|
||
if mkdir -p "$dir" 2>/dev/null; then
|
||
return 0
|
||
fi
|
||
|
||
sudo mkdir -p "$dir"
|
||
sudo chown "$(id -u):$(id -g)" "$dir"
|
||
}
|
||
|
||
ensure_user_owns_path() {
|
||
local path="$1"
|
||
|
||
if [[ -e "$path" && ! -w "$path" ]]; then
|
||
sudo chown -R "$(id -u):$(id -g)" "$path"
|
||
fi
|
||
}
|
||
|
||
sync_git_repo() {
|
||
local repo_url="$1"
|
||
local repo_dir="$2"
|
||
local branch="$3"
|
||
local repo_mode="$4"
|
||
local parent_dir
|
||
local active_branch
|
||
|
||
parent_dir="$(dirname "$repo_dir")"
|
||
if [[ ! -d "$parent_dir" ]]; then
|
||
ensure_user_writable_dir "$parent_dir"
|
||
fi
|
||
|
||
if [[ "$repo_mode" == "fresh" && -e "$repo_dir" ]]; then
|
||
log INFO "Removing existing repository for fresh checkout: $repo_dir"
|
||
rm -rf "$repo_dir" 2>/dev/null || sudo rm -rf "$repo_dir"
|
||
fi
|
||
|
||
if [[ -d "$repo_dir/.git" ]]; then
|
||
ensure_user_owns_path "$repo_dir"
|
||
log INFO "Updating repository: $repo_dir"
|
||
git -C "$repo_dir" fetch --all --prune
|
||
active_branch="$branch"
|
||
if [[ -z "$active_branch" ]]; then
|
||
active_branch="$(git -C "$repo_dir" branch --show-current)"
|
||
fi
|
||
if [[ -z "$active_branch" ]]; then
|
||
active_branch="$(git -C "$repo_dir" symbolic-ref --quiet --short refs/remotes/origin/HEAD 2>/dev/null | sed 's|^origin/||')"
|
||
fi
|
||
if [[ -n "$active_branch" ]]; then
|
||
git -C "$repo_dir" checkout "$active_branch"
|
||
git -C "$repo_dir" pull --ff-only origin "$active_branch"
|
||
else
|
||
git -C "$repo_dir" pull --ff-only
|
||
fi
|
||
return 0
|
||
fi
|
||
|
||
if [[ -d "$repo_dir" && -z "$(ls -A "$repo_dir" 2>/dev/null)" ]]; then
|
||
rmdir "$repo_dir" 2>/dev/null || sudo rmdir "$repo_dir"
|
||
fi
|
||
|
||
if [[ -e "$repo_dir" ]]; then
|
||
die "Path exists but is not a git repository: $repo_dir"
|
||
fi
|
||
|
||
if [[ ! -w "$parent_dir" ]]; then
|
||
sudo mkdir -p "$repo_dir"
|
||
sudo chown "$(id -u):$(id -g)" "$repo_dir"
|
||
fi
|
||
|
||
log INFO "Cloning repository $repo_url -> $repo_dir"
|
||
if [[ -n "$branch" ]]; then
|
||
git clone --branch "$branch" --single-branch "$repo_url" "$repo_dir"
|
||
else
|
||
git clone "$repo_url" "$repo_dir"
|
||
fi
|
||
}
|
||
|
||
sync_support_repo() {
|
||
local repo_name="$1"
|
||
local repo_url="$2"
|
||
local repo_dir="$3"
|
||
|
||
log INFO "Preparing support repository: $repo_name"
|
||
sync_git_repo "$repo_url" "$repo_dir" "" "$REPO_MODE"
|
||
}
|
||
|
||
copy_tree_contents() {
|
||
local src_dir="$1"
|
||
local dst_dir="$2"
|
||
local label="$3"
|
||
|
||
if [[ ! -d "$src_dir" ]]; then
|
||
log INFO "Skipping missing source for $label: $src_dir"
|
||
return 0
|
||
fi
|
||
|
||
mkdir -p "$dst_dir"
|
||
# Exclude .git to avoid permission issues on repeated runs
|
||
if command -v rsync >/dev/null 2>&1; then
|
||
rsync -a --exclude='.git' "$src_dir/" "$dst_dir/"
|
||
else
|
||
find "$src_dir" -maxdepth 1 -mindepth 1 ! -name '.git' \
|
||
-exec cp -a {} "$dst_dir/" \;
|
||
fi
|
||
log INFO "Copied $label: $src_dir -> $dst_dir"
|
||
}
|
||
|
||
apply_legacy_patches() {
|
||
local patch_dir="$1"
|
||
local patch_file
|
||
|
||
[[ -n "$patch_dir" ]] || return 0
|
||
|
||
if [[ ! -d "$patch_dir" ]]; then
|
||
die "Legacy patch directory not found: $patch_dir"
|
||
fi
|
||
|
||
shopt -s nullglob
|
||
local patches=("$patch_dir"/*.patch)
|
||
shopt -u nullglob
|
||
|
||
if [[ ${#patches[@]} -eq 0 ]]; then
|
||
log INFO "No legacy patches found in $patch_dir"
|
||
return 0
|
||
fi
|
||
|
||
for patch_file in "${patches[@]}"; do
|
||
if git -C "$OPENSIM_DIR" apply --reverse --check "$patch_file" >/dev/null 2>&1; then
|
||
log INFO "Legacy patch already applied: $(basename "$patch_file")"
|
||
continue
|
||
fi
|
||
|
||
log INFO "Applying legacy patch: $(basename "$patch_file")"
|
||
if ! git -C "$OPENSIM_DIR" apply "$patch_file"; then
|
||
git -C "$OPENSIM_DIR" apply --ignore-space-change --ignore-whitespace "$patch_file" \
|
||
|| die "Failed to apply legacy patch: $patch_file"
|
||
fi
|
||
done
|
||
}
|
||
|
||
deploy_opensim_binaries() {
|
||
local src_bin="$OPENSIM_DIR/bin"
|
||
local deployed=0
|
||
local sim_dir
|
||
|
||
[[ -d "$src_bin" ]] || die "OpenSim build output missing: $src_bin"
|
||
|
||
if [[ -d "$WORKDIR/robust/bin" ]]; then
|
||
copy_tree_contents "$src_bin" "$WORKDIR/robust/bin" "robust binaries"
|
||
deployed=1
|
||
fi
|
||
|
||
if [[ -d "$WORKDIR/standalone/bin" ]]; then
|
||
copy_tree_contents "$src_bin" "$WORKDIR/standalone/bin" "standalone binaries"
|
||
deployed=1
|
||
fi
|
||
|
||
shopt -s nullglob
|
||
for sim_dir in "$WORKDIR"/sim*; do
|
||
if [[ -d "$sim_dir/bin" ]]; then
|
||
copy_tree_contents "$src_bin" "$sim_dir/bin" "region binaries"
|
||
deployed=1
|
||
fi
|
||
done
|
||
shopt -u nullglob
|
||
|
||
if [[ "$deployed" -eq 0 ]]; then
|
||
log INFO "No target runtime directories found for binary deployment under $WORKDIR"
|
||
else
|
||
log INFO "OpenSim binaries deployed to available runtime directories"
|
||
fi
|
||
}
|
||
|
||
install_dotnet8() {
|
||
need_cmd apt-get
|
||
need_cmd sudo
|
||
need_cmd wget
|
||
|
||
if has_dotnet8_sdk; then
|
||
log INFO "dotnet SDK 8.x already installed"
|
||
return 0
|
||
fi
|
||
|
||
log INFO "Installing .NET SDK 8.0"
|
||
sudo apt-get update
|
||
sudo apt-get install -y apt-transport-https ca-certificates gnupg
|
||
|
||
if ! apt-cache policy dotnet-sdk-8.0 | grep -q "Candidate:"; then
|
||
local version_id pkg_url pkg_file
|
||
version_id="$(awk -F= '/^VERSION_ID=/{gsub(/\"/,"",$2); print $2; exit}' /etc/os-release 2>/dev/null || true)"
|
||
[[ -n "$version_id" ]] || die "Could not detect VERSION_ID from /etc/os-release"
|
||
pkg_url="https://packages.microsoft.com/config/ubuntu/${version_id}/packages-microsoft-prod.deb"
|
||
pkg_file="/tmp/packages-microsoft-prod.deb"
|
||
|
||
# Ubuntu 26.04: Microsoft bietet noch kein eigenes Repo an; 24.04 (noble) ist kompatibel
|
||
if [[ "$version_id" == "26.04" ]]; then
|
||
log INFO "Ubuntu 26.04 erkannt – verwende Microsoft-Repo fuer Ubuntu 24.04 (noble)"
|
||
pkg_url="https://packages.microsoft.com/config/ubuntu/24.04/packages-microsoft-prod.deb"
|
||
fi
|
||
|
||
log INFO "Adding Microsoft package repository for Ubuntu ${version_id}"
|
||
wget -q -O "$pkg_file" "$pkg_url"
|
||
sudo dpkg -i "$pkg_file"
|
||
rm -f "$pkg_file"
|
||
sudo apt-get update
|
||
fi
|
||
|
||
sudo apt-get install -y dotnet-sdk-8.0
|
||
|
||
if has_dotnet8_sdk; then
|
||
log INFO "dotnet SDK 8.x installed successfully"
|
||
return 0
|
||
fi
|
||
|
||
die "dotnet SDK 8.x installation failed"
|
||
}
|
||
|
||
install_opensim_deps() {
|
||
local tokens=(
|
||
git zip screen libgdiplus zlib1g libunwind8 libgssapi-krb5-2 libstdc++6
|
||
"mariadb-client|default-mysql-client|mysql-client"
|
||
"mariadb-server|mysql-server"
|
||
"libgcc-s1|libgcc1"
|
||
"libssl3|libssl1.1"
|
||
"libicu74|libicu72|libicu71|libicu70|libicu67"
|
||
"liblttng-ust1|liblttng-ust0"
|
||
)
|
||
local to_install=()
|
||
local token resolved
|
||
|
||
need_cmd apt-get
|
||
need_cmd sudo
|
||
|
||
for token in "${tokens[@]}"; do
|
||
if resolve_package_token "$token" >/dev/null 2>&1; then
|
||
resolved="$(resolve_package_token "$token")"
|
||
if ! dpkg -s "$resolved" >/dev/null 2>&1; then
|
||
to_install+=("$resolved")
|
||
fi
|
||
else
|
||
die "No installable package found for token: $token"
|
||
fi
|
||
done
|
||
|
||
if [[ ${#to_install[@]} -eq 0 ]]; then
|
||
log INFO "OpenSim runtime dependencies already installed"
|
||
return 0
|
||
fi
|
||
|
||
log INFO "Installing OpenSim dependencies: ${to_install[*]}"
|
||
sudo apt-get update
|
||
sudo apt-get install -y "${to_install[@]}"
|
||
}
|
||
|
||
ensure_mariadb_service() {
|
||
need_cmd sudo
|
||
|
||
if ! command -v mariadb >/dev/null 2>&1; then
|
||
die "MariaDB client not found after dependency install"
|
||
fi
|
||
|
||
if command -v systemctl >/dev/null 2>&1; then
|
||
if systemctl list-unit-files 2>/dev/null | grep -q '^mariadb\.service'; then
|
||
log INFO "Ensuring mariadb.service is enabled and running"
|
||
sudo systemctl enable --now mariadb
|
||
if ! systemctl is-active --quiet mariadb; then
|
||
die "MariaDB service could not be started"
|
||
fi
|
||
return 0
|
||
fi
|
||
fi
|
||
|
||
if command -v service >/dev/null 2>&1; then
|
||
if service --status-all 2>/dev/null | grep -q mariadb; then
|
||
log INFO "Ensuring MariaDB service is running"
|
||
sudo service mariadb start
|
||
return 0
|
||
fi
|
||
fi
|
||
|
||
log INFO "No controllable MariaDB service unit detected; skipping service activation"
|
||
}
|
||
|
||
copy_ini_if_missing() {
|
||
local bin_dir="$1"
|
||
local src_name="$2"
|
||
local dst_name="$3"
|
||
local src dst
|
||
|
||
src="$bin_dir/$src_name"
|
||
dst="$bin_dir/$dst_name"
|
||
|
||
[[ -d "$bin_dir" ]] || return 0
|
||
|
||
if [[ -f "$dst" ]]; then
|
||
log INFO "Keeping existing config: $dst"
|
||
return 0
|
||
fi
|
||
|
||
if [[ -f "$src" ]]; then
|
||
cp -a "$src" "$dst"
|
||
log INFO "Created config from template: $dst"
|
||
else
|
||
log INFO "Template not found, skipping: $src"
|
||
fi
|
||
}
|
||
|
||
copy_example_if_missing() {
|
||
local bin_dir="$1"
|
||
local base_name="$2"
|
||
copy_ini_if_missing "$bin_dir" "${base_name}.example" "$base_name"
|
||
}
|
||
|
||
set_ini_key_value() {
|
||
local file="$1"
|
||
local key="$2"
|
||
local value="$3"
|
||
local escaped
|
||
|
||
[[ -f "$file" ]] || return 0
|
||
escaped="${value//\\/\\\\}"
|
||
escaped="${escaped//&/\\&}"
|
||
sed -i -E "s|^([[:space:]]*${key}[[:space:]]*=[[:space:]]*).*$|\\1\"${escaped}\"|" "$file"
|
||
}
|
||
|
||
set_architecture_include() {
|
||
local file="$1"
|
||
local include_value="$2"
|
||
|
||
[[ -f "$file" ]] || return 0
|
||
|
||
if grep -qE '^[[:space:]]*Include-Architecture[[:space:]]*=' "$file"; then
|
||
sed -i -E "s|^([[:space:]]*Include-Architecture[[:space:]]*=[[:space:]]*).*$|\\1\"${include_value}\"|" "$file"
|
||
else
|
||
{
|
||
echo ""
|
||
echo "[Architecture]"
|
||
echo "Include-Architecture = \"${include_value}\""
|
||
} >> "$file"
|
||
fi
|
||
}
|
||
|
||
read_userinfo_credential() {
|
||
local file="$1"
|
||
local key="$2"
|
||
|
||
[[ -f "$file" ]] || return 1
|
||
awk -F '=' -v key="$key" '
|
||
$1 ~ "^[[:space:]]*" key "[[:space:]]*$" {
|
||
sub(/^[[:space:]]+/, "", $2)
|
||
sub(/[[:space:]]+$/, "", $2)
|
||
print $2
|
||
exit
|
||
}
|
||
' "$file"
|
||
}
|
||
|
||
configure_opensim_runtime() {
|
||
local sim_dir cfg_user cfg_pass userinfo_file sim_arch
|
||
|
||
log INFO "Configuring OpenSim runtime ini files"
|
||
|
||
copy_ini_if_missing "$WORKDIR/robust/bin" "Robust.HG.ini.example" "Robust.ini"
|
||
copy_ini_if_missing "$WORKDIR/robust/bin" "Robust.ini.example" "Robust.ini"
|
||
copy_ini_if_missing "$WORKDIR/robust/bin" "MoneyServer.ini.example" "MoneyServer.ini"
|
||
copy_example_if_missing "$WORKDIR/robust/bin/config-include" "GridCommon.ini"
|
||
copy_example_if_missing "$WORKDIR/robust/bin/config-include" "osslEnable.ini"
|
||
|
||
copy_ini_if_missing "$WORKDIR/standalone/bin" "OpenSim.ini.example" "OpenSim.ini"
|
||
copy_example_if_missing "$WORKDIR/standalone/bin/config-include" "StandaloneCommon.ini"
|
||
copy_example_if_missing "$WORKDIR/standalone/bin/config-include" "osslEnable.ini"
|
||
|
||
sim_arch="config-include/Grid.ini"
|
||
if [[ "$PROFILE" == "standalone" ]]; then
|
||
sim_arch="config-include/Standalone.ini"
|
||
fi
|
||
|
||
shopt -s nullglob
|
||
for sim_dir in "$WORKDIR"/sim*/bin; do
|
||
copy_ini_if_missing "$sim_dir" "OpenSim.ini.example" "OpenSim.ini"
|
||
copy_example_if_missing "$sim_dir/config-include" "GridCommon.ini"
|
||
copy_example_if_missing "$sim_dir/config-include" "osslEnable.ini"
|
||
set_architecture_include "$sim_dir/OpenSim.ini" "$sim_arch"
|
||
done
|
||
shopt -u nullglob
|
||
|
||
cfg_user="$DB_USER"
|
||
cfg_pass="$DB_PASS"
|
||
userinfo_file="$WORKDIR/UserInfo.ini"
|
||
|
||
if [[ -z "$cfg_user" ]]; then
|
||
cfg_user="$(read_userinfo_credential "$userinfo_file" "DB_Benutzername" || true)"
|
||
fi
|
||
if [[ -z "$cfg_pass" ]]; then
|
||
cfg_pass="$(read_userinfo_credential "$userinfo_file" "DB_Passwort" || true)"
|
||
fi
|
||
|
||
if [[ -n "$cfg_user" && -n "$cfg_pass" ]]; then
|
||
local db_conn_robust db_conn_sim sim_name_inner
|
||
|
||
# MoneyServer Credentials
|
||
set_ini_key_value "$WORKDIR/robust/bin/MoneyServer.ini" "username" "$cfg_user"
|
||
set_ini_key_value "$WORKDIR/robust/bin/MoneyServer.ini" "password" "$cfg_pass"
|
||
|
||
# Robust.ini ConnectionString (zwingend erforderlich für Datenbankverbindung)
|
||
db_conn_robust="Data Source=localhost;Database=robust;User ID=${cfg_user};Password=${cfg_pass};Old Guids=true;"
|
||
if [[ -f "$WORKDIR/robust/bin/Robust.ini" ]]; then
|
||
upsert_key "$WORKDIR/robust/bin/Robust.ini" "ConnectionString" "\"${db_conn_robust}\""
|
||
fi
|
||
|
||
# Jede simX/bin/OpenSim.ini ConnectionString (zwingend, sonst startet sim nicht)
|
||
shopt -s nullglob
|
||
for sim_dir in "$WORKDIR"/sim[0-9]*/bin; do
|
||
sim_name_inner="$(basename "$(dirname "$sim_dir")")"
|
||
[[ "$sim_name_inner" =~ ^sim[0-9]+$ ]] || continue
|
||
[[ -f "$sim_dir/OpenSim.ini" ]] || continue
|
||
db_conn_sim="Data Source=localhost;Database=${sim_name_inner};User ID=${cfg_user};Password=${cfg_pass};Old Guids=true;"
|
||
upsert_key "$sim_dir/OpenSim.ini" "ConnectionString" "\"${db_conn_sim}\""
|
||
done
|
||
shopt -u nullglob
|
||
|
||
log INFO "Updated ConnectionStrings in Robust.ini, MoneyServer.ini und simX/OpenSim.ini"
|
||
else
|
||
log INFO "Keine DB-Credentials verfügbar — ConnectionString nicht gesetzt. Erst configure-database ausführen."
|
||
fi
|
||
|
||
# Hostname/IP in alle Konfigurationsdateien einsetzen (YOURHOST ersetzen)
|
||
if [[ -n "$PUBLIC_HOST" && "$PUBLIC_HOST" != "127.0.0.1" ]]; then
|
||
local h_escaped
|
||
h_escaped="$(printf '%s' "$PUBLIC_HOST" | sed 's/[\/&]/\\&/g')"
|
||
local cfg_f
|
||
for cfg_f in \
|
||
"$WORKDIR/robust/bin/Robust.ini" \
|
||
"$WORKDIR/robust/bin/config-include/GridCommon.ini" \
|
||
"$WORKDIR/standalone/bin/config-include/StandaloneCommon.ini"; do
|
||
[[ -f "$cfg_f" ]] || continue
|
||
sed -i "s|YOURHOST|${h_escaped}|g" "$cfg_f"
|
||
done
|
||
shopt -s nullglob
|
||
for sim_dir in "$WORKDIR"/sim[0-9]*/bin; do
|
||
for cfg_f in "$sim_dir/OpenSim.ini" "$sim_dir/config-include/GridCommon.ini"; do
|
||
[[ -f "$cfg_f" ]] || continue
|
||
sed -i "s|YOURHOST|${h_escaped}|g" "$cfg_f"
|
||
done
|
||
done
|
||
shopt -u nullglob
|
||
log INFO "Hostname ($PUBLIC_HOST) in Konfigurationsdateien eingesetzt"
|
||
fi
|
||
|
||
# Gridname in Konfigurationsdateien setzen
|
||
if [[ -n "$GRIDNAME" ]]; then
|
||
local cfg_f
|
||
for cfg_f in \
|
||
"$WORKDIR/robust/bin/Robust.ini" \
|
||
"$WORKDIR/robust/bin/config-include/GridCommon.ini" \
|
||
"$WORKDIR/standalone/bin/config-include/StandaloneCommon.ini"; do
|
||
[[ -f "$cfg_f" ]] || continue
|
||
upsert_key "$cfg_f" "GridName" "\"${GRIDNAME}\""
|
||
upsert_key "$cfg_f" "WelcomeMessage" "\"Willkommen bei ${GRIDNAME}\""
|
||
done
|
||
log INFO "Gridname ($GRIDNAME) in Konfigurationsdateien gesetzt"
|
||
fi
|
||
|
||
log INFO "OpenSim runtime ini Konfiguration abgeschlossen"
|
||
}
|
||
|
||
sql_escape() {
|
||
local s="$1"
|
||
s="${s//\\/\\\\}"
|
||
s="${s//\'/\'\'}"
|
||
printf '%s' "$s"
|
||
}
|
||
|
||
run_mariadb_sql() {
|
||
local sql="$1"
|
||
|
||
if [[ -n "$DB_ROOT_PASS" ]]; then
|
||
mariadb -u"$DB_ROOT_USER" -p"$DB_ROOT_PASS" -e "$sql"
|
||
else
|
||
mariadb -u"$DB_ROOT_USER" -e "$sql"
|
||
fi
|
||
}
|
||
|
||
discover_sim_databases() {
|
||
local sim_bin sim_name
|
||
local sim_dbs=()
|
||
|
||
shopt -s nullglob
|
||
for sim_bin in "$WORKDIR"/sim*/bin; do
|
||
sim_name="$(basename "$(dirname "$sim_bin")")"
|
||
sim_dbs+=("$sim_name")
|
||
done
|
||
shopt -u nullglob
|
||
|
||
printf '%s\n' "${sim_dbs[@]}"
|
||
}
|
||
|
||
write_db_credentials_file() {
|
||
local file="$WORKDIR/UserInfo.ini"
|
||
|
||
mkdir -p "$WORKDIR" 2>/dev/null || sudo mkdir -p "$WORKDIR"
|
||
if [[ ! -f "$file" ]]; then
|
||
: > "$file" 2>/dev/null || sudo touch "$file"
|
||
fi
|
||
|
||
{
|
||
echo "[DatabaseData]"
|
||
echo "DB_Benutzername = $DB_USER"
|
||
echo "DB_Passwort = $DB_PASS"
|
||
} | sudo tee "$file" >/dev/null
|
||
|
||
log INFO "Database credentials written: $file"
|
||
}
|
||
|
||
configure_database() {
|
||
local escaped_user escaped_pass db_name
|
||
local db_ident
|
||
local sim_db_list
|
||
|
||
need_cmd mariadb
|
||
need_cmd sudo
|
||
ensure_mariadb_service
|
||
|
||
[[ -n "$DB_USER" ]] || die "--db-user is required for configure-database"
|
||
[[ -n "$DB_PASS" ]] || die "--db-pass is required for configure-database"
|
||
|
||
escaped_user="$(sql_escape "$DB_USER")"
|
||
escaped_pass="$(sql_escape "$DB_PASS")"
|
||
|
||
if ! run_mariadb_sql "SELECT 1" >/dev/null 2>&1; then
|
||
die "Cannot connect to MariaDB as '$DB_ROOT_USER'. Check --db-root-user/--db-root-pass and server state."
|
||
fi
|
||
|
||
log INFO "Configuring MariaDB databases and grants"
|
||
|
||
if [[ -d "$WORKDIR/robust" ]]; then
|
||
run_mariadb_sql "CREATE DATABASE IF NOT EXISTS robust CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
|
||
log INFO "Ensured database: robust"
|
||
fi
|
||
|
||
# Sim-Datenbanken: bei --sim-count N explizit, sonst Verzeichnisse ermitteln
|
||
local sim_db_list=""
|
||
if [[ "$SIM_COUNT" -gt 0 ]]; then
|
||
sim_db_list="$(for ((i=1; i<=SIM_COUNT; i++)); do echo "sim${i}"; done)"
|
||
log INFO "--sim-count $SIM_COUNT: erstelle Datenbanken sim1..sim${SIM_COUNT}"
|
||
else
|
||
sim_db_list="$(discover_sim_databases)"
|
||
if [[ -z "$sim_db_list" ]]; then
|
||
log INFO "Keine sim*-Verzeichnisse unter $WORKDIR gefunden — sim-Datenbanken übersprungen. Mit --sim-count N erzwingen."
|
||
fi
|
||
fi
|
||
|
||
if [[ -n "$sim_db_list" ]]; then
|
||
while IFS= read -r db_name; do
|
||
[[ -n "$db_name" ]] || continue
|
||
local db_ident="\`$db_name\`"
|
||
run_mariadb_sql "CREATE DATABASE IF NOT EXISTS $db_ident CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
|
||
log INFO "Datenbank sichergestellt: $db_name"
|
||
done <<< "$sim_db_list"
|
||
fi
|
||
|
||
run_mariadb_sql "CREATE USER IF NOT EXISTS '$escaped_user'@'localhost' IDENTIFIED BY '$escaped_pass';"
|
||
run_mariadb_sql "ALTER USER '$escaped_user'@'localhost' IDENTIFIED BY '$escaped_pass';"
|
||
|
||
if [[ -d "$WORKDIR/robust" ]]; then
|
||
run_mariadb_sql "GRANT ALL PRIVILEGES ON robust.* TO '$escaped_user'@'localhost';"
|
||
fi
|
||
|
||
if [[ -n "$sim_db_list" ]]; then
|
||
while IFS= read -r db_name; do
|
||
[[ -n "$db_name" ]] || continue
|
||
local db_ident="\`$db_name\`"
|
||
run_mariadb_sql "GRANT ALL PRIVILEGES ON $db_ident.* TO '$escaped_user'@'localhost';"
|
||
done <<< "$sim_db_list"
|
||
fi
|
||
|
||
run_mariadb_sql "FLUSH PRIVILEGES;"
|
||
|
||
write_db_credentials_file
|
||
log INFO "MariaDB Datenbank-Setup abgeschlossen"
|
||
}
|
||
|
||
server_check() {
|
||
local fail=0
|
||
local os_id=""
|
||
local free_kb="0"
|
||
local missing_pkgs=()
|
||
local required_janus_pkgs=(
|
||
build-essential cmake git pkg-config automake libtool gengetopt
|
||
libmicrohttpd-dev libjansson-dev libssl-dev libsofia-sip-ua-dev libglib2.0-dev
|
||
libopus-dev libogg-dev libcurl4-openssl-dev liblua5.3-dev libconfig-dev
|
||
libwebsockets-dev libsrtp2-dev libnice-dev libsqlite3-dev
|
||
)
|
||
local required_opensim_tokens=(
|
||
git zip screen libgdiplus zlib1g libunwind8 libgssapi-krb5-2 libstdc++6
|
||
"mariadb-client|default-mysql-client|mysql-client"
|
||
"mariadb-server|mysql-server"
|
||
"libgcc-s1|libgcc1"
|
||
"libssl3|libssl1.1"
|
||
"libicu74|libicu72|libicu71|libicu70|libicu67"
|
||
"liblttng-ust1|liblttng-ust0"
|
||
)
|
||
local pkg token
|
||
|
||
log INFO "Running server readiness check"
|
||
|
||
if [[ -f /etc/os-release ]]; then
|
||
os_id="$(awk -F= '/^ID=/{gsub(/\"/,"",$2); print $2; exit}' /etc/os-release 2>/dev/null || true)"
|
||
[[ -n "$os_id" ]] || os_id="unknown"
|
||
local os_pretty
|
||
os_pretty="$(awk -F= '/^PRETTY_NAME=/{gsub(/\"/,"",$2); print $2; exit}' /etc/os-release 2>/dev/null || true)"
|
||
[[ -n "$os_pretty" ]] || os_pretty="unknown"
|
||
log INFO "Detected OS: $os_pretty"
|
||
fi
|
||
|
||
if [[ "$os_id" != "ubuntu" && "$os_id" != "debian" ]]; then
|
||
log ERROR "Unsupported OS for this automation: $os_id"
|
||
fail=1
|
||
fi
|
||
|
||
if command -v sudo >/dev/null 2>&1; then
|
||
if sudo -n true >/dev/null 2>&1; then
|
||
log INFO "sudo non-interactive check: OK"
|
||
else
|
||
log INFO "sudo available but password will be required"
|
||
fi
|
||
else
|
||
log ERROR "sudo not found"
|
||
fail=1
|
||
fi
|
||
|
||
if command -v apt-get >/dev/null 2>&1; then
|
||
log INFO "apt-get available"
|
||
else
|
||
log ERROR "apt-get missing"
|
||
fail=1
|
||
fi
|
||
|
||
if command -v curl >/dev/null 2>&1; then
|
||
if curl -Is https://github.com >/dev/null 2>&1; then
|
||
log INFO "Network check to github.com: OK"
|
||
else
|
||
log ERROR "Network check to github.com failed"
|
||
fail=1
|
||
fi
|
||
else
|
||
log ERROR "curl missing"
|
||
fail=1
|
||
fi
|
||
|
||
free_kb="$(df -Pk /opt | awk 'NR==2 {print $4}')"
|
||
if [[ -n "$free_kb" && "$free_kb" -gt 2097152 ]]; then
|
||
log INFO "Disk space in /opt is sufficient"
|
||
else
|
||
log ERROR "Low disk space in /opt (need at least 2GB free)"
|
||
fail=1
|
||
fi
|
||
|
||
for pkg in "${required_janus_pkgs[@]}"; do
|
||
if ! dpkg -s "$pkg" >/dev/null 2>&1; then
|
||
missing_pkgs+=("$pkg")
|
||
fi
|
||
done
|
||
|
||
for token in "${required_opensim_tokens[@]}"; do
|
||
if ! resolve_package_token "$token" >/dev/null 2>&1; then
|
||
missing_pkgs+=("$token")
|
||
fi
|
||
done
|
||
|
||
if [[ ${#missing_pkgs[@]} -eq 0 ]]; then
|
||
log INFO "All required Janus/OpenSim dependency packages are installed"
|
||
else
|
||
log ERROR "Missing packages: ${missing_pkgs[*]}"
|
||
log INFO "Run: sudo apt-get update && sudo apt-get install -y ${missing_pkgs[*]}"
|
||
fail=1
|
||
fi
|
||
|
||
if has_dotnet8_sdk; then
|
||
log INFO "dotnet SDK 8.x found"
|
||
else
|
||
log ERROR "dotnet SDK 8.x missing (required for OpenSim build/runtime)"
|
||
fail=1
|
||
fi
|
||
|
||
if command -v mysqldump >/dev/null 2>&1; then
|
||
log INFO "mysqldump found (MariaDB backup tooling ready)"
|
||
else
|
||
log ERROR "mysqldump missing (MariaDB client tools are required)"
|
||
fail=1
|
||
fi
|
||
|
||
if [[ "$fail" -eq 0 ]]; then
|
||
log INFO "Server readiness check PASSED"
|
||
return 0
|
||
fi
|
||
|
||
die "Server readiness check FAILED"
|
||
}
|
||
|
||
upsert_key() {
|
||
local file="$1"
|
||
local key="$2"
|
||
local value="$3"
|
||
|
||
if grep -Eq "^[[:space:]]*;?[[:space:]]*${key}[[:space:]]*=" "$file"; then
|
||
sudo sed -i -E "s|^[[:space:]]*;?[[:space:]]*(${key})[[:space:]]*=.*|\1 = $value|" "$file"
|
||
else
|
||
echo "$key = $value" | sudo tee -a "$file" >/dev/null
|
||
fi
|
||
}
|
||
|
||
generate_alnum_token() {
|
||
local length="${1:-32}"
|
||
if command -v openssl >/dev/null 2>&1; then
|
||
openssl rand -hex "$((length / 2))" | cut -c1-"$length"
|
||
return
|
||
fi
|
||
tr -dc 'A-Za-z0-9' </dev/urandom | head -c "$length"
|
||
}
|
||
|
||
compile_janus() {
|
||
need_cmd apt-get
|
||
need_cmd git
|
||
|
||
log INFO "Installing Janus build dependencies"
|
||
sudo apt-get update
|
||
sudo apt-get install -y \
|
||
build-essential cmake git pkg-config automake libtool gengetopt \
|
||
libmicrohttpd-dev libjansson-dev libssl-dev libsofia-sip-ua-dev libglib2.0-dev \
|
||
libopus-dev libogg-dev libcurl4-openssl-dev liblua5.3-dev libconfig-dev \
|
||
libwebsockets-dev libsrtp2-dev libnice-dev libsqlite3-dev
|
||
|
||
if [[ -d "$JANUS_SRC/.git" ]]; then
|
||
log INFO "Updating existing Janus source at $JANUS_SRC"
|
||
git -C "$JANUS_SRC" pull --ff-only
|
||
else
|
||
if [[ -e "$JANUS_SRC" ]]; then
|
||
die "Janus source path exists but is not a git repository: $JANUS_SRC"
|
||
fi
|
||
log INFO "Cloning Janus source to $JANUS_SRC"
|
||
git clone https://github.com/meetecho/janus-gateway.git "$JANUS_SRC"
|
||
fi
|
||
|
||
log INFO "Building Janus"
|
||
(
|
||
cd "$JANUS_SRC"
|
||
sh autogen.sh
|
||
./configure --prefix="$JANUS_PREFIX"
|
||
make -j"$(nproc)"
|
||
sudo make install
|
||
sudo make configs
|
||
)
|
||
|
||
log INFO "Janus compiled and installed to $JANUS_PREFIX"
|
||
}
|
||
|
||
configure_janus() {
|
||
local conf_dir core_cfg http_cfg api_secret admin_secret
|
||
conf_dir="$JANUS_PREFIX/etc/janus"
|
||
|
||
[[ -d "$conf_dir" ]] || die "Janus config dir not found: $conf_dir"
|
||
|
||
core_cfg="$conf_dir/janus.jcfg"
|
||
[[ -f "$core_cfg" ]] || core_cfg="$conf_dir/janus.cfg"
|
||
|
||
http_cfg="$conf_dir/janus.transport.http.jcfg"
|
||
[[ -f "$http_cfg" ]] || http_cfg="$conf_dir/janus.transport.http.cfg"
|
||
|
||
[[ -f "$core_cfg" ]] || die "Missing janus core config in $conf_dir"
|
||
[[ -f "$http_cfg" ]] || die "Missing janus HTTP transport config in $conf_dir"
|
||
|
||
api_secret="$API_SECRET"
|
||
[[ -n "$api_secret" ]] || api_secret="$(generate_alnum_token 32)"
|
||
|
||
admin_secret="$ADMIN_SECRET"
|
||
[[ -n "$admin_secret" ]] || admin_secret="$(generate_alnum_token 32)"
|
||
|
||
sudo cp "$core_cfg" "$core_cfg.bak-$(date +%Y%m%d-%H%M%S)"
|
||
sudo cp "$http_cfg" "$http_cfg.bak-$(date +%Y%m%d-%H%M%S)"
|
||
|
||
upsert_key "$core_cfg" "rtp_port_range" "\"$RTP_RANGE\""
|
||
upsert_key "$http_cfg" "http" "true"
|
||
upsert_key "$http_cfg" "port" "$HTTP_PORT"
|
||
upsert_key "$http_cfg" "api_secret" "\"$api_secret\""
|
||
|
||
if [[ "$ENABLE_ADMIN" == "true" ]]; then
|
||
upsert_key "$http_cfg" "admin_http" "true"
|
||
upsert_key "$http_cfg" "admin_port" "$ADMIN_PORT"
|
||
upsert_key "$http_cfg" "admin_secret" "\"$admin_secret\""
|
||
else
|
||
upsert_key "$http_cfg" "admin_http" "false"
|
||
fi
|
||
|
||
local snippet_file secrets_file
|
||
snippet_file="$WORKDIR/opensim-janus-config.generated.ini"
|
||
secrets_file="$HOME/janus_opensim_secrets.env"
|
||
|
||
mkdir -p "$WORKDIR" 2>/dev/null || sudo mkdir -p "$WORKDIR"
|
||
|
||
# Vollstaendiges OpenSim/Robust-Snippet (entspricht config-janus-linux.sh)
|
||
cat <<EOF | sudo tee "$snippet_file" >/dev/null
|
||
; ==========================================================
|
||
; OpenSim WebRTC/Janus Config (generiert von osmtool)
|
||
; ==========================================================
|
||
|
||
; ----------------------------
|
||
; OpenSim.ini [WebRtcVoice]
|
||
; ----------------------------
|
||
[WebRtcVoice]
|
||
Enabled = true
|
||
SpatialVoiceService = WebRtcVoice.dll:WebRtcVoiceServiceConnector
|
||
NonSpatialVoiceService = WebRtcVoice.dll:WebRtcVoiceServiceConnector
|
||
WebRtcVoiceServerURI = http://$PUBLIC_HOST:8003
|
||
|
||
; ----------------------------
|
||
; Robust.ini [ServiceList] + [WebRtcVoice] + [JanusWebRtcVoice]
|
||
; ----------------------------
|
||
[ServiceList]
|
||
VoiceServiceConnector = "8000/OpenSim.Server.Handlers.dll:OpenSim.Server.Handlers.WebRtcVoiceServerConnector"
|
||
|
||
[WebRtcVoice]
|
||
Enabled = true
|
||
NonSpatialVoiceService = WebRtcJanusService.dll:WebRtcJanusService
|
||
|
||
[JanusWebRtcVoice]
|
||
JanusGatewayURI = http://$PUBLIC_HOST:$HTTP_PORT/janus
|
||
APIToken = $api_secret
|
||
EOF
|
||
|
||
if [[ "$ENABLE_ADMIN" == "true" ]]; then
|
||
cat <<EOF | sudo tee -a "$snippet_file" >/dev/null
|
||
JanusGatewayAdminURI = http://$PUBLIC_HOST:$ADMIN_PORT/admin
|
||
AdminAPIToken = $admin_secret
|
||
EOF
|
||
fi
|
||
|
||
cat <<'EOF' | sudo tee -a "$snippet_file" >/dev/null
|
||
MessageDetails = false
|
||
EOF
|
||
|
||
# Secrets sichern (analog janus_instal.sh)
|
||
{
|
||
echo "JANUS_API_SECRET=$api_secret"
|
||
[[ -n "$admin_secret" ]] && echo "JANUS_ADMIN_SECRET=$admin_secret"
|
||
echo "JANUS_HTTP_PORT=$HTTP_PORT"
|
||
echo "JANUS_PUBLIC_HOST=$PUBLIC_HOST"
|
||
} > "$secrets_file"
|
||
chmod 600 "$secrets_file"
|
||
log INFO "Janus Secrets gespeichert: $secrets_file (chmod 600)"
|
||
|
||
cat <<EOF | sudo tee "$JANUS_PREFIX/.osmtool_janus_ready" >/dev/null
|
||
JANUS_PREFIX=$JANUS_PREFIX
|
||
HTTP_PORT=$HTTP_PORT
|
||
ADMIN_PORT=$ADMIN_PORT
|
||
ENABLE_ADMIN=$ENABLE_ADMIN
|
||
RTP_RANGE=$RTP_RANGE
|
||
PUBLIC_HOST=$PUBLIC_HOST
|
||
EOF
|
||
|
||
log INFO "Janus konfiguriert. Snippet: $snippet_file — Marker: $JANUS_PREFIX/.osmtool_janus_ready"
|
||
log INFO "Firewall oeffnen: TCP $HTTP_PORT, UDP ${RTP_RANGE%%-*}-${RTP_RANGE##*-}"
|
||
log INFO "Janus neu starten: sudo systemctl restart janus"
|
||
log INFO "Snippet-Inhalt in OpenSim.ini und Robust.ini uebernehmen."
|
||
}
|
||
|
||
prepare_ubuntu() {
|
||
need_cmd apt-get
|
||
log INFO "Preparing Ubuntu server"
|
||
sudo apt-get update
|
||
sudo apt-get -y upgrade
|
||
sudo apt-get -y install curl git screen unzip jq wget
|
||
log INFO "Ubuntu base packages installed"
|
||
}
|
||
|
||
install_opensim() {
|
||
need_cmd git
|
||
need_cmd dotnet
|
||
need_cmd bash
|
||
|
||
log INFO "Starting OpenSim install/build flow"
|
||
log INFO "OpenSim repository: $OPENSIM_REPO"
|
||
log INFO "OpenSim branch: $OPENSIM_BRANCH"
|
||
log INFO "OpenSim directory: $OPENSIM_DIR"
|
||
|
||
sync_git_repo "$OPENSIM_REPO" "$OPENSIM_DIR" "$OPENSIM_BRANCH" "$REPO_MODE"
|
||
ensure_user_owns_path "$OPENSIM_DIR"
|
||
|
||
# Patch-Dateien nur mit Bestaetigung einspielen
|
||
if [[ -n "$LEGACY_PATCH_DIR" ]]; then
|
||
if confirm_addon "Patch-Dateien" "Verzeichnis: $LEGACY_PATCH_DIR"; then
|
||
apply_legacy_patches "$LEGACY_PATCH_DIR"
|
||
fi
|
||
fi
|
||
|
||
# opensim-tsassets (Texturen/Assets)
|
||
if confirm_addon "opensim-tsassets" "$TSASSETS_REPO"; then
|
||
sync_support_repo "opensim-tsassets" "$TSASSETS_REPO" "$TSASSETS_DIR"
|
||
copy_tree_contents "$TSASSETS_DIR/bin" "$OPENSIM_DIR/bin" "tsassets bin content"
|
||
copy_tree_contents "$TSASSETS_DIR/OpenSim" "$OPENSIM_DIR/OpenSim" "tsassets OpenSim content"
|
||
fi
|
||
|
||
# opensimcurrencyserver-dotnet (Geldsystem)
|
||
if confirm_addon "opensimcurrencyserver-dotnet" "$CURRENCY_REPO"; then
|
||
sync_support_repo "opensimcurrencyserver" "$CURRENCY_REPO" "$CURRENCY_DIR"
|
||
copy_tree_contents "$CURRENCY_DIR/addon-modules" "$OPENSIM_DIR/addon-modules" "currency addon modules"
|
||
copy_tree_contents "$CURRENCY_DIR/bin" "$OPENSIM_DIR/bin" "currency bin content"
|
||
fi
|
||
|
||
# os-data-backup
|
||
if confirm_addon "os-data-backup" "$DATA_BACKUP_REPO"; then
|
||
sync_support_repo "os-data-backup" "$DATA_BACKUP_REPO" "$DATA_BACKUP_DIR"
|
||
copy_tree_contents "$DATA_BACKUP_DIR" "$OPENSIM_DIR/addon-modules/os-data-backup" "os-data-backup content"
|
||
fi
|
||
|
||
log INFO "Running OpenSim prebuild"
|
||
(
|
||
cd "$OPENSIM_DIR"
|
||
bash runprebuild.sh
|
||
dotnet build --configuration Release OpenSim.sln
|
||
)
|
||
|
||
[[ -f "$OPENSIM_DIR/bin/OpenSim.dll" ]] || die "OpenSim build output missing: $OPENSIM_DIR/bin/OpenSim.dll"
|
||
[[ -f "$OPENSIM_DIR/bin/Robust.dll" ]] || die "OpenSim build output missing: $OPENSIM_DIR/bin/Robust.dll"
|
||
|
||
if [[ "$DEPLOY_BINARIES" == "true" ]]; then
|
||
deploy_opensim_binaries
|
||
configure_opensim_runtime
|
||
else
|
||
log INFO "Binary deployment skipped by configuration"
|
||
fi
|
||
|
||
log INFO "OpenSim install/build flow completed"
|
||
}
|
||
|
||
# Allgemeine Bestaetigungsfunktion fuer externe Addons.
|
||
# Umgebungsvariable ADDON_CONFIRMED=true ueberspringt die Abfrage (CI/Automation).
|
||
confirm_addon() {
|
||
local addon_name="${1:-Addon}"
|
||
local addon_desc="${2:-}"
|
||
local answer
|
||
|
||
if [[ "${ADDON_CONFIRMED:-}" == "true" ]]; then
|
||
return 0
|
||
fi
|
||
|
||
echo
|
||
echo "======================================================="
|
||
echo " $(msg PROMPT_EXTERNAL_ADDON): $addon_name"
|
||
[[ -n "$addon_desc" ]] && echo " $addon_desc"
|
||
echo " $(msg PROMPT_ADDON_INFO_1)"
|
||
echo " $(msg PROMPT_ADDON_INFO_2)"
|
||
echo "======================================================="
|
||
read -r -p " $(msg PROMPT_INSTALL_YESNO) " answer
|
||
case "${answer,,}" in
|
||
j|ja|y|yes|o|oui|s|si|sí) return 0 ;;
|
||
*)
|
||
log INFO "$(msg INFO_ADDON_SKIPPED): $addon_name"
|
||
return 1
|
||
;;
|
||
esac
|
||
}
|
||
|
||
confirm_janus() {
|
||
local action_label="${1:-Janus-Aktion}"
|
||
local answer
|
||
|
||
# Im nicht-interaktiven Betrieb (z. B. CI) Var JANUS_CONFIRMED=true setzen
|
||
if [[ "${JANUS_CONFIRMED:-}" == "true" ]]; then
|
||
return 0
|
||
fi
|
||
|
||
echo
|
||
echo "======================================================="
|
||
echo " $(msg PROMPT_JANUS_TITLE): $action_label"
|
||
echo "======================================================="
|
||
echo " $(msg PROMPT_JANUS_INFO_1)"
|
||
echo " $(msg PROMPT_JANUS_INFO_2)"
|
||
echo " $(msg PROMPT_JANUS_INFO_3) $JANUS_PREFIX."
|
||
echo "======================================================="
|
||
read -r -p " $(msg PROMPT_CONTINUE_YESNO) " answer
|
||
case "${answer,,}" in
|
||
j|ja|y|yes|o|oui|s|si|sí) return 0 ;;
|
||
*)
|
||
log INFO "$(msg INFO_JANUS_CANCELLED)"
|
||
exit 0
|
||
;;
|
||
esac
|
||
}
|
||
|
||
install_janus() {
|
||
confirm_janus "Installation + Konfiguration"
|
||
compile_janus
|
||
configure_janus
|
||
}
|
||
|
||
ensure_shared_config_for_install() {
|
||
if [[ -f "$OSMTOOL_CONFIG_FILE" ]]; then
|
||
return 0
|
||
fi
|
||
|
||
if [[ -t 0 ]]; then
|
||
log INFO "Shared configuration not found. Starting interactive setup."
|
||
init_shared_config_interactive
|
||
return 0
|
||
fi
|
||
|
||
log INFO "Shared configuration not found at $OSMTOOL_CONFIG_FILE (non-interactive mode)"
|
||
return 0
|
||
}
|
||
|
||
WORKDIR="$DEFAULT_WORKDIR"
|
||
ACTION=""
|
||
PROFILE="grid-sim"
|
||
REPO_MODE="${REPO_MODE:-update}"
|
||
OPENSIM_REPO="${OPENSIM_REPO:-https://github.com/opensim/opensim.git}"
|
||
OPENSIM_BRANCH="${OPENSIM_BRANCH:-master}"
|
||
OPENSIM_DIR="${OPENSIM_DIR:-${CONFIG_OPENSIM_DIR:-$WORKDIR/opensim}}"
|
||
TSASSETS_REPO="${TSASSETS_REPO:-https://github.com/ManfredAabye/opensim-tsassets.git}"
|
||
TSASSETS_DIR="${TSASSETS_DIR:-$WORKDIR/opensim-tsassets}"
|
||
CURRENCY_REPO="${CURRENCY_REPO:-https://github.com/ManfredAabye/opensimcurrencyserver-dotnet.git}"
|
||
CURRENCY_DIR="${CURRENCY_DIR:-$WORKDIR/opensimcurrencyserver}"
|
||
DATA_BACKUP_REPO="${DATA_BACKUP_REPO:-https://github.com/ManfredAabye/os-data-backup.git}"
|
||
DATA_BACKUP_DIR="${DATA_BACKUP_DIR:-$WORKDIR/os-data-backup}"
|
||
DEPLOY_BINARIES="${DEPLOY_BINARIES:-true}"
|
||
LEGACY_PATCH_DIR="${LEGACY_PATCH_DIR:-}"
|
||
DB_ROOT_USER="${DB_ROOT_USER:-${CONFIG_DB_ROOT_USER:-root}}"
|
||
DB_ROOT_PASS="${DB_ROOT_PASS:-${CONFIG_DB_ROOT_PASS:-}}"
|
||
DB_USER="${DB_USER:-${CONFIG_DB_USER:-opensimuser}}"
|
||
DB_PASS="${DB_PASS:-${CONFIG_DB_PASS:-}}"
|
||
JANUS_PREFIX="${JANUS_PREFIX:-${CONFIG_JANUS_PREFIX:-/opt/janus}}"
|
||
JANUS_SRC="${JANUS_SRC:-$WORKDIR/janus-gateway}"
|
||
PUBLIC_HOST="${PUBLIC_HOST:-${CONFIG_PUBLIC_HOST:-127.0.0.1}}"
|
||
HTTP_PORT="${HTTP_PORT:-8088}"
|
||
ADMIN_PORT="${ADMIN_PORT:-7088}"
|
||
RTP_RANGE="${RTP_RANGE:-10000-10200}"
|
||
ENABLE_ADMIN="${ENABLE_ADMIN:-false}"
|
||
API_SECRET="${API_SECRET:-}"
|
||
ADMIN_SECRET="${ADMIN_SECRET:-}"
|
||
GRIDNAME="${GRIDNAME:-${CONFIG_GRIDNAME:-}}"
|
||
SIM_COUNT="${SIM_COUNT:-0}"
|
||
|
||
while [[ $# -gt 0 ]]; do
|
||
case "$1" in
|
||
--workdir) WORKDIR="$2"; shift 2 ;;
|
||
--profile) PROFILE="$2"; shift 2 ;;
|
||
--action) ACTION="$2"; shift 2 ;;
|
||
--opensim-dir) OPENSIM_DIR="$2"; shift 2 ;;
|
||
--opensim-repo) OPENSIM_REPO="$2"; shift 2 ;;
|
||
--opensim-branch) OPENSIM_BRANCH="$2"; shift 2 ;;
|
||
--repo-mode) REPO_MODE="$2"; shift 2 ;;
|
||
--tsassets-dir) TSASSETS_DIR="$2"; shift 2 ;;
|
||
--currency-dir) CURRENCY_DIR="$2"; shift 2 ;;
|
||
--data-backup-dir) DATA_BACKUP_DIR="$2"; shift 2 ;;
|
||
--deploy-binaries) DEPLOY_BINARIES="$2"; shift 2 ;;
|
||
--legacy-patch-dir) LEGACY_PATCH_DIR="$2"; shift 2 ;;
|
||
--db-root-user) DB_ROOT_USER="$2"; shift 2 ;;
|
||
--db-root-pass) DB_ROOT_PASS="$2"; shift 2 ;;
|
||
--db-user) DB_USER="$2"; shift 2 ;;
|
||
--db-pass) DB_PASS="$2"; shift 2 ;;
|
||
--janus-prefix) JANUS_PREFIX="$2"; shift 2 ;;
|
||
--janus-src) JANUS_SRC="$2"; shift 2 ;;
|
||
--public-host) PUBLIC_HOST="$2"; shift 2 ;;
|
||
--http-port) HTTP_PORT="$2"; shift 2 ;;
|
||
--admin-port) ADMIN_PORT="$2"; shift 2 ;;
|
||
--rtp-range) RTP_RANGE="$2"; shift 2 ;;
|
||
--enable-admin) ENABLE_ADMIN="$2"; shift 2 ;;
|
||
--api-secret) API_SECRET="$2"; shift 2 ;;
|
||
--admin-secret) ADMIN_SECRET="$2"; shift 2 ;; --gridname) GRIDNAME="$2"; shift 2 ;;
|
||
--sim-count) SIM_COUNT="$2"; shift 2 ;; --help|-h) usage; exit 0 ;;
|
||
*) die "Unknown option: $1" ;;
|
||
esac
|
||
done
|
||
|
||
[[ -n "$ACTION" ]] || die "Missing --action"
|
||
validate_profile "$PROFILE"
|
||
ensure_profile_action_allowed install "$PROFILE" "$ACTION"
|
||
|
||
if [[ "$ACTION" != "init-config" ]]; then
|
||
ensure_shared_config_for_install
|
||
fi
|
||
|
||
case "$REPO_MODE" in
|
||
update|fresh) ;;
|
||
*) die "Unsupported repo mode: $REPO_MODE" ;;
|
||
esac
|
||
|
||
case "$DEPLOY_BINARIES" in
|
||
true|false) ;;
|
||
*) die "--deploy-binaries must be true or false" ;;
|
||
esac
|
||
|
||
log INFO "Using workdir: $WORKDIR"
|
||
log INFO "Using profile: $PROFILE"
|
||
log INFO "Repo mode: $REPO_MODE"
|
||
log INFO "OpenSim dir: $OPENSIM_DIR"
|
||
log INFO "Janus prefix: $JANUS_PREFIX"
|
||
|
||
case "$ACTION" in
|
||
init-config)
|
||
init_shared_config_interactive
|
||
;;
|
||
server-check) server_check ;;
|
||
prepare-ubuntu) prepare_ubuntu ;;
|
||
install-opensim-deps) install_opensim_deps ;;
|
||
install-dotnet8) install_dotnet8 ;;
|
||
install-opensim) install_opensim ;;
|
||
configure-opensim) configure_opensim_runtime ;;
|
||
configure-database) configure_database ;;
|
||
compile-janus)
|
||
confirm_janus "Kompilierung"
|
||
compile_janus
|
||
;;
|
||
configure-janus)
|
||
confirm_janus "Konfiguration"
|
||
configure_janus
|
||
;;
|
||
install-janus) install_janus ;;
|
||
*) die "Unsupported action: $ACTION" ;;
|
||
esac
|