From a1042482447e910db6f808e78b30789a02913a10 Mon Sep 17 00:00:00 2001 From: AlphaLawless Date: Thu, 25 Dec 2025 22:28:50 -0300 Subject: [PATCH] update romm script - working now --- ct/romm.sh | 67 +++++---- install/romm-install.sh | 320 ++++++++++++++++++++++++++++------------ misc/tools.func | 61 +++++--- 3 files changed, 304 insertions(+), 144 deletions(-) diff --git a/ct/romm.sh b/ct/romm.sh index 129da9a34..39e0cbc7c 100644 --- a/ct/romm.sh +++ b/ct/romm.sh @@ -2,7 +2,8 @@ source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) # Copyright (c) 2021-2025 community-scripts ORG # Author: MickLesk (CanbiZ) -# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE +# Co-author: AlphaLawless +# License: MIT | https://github.com/AlphaLawless/ProxmoxVED/raw/main/LICENSE # Source: https://romm.app APP="RomM" @@ -10,10 +11,9 @@ var_tags="${var_tags:-emulation}" var_cpu="${var_cpu:-2}" var_ram="${var_ram:-4096}" var_disk="${var_disk:-20}" -var_os="${var_os:-ubuntu}" -var_version="${var_version:-24.04}" +var_os="${var_os:-debian}" +var_version="${var_version:-13}" var_unprivileged="${var_unprivileged:-1}" -var_fuse="${var_fuse:-1}" header_info "$APP" variables @@ -30,35 +30,44 @@ function update_script() { exit fi - msg_info "Stopping $APP" - systemctl stop romm - systemctl stop nginx - msg_ok "Stopped $APP" + if check_for_gh_release "romm" "rommapp/romm"; then + msg_info "Stopping ${APP} services" + systemctl stop romm-backend romm-worker romm-scheduler romm-watcher + msg_ok "Stopped ${APP} services" - msg_info "Updating $APP" - cd /opt/romm/app - git pull + msg_info "Backing up configuration" + cp /opt/romm/.env /opt/romm/.env.backup + msg_ok "Backed up configuration" - # Update backend - cd /opt/romm/app - source /opt/romm/venv/bin/activate - pip install --upgrade pip - pip install poetry - poetry install + msg_info "Updating ${APP}" + fetch_and_deploy_gh_release "romm" "rommapp/romm" "tarball" "latest" "/opt/romm" - # Update frontend - cd /opt/romm/app/frontend - npm install - npm run build + cp /opt/romm/.env.backup /opt/romm/.env - echo "Updated on $(date)" >/opt/romm/version.txt - msg_ok "Updated $APP" + cd /opt/romm + $STD uv sync --all-extras - msg_info "Starting $APP" - systemctl start romm - systemctl start nginx - msg_ok "Started $APP" - msg_ok "Update Successful" + cd /opt/romm/backend + $STD uv run alembic upgrade head + + cd /opt/romm/frontend + $STD npm install + $STD npm run build + + # Merge static assets into dist folder + cp -rf /opt/romm/frontend/assets/* /opt/romm/frontend/dist/assets/ + + mkdir -p /opt/romm/frontend/dist/assets/romm + ln -sfn /var/lib/romm/resources /opt/romm/frontend/dist/assets/romm/resources + ln -sfn /var/lib/romm/assets /opt/romm/frontend/dist/assets/romm/assets + msg_ok "Updated ${APP}" + + msg_info "Starting ${APP} services" + systemctl start romm-backend romm-worker romm-scheduler romm-watcher + msg_ok "Started ${APP} services" + + msg_ok "Update Successful" + fi exit } @@ -69,4 +78,4 @@ description msg_ok "Completed Successfully!\n" echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" echo -e "${INFO}${YW} Access it using the following URL:${CL}" -echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8080${CL}" +echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}" diff --git a/install/romm-install.sh b/install/romm-install.sh index 438e4e5a7..8027ab3a6 100644 --- a/install/romm-install.sh +++ b/install/romm-install.sh @@ -2,9 +2,10 @@ # Copyright (c) 2021-2025 community-scripts ORG # Author: DevelopmentCats -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Co-author: AlphaLawless +# License: MIT | https://github.com/AlphaLawless/ProxmoxVED/raw/main/LICENSE # Source: https://romm.app -# Updated: 03/10/2025 +# Updated: 25/12/2025 source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" color @@ -18,65 +19,126 @@ msg_info "Installing dependencies" $STD apt-get install -y \ acl \ build-essential \ + gcc \ + g++ \ + make \ + git \ + curl \ libssl-dev \ libffi-dev \ + libmagic-dev \ python3-dev \ python3-pip \ python3-venv \ libmariadb3 \ libmariadb-dev \ libpq-dev \ + libbz2-dev \ + libreadline-dev \ + libsqlite3-dev \ + zlib1g-dev \ + liblzma-dev \ + libncurses5-dev \ + libncursesw5-dev \ + redis-server \ redis-tools \ - p7zip \ + p7zip-full \ tzdata \ - jq -msg_ok "Installed core dependencies" + jq \ + nginx +msg_ok "Installed dependencies" -PYTHON_VERSION="3.12" setup_uv -NODE_VERSION="22" NODE_MODULE="serve" setup_nodejs +UV_VERSION="0.7.19" PYTHON_VERSION="3.13" setup_uv +NODE_VERSION="22" setup_nodejs setup_mariadb +MARIADB_DB_NAME="romm" MARIADB_DB_USER="romm" setup_mariadb_db -msg_info "Configuring Database" -DB_NAME=romm -DB_USER=romm -DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13) -$STD mariadb -u root -e "CREATE DATABASE IF NOT EXISTS $DB_NAME CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" -$STD mariadb -u root -e "CREATE USER IF NOT EXISTS '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASS';" -$STD mariadb -u root -e "GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost'; FLUSH PRIVILEGES;" -{ - echo "RomM-Credentials" - echo "RomM Database User: $DB_USER" - echo "RomM Database Password: $DB_PASS" - echo "RomM Database Name: $DB_NAME" -} >~/romm.creds -chmod 600 ~/romm.creds -msg_ok "Configured Database" - -msg_info "Creating romm user and directories" -id -u romm &>/dev/null || useradd -r -m -d /var/lib/romm -s /bin/bash romm +msg_info "Creating directories" mkdir -p /opt/romm \ /var/lib/romm/config \ /var/lib/romm/resources \ /var/lib/romm/assets/{saves,states,screenshots} \ - /var/lib/romm/library/roms/{gba,gbc,ps} \ - /var/lib/romm/library/bios/{gba,ps} -chown -R romm:romm /opt/romm /var/lib/romm -msg_ok "Created romm user and directories" + /var/lib/romm/library/roms \ + /var/lib/romm/library/bios +msg_ok "Created directories" -msg_info "Configuring Database" -DB_NAME=romm -DB_USER=romm -DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13) -$STD mariadb -u root -e "CREATE DATABASE $DB_NAME CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" -$STD mariadb -u root -e "CREATE USER '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASS';" -$STD mariadb -u root -e "GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost'; FLUSH PRIVILEGES;" -{ - echo "RomM-Credentials" - echo "RomM Database User: $DB_USER" - echo "RomM Database Password: $DB_PASS" - echo "RomM Database Name: $DB_NAME" -} >~/romm.creds -msg_ok "Configured Database" +msg_info "Creating configuration file" +cat >/var/lib/romm/config/config.yml <<'CONFIGEOF' +# RomM Configuration File +# Documentation: https://docs.romm.app/latest/Getting-Started/Configuration-File/ +# Only uncomment the lines you want to use/modify + +# exclude: +# platforms: +# - excluded_folder_a +# roms: +# single_file: +# extensions: +# - xml +# - txt +# names: +# - '._*' +# - '*.nfo' +# multi_file: +# names: +# - downloaded_media +# - media + +# system: +# platforms: +# gc: ngc +# ps1: psx + +# The folder name where your roms are located (relative to library path) +# filesystem: +# roms_folder: 'roms' + +# scan: +# priority: +# metadata: +# - "igdb" +# - "moby" +# - "ss" +# - "ra" +# artwork: +# - "igdb" +# - "moby" +# - "ss" +# region: +# - "us" +# - "eu" +# - "jp" +# language: +# - "en" +# media: +# - box2d +# - box3d +# - screenshot +# - manual + +# emulatorjs: +# debug: false +# cache_limit: null +CONFIGEOF +chmod 644 /var/lib/romm/config/config.yml +msg_ok "Created configuration file" + +msg_info "Building RAHasher (RetroAchievements)" +RAHASHER_VERSION="1.8.1" +cd /tmp +git clone --recursive --branch "$RAHASHER_VERSION" --depth 1 https://github.com/RetroAchievements/RALibretro.git +cd RALibretro +sed -i '22a #include ' ./src/Util.h +sed -i '6a #include ' \ + ./src/libchdr/deps/zlib-1.3.1/gzlib.c \ + ./src/libchdr/deps/zlib-1.3.1/gzread.c \ + ./src/libchdr/deps/zlib-1.3.1/gzwrite.c +$STD make HAVE_CHD=1 -f ./Makefile.RAHasher +cp ./bin64/RAHasher /usr/bin/RAHasher +chmod +x /usr/bin/RAHasher +cd /tmp +rm -rf /tmp/RALibretro +msg_ok "Built RAHasher" fetch_and_deploy_gh_release "romm" "rommapp/romm" @@ -88,13 +150,14 @@ AUTH_SECRET_KEY=$(openssl rand -hex 32) cat >/opt/romm/.env </etc/nginx/sites-available/romm <<'EOF' +upstream romm_backend { + server 127.0.0.1:5000; +} +map $http_upgrade $connection_upgrade { + default upgrade; + '' close; +} + +server { + listen 80; + server_name _; + root /opt/romm/frontend/dist; + client_max_body_size 0; + + # Frontend SPA + location / { + try_files $uri $uri/ /index.html; + } + + # EmulatorJS player - requires COOP/COEP headers for SharedArrayBuffer + location ~ ^/rom/.*/ejs$ { + add_header Cross-Origin-Embedder-Policy "require-corp"; + add_header Cross-Origin-Opener-Policy "same-origin"; + try_files $uri /index.html; + } + + # Backend API + location /api { + proxy_pass http://romm_backend; + proxy_buffering off; + proxy_request_buffering off; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + # WebSocket and Netplay + location ~ ^/(ws|netplay) { + proxy_pass http://romm_backend; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + proxy_set_header Host $host; + proxy_read_timeout 86400; + } + + # OpenAPI docs + location = /openapi.json { + proxy_pass http://romm_backend; + } + + # Internal library file serving + location /library/ { + internal; + alias /var/lib/romm/library/; + } +} +EOF + +rm -f /etc/nginx/sites-enabled/default +ln -sf /etc/nginx/sites-available/romm /etc/nginx/sites-enabled/romm +$STD nginx -t +systemctl restart nginx +systemctl enable -q nginx +msg_ok "Configured nginx" + +msg_info "Creating services" cat >/etc/systemd/system/romm-backend.service </etc/systemd/system/romm-frontend.service </etc/systemd/system/romm-worker.service </etc/systemd/system/romm-scheduler.service </etc/systemd/system/romm-watcher.service </dev/null || echo "") + # Check if specific version is requested via UV_VERSION environment variable + if [[ -n "${UV_VERSION:-}" ]]; then + TARGET_VERSION="${UV_VERSION}" + USE_PINNED_VERSION=true + else + # Fetch latest version from GitHub API + local releases_json + releases_json=$(curl -fsSL --max-time 15 \ + "https://api.github.com/repos/astral-sh/uv/releases/latest" 2>/dev/null || echo "") - if [[ -z "$releases_json" ]]; then - msg_error "Could not fetch latest uv version from GitHub API" - return 1 - fi + if [[ -z "$releases_json" ]]; then + msg_error "Could not fetch latest uv version from GitHub API" + return 1 + fi - local LATEST_VERSION - LATEST_VERSION=$(echo "$releases_json" | jq -r '.tag_name' 2>/dev/null | sed 's/^v//') + TARGET_VERSION=$(echo "$releases_json" | jq -r '.tag_name' 2>/dev/null | sed 's/^v//') - if [[ -z "$LATEST_VERSION" ]]; then - msg_error "Could not parse uv version from GitHub API response" - return 1 + if [[ -z "$TARGET_VERSION" ]]; then + msg_error "Could not parse uv version from GitHub API response" + return 1 + fi fi # Get currently installed version @@ -4734,9 +4741,9 @@ function setup_uv() { INSTALLED_VERSION=$("$UV_BIN" --version 2>/dev/null | awk '{print $2}') fi - # Scenario 1: Already at latest version - if [[ -n "$INSTALLED_VERSION" && "$INSTALLED_VERSION" == "$LATEST_VERSION" ]]; then - cache_installed_version "uv" "$LATEST_VERSION" + # Scenario 1: Already at target version + if [[ -n "$INSTALLED_VERSION" && "$INSTALLED_VERSION" == "$TARGET_VERSION" ]]; then + cache_installed_version "uv" "$TARGET_VERSION" # Check if uvx is needed and missing if [[ "${USE_UVX:-NO}" == "YES" ]] && [[ ! -x "$UVX_BIN" ]]; then @@ -4748,14 +4755,22 @@ function setup_uv() { return 0 fi - # Scenario 2: New install or upgrade - if [[ -n "$INSTALLED_VERSION" && "$INSTALLED_VERSION" != "$LATEST_VERSION" ]]; then - msg_info "Upgrade uv from $INSTALLED_VERSION to $LATEST_VERSION" + # Scenario 2: New install or upgrade/downgrade + if [[ -n "$INSTALLED_VERSION" ]]; then + if [[ "$USE_PINNED_VERSION" == true ]]; then + msg_info "Switching uv from $INSTALLED_VERSION to pinned version $TARGET_VERSION" + else + msg_info "Upgrade uv from $INSTALLED_VERSION to $TARGET_VERSION" + fi else - msg_info "Setup uv $LATEST_VERSION" + if [[ "$USE_PINNED_VERSION" == true ]]; then + msg_info "Setup uv $TARGET_VERSION (pinned)" + else + msg_info "Setup uv $TARGET_VERSION" + fi fi - local UV_URL="https://github.com/astral-sh/uv/releases/download/${LATEST_VERSION}/${UV_TAR}" + local UV_URL="https://github.com/astral-sh/uv/releases/download/${TARGET_VERSION}/${UV_TAR}" $STD curl -fsSL "$UV_URL" -o "$TMP_DIR/uv.tar.gz" || { msg_error "Failed to download uv from $UV_URL" @@ -4809,8 +4824,8 @@ function setup_uv() { msg_ok "Python $PYTHON_VERSION installed" fi - cache_installed_version "uv" "$LATEST_VERSION" - msg_ok "Setup uv $LATEST_VERSION" + cache_installed_version "uv" "$TARGET_VERSION" + msg_ok "Setup uv $TARGET_VERSION" } # Helper function to install uvx wrapper