Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,17 @@ build_locations(){
include fastcgi_params;
}
#
# SSO endpoints (public)
location /auth/sso {
allow all;
proxy_pass http://unix:/var/run/unraid-core.sock:;
proxy_http_version 1.1;
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;
}
#
# Redirect to login page on failed authentication (401)
#
error_page 401 @401;
Expand Down Expand Up @@ -417,10 +428,22 @@ build_locations(){
#
# my servers proxy
#
location /graphql/api {
allow all;
proxy_pass http://unix:/var/run/unraid-api.sock:;
proxy_http_version 1.1;
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;
}
location /graphql {
allow all;
error_log /dev/null crit;
proxy_pass http://unix:/var/run/unraid-api.sock:/graphql;
if ($http_upgrade = "websocket") {
rewrite ^/graphql$ /graphql/socket break;
}
proxy_pass http://unix:/var/run/unraid-core.sock:;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,57 @@ Index: /etc/rc.d/rc.nginx
T=' '
if check && [[ $1 == lo ]]; then
if [[ $IPV4 == yes ]]; then
@@ -566,11 +584,11 @@
@@ -363,10 +381,21 @@
allow all;
try_files /login.php =404;
include fastcgi_params;
}
#
+ # SSO endpoints (public)
+ location /auth/sso {
+ allow all;
+ proxy_pass http://unix:/var/run/unraid-core.sock:;
+ proxy_http_version 1.1;
+ 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;
+ }
+ #
# Redirect to login page on failed authentication (401)
#
error_page 401 @401;
location @401 {
return 302 $scheme://$http_host/login;
@@ -397,14 +426,26 @@
nchan_stub_status;
}
#
# my servers proxy
#
+ location /graphql/api {
+ allow all;
+ proxy_pass http://unix:/var/run/unraid-api.sock:;
+ proxy_http_version 1.1;
+ 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;
+ }
location /graphql {
allow all;
error_log /dev/null crit;
- proxy_pass http://unix:/var/run/unraid-api.sock:/graphql;
+ if ($http_upgrade = "websocket") {
+ rewrite ^/graphql$ /graphql/socket break;
+ }
+ proxy_pass http://unix:/var/run/unraid-core.sock:;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_cache_bypass $http_upgrade;
@@ -566,11 +607,11 @@
# extract common name from cert
CERTNAME=$(openssl x509 -noout -subject -nameopt multiline -in $CERTPATH | sed -n 's/ *commonName *= //p')
# define CSP frame-ancestors for cert
Expand All @@ -57,7 +107,7 @@ Index: /etc/rc.d/rc.nginx
WANIP6=$(curl https://wanip6.unraid.net/ 2>/dev/null)
fi
if [[ $CERTNAME == *\.myunraid\.net ]]; then
@@ -660,14 +678,14 @@
@@ -660,14 +701,14 @@
echo "NGINX_WANFQDN=\"$WANFQDN\"" >>$INI
echo "NGINX_WANFQDN6=\"$WANFQDN6\"" >>$INI
# defined if ts_bundle.pem present:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ export default class RcNginxModification extends FileModification {
throw new Error(`File ${this.filePath} not found.`);
}
const fileContent = await readFile(this.filePath, 'utf8');
if (!fileContent.includes('MYSERVERS=')) {
throw new Error(`MYSERVERS not found in the file; incorrect target?`);
}
// if (!fileContent.includes('MYSERVERS=')) {
// throw new Error(`MYSERVERS not found in the file; incorrect target?`);
// }

let newContent = fileContent.replace(
'MYSERVERS="/boot/config/plugins/dynamix.my.servers/myservers.cfg"',
Expand Down Expand Up @@ -68,6 +68,27 @@ check_remote_access(){
`if [[ -L /usr/local/sbin/unraid-api ]] && check_remote_access; then`
);

newContent = newContent.replace(
'proxy_pass http://unix:/var/run/unraid-api.sock:/graphql;',
'if ($http_upgrade = "websocket") {\n\t rewrite ^/graphql$ /graphql/socket break;\n\t }\n\t proxy_pass http://unix:/var/run/unraid-core.sock:;'
);

if (!newContent.includes('location /auth/sso')) {
newContent = newContent.replace(
'\t# Redirect to login page on failed authentication (401)\n',
// prettier-ignore
`\t# SSO endpoints (public)\n\tlocation /auth/sso {\n\t allow all;\n\t proxy_pass http://unix:/var/run/unraid-core.sock:;\n\t proxy_http_version 1.1;\n\t proxy_set_header Host $host;\n\t proxy_set_header X-Real-IP $remote_addr;\n\t proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n\t proxy_set_header X-Forwarded-Proto $scheme;\n\t}\n\t#\n\t# Redirect to login page on failed authentication (401)\n`
);
}

if (!newContent.includes('location /graphql/api')) {
newContent = newContent.replace(
'\t# my servers proxy\n\t#\n\tlocation /graphql {',
// prettier-ignore
`\t# my servers proxy\n\t#\n\tlocation /graphql/api {\n\t allow all;\n\t proxy_pass http://unix:/var/run/unraid-api.sock:;\n\t proxy_http_version 1.1;\n\t proxy_set_header Host $host;\n\t proxy_set_header X-Real-IP $remote_addr;\n\t proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n\t proxy_set_header X-Forwarded-Proto $scheme;\n\t}\n\tlocation /graphql {`
);
}

newContent = newContent.replace(
'for NET in ${!NET_FQDN6[@]}; do',
'for NET in "${!NET_FQDN6[@]}"; do'
Expand All @@ -91,7 +112,7 @@ check_remote_access(){
}

async shouldApply(): Promise<ShouldApplyWithReason> {
const { shouldApply, reason } = await super.shouldApply();
const { shouldApply, reason } = await super.shouldApply({ checkOsVersion: false });
return {
shouldApply,
reason,
Expand Down
66 changes: 66 additions & 0 deletions plugin/plugins/dynamix.unraid.net.plg
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
<!ENTITY txz_sha256 "">
<!ENTITY txz_url "">
<!ENTITY txz_name "">
<!ENTITY core_source "/boot/config/plugins/dynamix.my.servers/&core_txz_name;">
<!ENTITY core_txz_sha256 "ffa96c37f258149b4582dd4480ce4ca9e543bc2281d2e9de6729cbe598e68383">
<!ENTITY core_txz_url "https://pub-7247242eea6d482488594f04a3d7d4be.r2.dev/unraid-0.1.0-2026.01.15.1.txz">
<!ENTITY core_txz_name "unraid-0.1.0-2026.01.15.1.txz">
<!ENTITY arch "x86_64">
<!ENTITY build "1">
<!ENTITY tag "">
Expand Down Expand Up @@ -52,6 +56,12 @@ exit 0
<SHA256>&txz_sha256;</SHA256>
</FILE>

<!-- download unraid core txz -->
<FILE Name="&core_source;">
<URL>&core_txz_url;</URL>
<SHA256>&core_txz_sha256;</SHA256>
</FILE>

<!-- Check for compatible Unraid version -->
<FILE Run="/usr/bin/php" Method="install">
<INLINE>
Expand Down Expand Up @@ -320,6 +330,21 @@ exit 0
fi
fi

# Stop and remove Unraid Core package
if [ -x "/etc/rc.d/rc.unraid" ]; then
echo "Stopping Unraid Core..."
/etc/rc.d/rc.unraid stop || echo "Warning: Failed to stop Unraid Core"
fi

core_pkg_installed=$(ls -1 /var/log/packages/unraid-* 2>/dev/null | head -1)
if [ -n "$core_pkg_installed" ]; then
core_pkg_basename=$(basename "$core_pkg_installed")
echo "Removing core package: $core_pkg_basename"
removepkg --terse "$core_pkg_basename"
else
echo "No Unraid Core package found"
fi
Comment on lines +333 to +346
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cat -n plugin/plugins/dynamix.unraid.net.plg | sed -n '333,346p'

Repository: unraid/api

Length of output: 722


🏁 Script executed:

# Check for package naming patterns in the codebase
rg "unraid-" plugin/plugins/dynamix.unraid.net.plg | head -20

Repository: unraid/api

Length of output: 1437


🏁 Script executed:

# Look for references to package removals or installations to understand naming conventions
rg "removepkg|installpkg|txz" plugin/plugins/dynamix.unraid.net.plg | head -30

Repository: unraid/api

Length of output: 1699


Use a more specific pattern for core package matching.

The glob pattern unraid-* on line 339 could match unrelated packages like unraid-api if they're installed in /var/log/packages/. Since the core package follows a version-based naming convention (e.g., unraid-0.1.0-2026.01.14.1), use:

Suggested fix
-      core_pkg_installed=$(ls -1 /var/log/packages/unraid-* 2>/dev/null | head -1)
+      core_pkg_installed=$(ls -1 /var/log/packages/unraid-[0-9]* 2>/dev/null | head -1)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Stop and remove Unraid Core package
if [ -x "/etc/rc.d/rc.unraid" ]; then
echo "Stopping Unraid Core..."
/etc/rc.d/rc.unraid stop || echo "Warning: Failed to stop Unraid Core"
fi
core_pkg_installed=$(ls -1 /var/log/packages/unraid-* 2>/dev/null | head -1)
if [ -n "$core_pkg_installed" ]; then
core_pkg_basename=$(basename "$core_pkg_installed")
echo "Removing core package: $core_pkg_basename"
removepkg --terse "$core_pkg_basename"
else
echo "No Unraid Core package found"
fi
# Stop and remove Unraid Core package
if [ -x "/etc/rc.d/rc.unraid" ]; then
echo "Stopping Unraid Core..."
/etc/rc.d/rc.unraid stop || echo "Warning: Failed to stop Unraid Core"
fi
core_pkg_installed=$(ls -1 /var/log/packages/unraid-[0-9]* 2>/dev/null | head -1)
if [ -n "$core_pkg_installed" ]; then
core_pkg_basename=$(basename "$core_pkg_installed")
echo "Removing core package: $core_pkg_basename"
removepkg --terse "$core_pkg_basename"
else
echo "No Unraid Core package found"
fi
🤖 Prompt for AI Agents
In `@plugin/plugins/dynamix.unraid.net.plg` around lines 333 - 346, Replace the
broad glob "unraid-*" used when setting core_pkg_installed with a
version-specific pattern or filter to avoid matching unrelated packages: update
the ls/grep invocation that assigns core_pkg_installed to only match names like
"unraid-" followed by a digit (e.g., use "unraid-[0-9]*" or pipe through grep -E
'^unraid-[0-9]') so core_pkg_installed and core_pkg_basename resolve to the
actual core package name and removepkg --terse is invoked only for that package.


# File restoration function
echo "Restoring files..."

Expand Down Expand Up @@ -404,6 +429,9 @@ exit 0
PKG_FILE="&source;" # Full path to the package file including .txz extension
PKG_URL="&txz_url;" # URL where package was downloaded from
PKG_NAME="&txz_name;" # Name of the package file
CORE_PKG_FILE="&core_source;"
CORE_PKG_URL="&core_txz_url;"
CORE_PKG_NAME="&core_txz_name;"
CONNECT_API_VERSION="&api_version;" # Version of API included with Connect
<![CDATA[
# Function to compare version numbers using PHP's version_compare
Expand Down Expand Up @@ -524,6 +552,37 @@ else
echo "Connect plugin remains installed but API was not modified"
fi

# Install Unraid Core package
if [ -f "$CORE_PKG_FILE" ]; then
echo "Installing Unraid Core package..."
# Clean up any old core package txz files if they don't match our current version
for txz_file in /boot/config/plugins/dynamix.my.servers/unraid-*.txz; do
if [ -f "$txz_file" ] && [ "$txz_file" != "${CORE_PKG_FILE}" ]; then
echo "Removing old core package file: $txz_file"
rm -f "$txz_file"
fi
done

# Stop the core service before mutating /usr/local/unraid
if [ -x "/etc/rc.d/rc.unraid" ]; then
echo "Stopping Unraid Core service before upgrade..."
/etc/rc.d/rc.unraid stop || echo "Warning: Failed to stop Unraid Core service"
fi

upgradepkg --install-new --reinstall "${CORE_PKG_FILE}"
if [ $? -ne 0 ]; then
echo "⚠️ Core package installation failed"
exit 1
fi

if [ -f "/etc/rc.d/rc.unraid" ]; then
chmod +x /etc/rc.d/rc.unraid
fi
else
echo "⚠️ Core package file not found: $CORE_PKG_FILE"
exit 1
fi

exit 0
]]>
</INLINE>
Expand Down Expand Up @@ -599,6 +658,13 @@ echo "If no additional messages appear within 30 seconds, it is safe to refresh
/etc/rc.d/rc.unraid-api start

echo "Unraid API service started"
if [ -x "/etc/rc.d/rc.unraid" ]; then
echo "Starting Unraid Core service"
/etc/rc.d/rc.unraid start
echo "Unraid Core service started"
else
echo "Warning: rc.unraid not found; core service not started"
fi
echo "✅ Installation is complete, it is safe to close this window"
echo
exit 0
Expand Down
89 changes: 89 additions & 0 deletions plugin/source/dynamix.unraid.net/etc/rc.d/rc.unraid
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#!/bin/bash
# /etc/rc.d/rc.unraid
# Unraid Phoenix Application Service

APP_DIR="/usr/local/unraid"
RELEASE_BIN="$APP_DIR/_build/prod/rel/unraid/bin/unraid"
CONFIG_DIR="/boot/config/unraid"
SOCKET_PATH="/var/run/unraid-core.sock"
LOG_PATH="${UNRAID_LOG_PATH:-/var/log/unraid-core.log}"

# Load user env if exists
[ -f "$CONFIG_DIR/env" ] && source "$CONFIG_DIR/env"

# Ensure config and log directories exist
mkdir -p "$CONFIG_DIR"
mkdir -p "$(dirname "$LOG_PATH")"
touch "$LOG_PATH"

# Generate secret_key_base if not exists
if [ ! -f "$CONFIG_DIR/secret_key_base" ]; then
head -c 64 /dev/urandom | base64 | tr -d '\n' > "$CONFIG_DIR/secret_key_base"
chmod 600 "$CONFIG_DIR/secret_key_base"
fi

export SECRET_KEY_BASE=$(cat "$CONFIG_DIR/secret_key_base")
export RELEASE_COOKIE=$(cat "$CONFIG_DIR/secret_key_base" | head -c 20)
export UNRAID_CONFIG_DIR="$CONFIG_DIR"
export RUN_ERL_LOG="${RUN_ERL_LOG:-$LOG_PATH}"
export RELEASE_LOG_DIR="${RELEASE_LOG_DIR:-$(dirname "$LOG_PATH")}"
export RELEASE_NODE="${UNRAID_RELEASE_NODE:-unraid}"
export RELEASE_DISTRIBUTION="${UNRAID_RELEASE_DISTRIBUTION:-sname}"
export RELEASE_MODE="${UNRAID_RELEASE_MODE:-interactive}"

# Import user's runtime.exs if exists
[ -f "$CONFIG_DIR/runtime.exs" ] && export RELEASE_CONFIG_DIR="$CONFIG_DIR"

# Socket/port configuration
if [ -n "${UNRAID_PORT:-}" ]; then
export PHX_PORT="$UNRAID_PORT"
else
export PHX_SOCKET="${UNRAID_SOCKET:-$SOCKET_PATH}"
fi

start() {
echo -n "Starting Unraid... "
[ -S "$SOCKET_PATH" ] && rm -f "$SOCKET_PATH"
"$RELEASE_BIN" daemon
echo "done"
}

stop() {
echo -n "Stopping Unraid... "
"$RELEASE_BIN" stop 2>/dev/null || true
[ -S "$SOCKET_PATH" ] && rm -f "$SOCKET_PATH"
echo "done"
}

restart() {
stop
sleep 2
start
}

status() {
"$RELEASE_BIN" pid >/dev/null 2>&1 && echo "Running" || echo "Stopped"
}

rollback() {
if [ -d "/usr/local/unraid.prev" ]; then
echo "Rolling back to previous version..."
stop
rm -rf /usr/local/unraid
mv /usr/local/unraid.prev /usr/local/unraid
start
echo "Rollback complete"
else
echo "No previous version available"
exit 1
fi
}
Comment on lines +68 to +80
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Rollback operation is not atomic and risks data loss.

If the mv command on line 72 fails after rm -rf on line 71, the system will be left without any installation. Consider a safer swap approach:

🔧 Suggested safer rollback
 rollback() {
     if [ -d "/usr/local/unraid.prev" ]; then
         echo "Rolling back to previous version..."
         stop
-        rm -rf /usr/local/unraid
-        mv /usr/local/unraid.prev /usr/local/unraid
+        # Atomic swap: rename current to .old, then prev to current
+        rm -rf /usr/local/unraid.old 2>/dev/null
+        mv /usr/local/unraid /usr/local/unraid.old && \
+        mv /usr/local/unraid.prev /usr/local/unraid && \
+        rm -rf /usr/local/unraid.old
         start
         echo "Rollback complete"
     else
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
rollback() {
if [ -d "/usr/local/unraid.prev" ]; then
echo "Rolling back to previous version..."
stop
rm -rf /usr/local/unraid
mv /usr/local/unraid.prev /usr/local/unraid
start
echo "Rollback complete"
else
echo "No previous version available"
exit 1
fi
}
rollback() {
if [ -d "/usr/local/unraid.prev" ]; then
echo "Rolling back to previous version..."
stop
rm -rf /usr/local/unraid.old 2>/dev/null
mv /usr/local/unraid /usr/local/unraid.old && \
mv /usr/local/unraid.prev /usr/local/unraid && \
rm -rf /usr/local/unraid.old
start
echo "Rollback complete"
else
echo "No previous version available"
exit 1
fi
}
🤖 Prompt for AI Agents
In `@plugin/source/dynamix.unraid.net/etc/rc.d/rc.unraid` around lines 67 - 79,
The rollback() function currently does rm -rf /usr/local/unraid then mv
/usr/local/unraid.prev /usr/local/unraid which is not atomic and can leave the
system without an installation if mv fails; change to a safer three-step swap:
rename the current dir to a temp backup (e.g., mv /usr/local/unraid
/usr/local/unraid.tmp), then mv /usr/local/unraid.prev to /usr/local/unraid, and
only after verifying that succeeds remove the temp backup; ensure each mv is
checked for failure and on any error attempt to restore from the temp backup and
return a non-zero exit code so rollback is atomic and recoverable, updating the
rollback() function and its error handling accordingly.


case "${1:-}" in
start) start ;;
stop) stop ;;
restart) restart ;;
status) status ;;
rollback) rollback ;;
*) echo "Usage: $0 {start|stop|restart|status|rollback}" ;;
esac
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/sh
# Stop Unraid Core on shutdown/reboot

if [ -x /etc/rc.d/rc.unraid ]; then
echo "Stopping Unraid Core..."
/etc/rc.d/rc.unraid stop
fi
2 changes: 1 addition & 1 deletion plugin/source/dynamix.unraid.net/install/doinst.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ backup_file_if_exists() {
fi
}

for f in etc/rc.d/rc6.d/K*unraid-api etc/rc.d/rc6.d/K*flash-backup; do
for f in etc/rc.d/rc6.d/K*unraid-api etc/rc.d/rc6.d/K*unraid-core etc/rc.d/rc6.d/K*flash-backup; do
[ -e "$f" ] && chmod 755 "$f"
done

Expand Down
Loading
Loading