mirror of
https://github.com/unraid/api.git
synced 2026-01-02 14:40:01 -06:00
Compare commits
19 Commits
feat/serve
...
feat-flash
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7b767f7bdf | ||
|
|
31a5413643 | ||
|
|
a95fc5ed07 | ||
|
|
fcd7bb790e | ||
|
|
008e10948e | ||
|
|
c97a4f1268 | ||
|
|
3eba95b8cc | ||
|
|
2bf8f0b937 | ||
|
|
9ae45d1258 | ||
|
|
1835a4cf3f | ||
|
|
2ab44b894d | ||
|
|
1108f49b07 | ||
|
|
cc69213beb | ||
|
|
460e557dd8 | ||
|
|
05e29468d2 | ||
|
|
4d3a311fb4 | ||
|
|
bc62d210ec | ||
|
|
43d3ea6553 | ||
|
|
882e3e1ef4 |
@@ -2,6 +2,13 @@
|
||||
|
||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
||||
|
||||
## [3.6.0](https://github.com/unraid/api/compare/v3.5.3...v3.6.0) (2024-03-26)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* server config enum message w/ ineligible support ([#861](https://github.com/unraid/api/issues/861)) ([4d3a351](https://github.com/unraid/api/commit/4d3a3510777090788573f4cee83694a0dc6f8df5))
|
||||
|
||||
### [3.5.3](https://github.com/unraid/api/compare/v3.5.2...v3.5.3) (2024-03-25)
|
||||
|
||||
|
||||
|
||||
58
api/README.md
Normal file
58
api/README.md
Normal file
@@ -0,0 +1,58 @@
|
||||
# @unraid/api
|
||||
|
||||
## Installation
|
||||
|
||||
Install the production plugin via the apps tab (search for "my servers") on Unraid 6.9.2 or later.
|
||||
|
||||
## CLI
|
||||
|
||||
If you're on a unraid v6.9.2 or later machine this should be available by running `unraid-api` in any directory.
|
||||
|
||||
```bash
|
||||
root@Devon:~# unraid-api
|
||||
|
||||
Unraid API
|
||||
|
||||
Thanks for using the official Unraid API
|
||||
|
||||
Usage:
|
||||
|
||||
$ unraid-api command <options>
|
||||
|
||||
Commands:
|
||||
|
||||
start/stop/restart/version/status/report/switch-env
|
||||
|
||||
Options:
|
||||
|
||||
-h, --help Prints this usage guide.
|
||||
-d, --debug Enabled debug mode.
|
||||
-p, --port string Set the graphql port.
|
||||
--environment production/staging/development Set the working environment.
|
||||
--log-level ALL/TRACE/DEBUG/INFO/WARN/ERROR/FATAL/MARK/OFF Set the log level.
|
||||
|
||||
Copyright © 2022 Lime Technology, Inc.
|
||||
|
||||
```
|
||||
|
||||
## Report
|
||||
To view the current status of the unraid-api and its connection to mothership, run:
|
||||
```
|
||||
unraid-api report
|
||||
```
|
||||
|
||||
To view verbose data (anonymized), run:
|
||||
```
|
||||
unraid-api report -v
|
||||
```
|
||||
|
||||
To view non-anonymized verbose data, run:
|
||||
```
|
||||
unraid-api report -vv
|
||||
```
|
||||
|
||||
## Secrets
|
||||
If you found this file you're likely a developer. If you'd like to know more about the API and when it's available please join [our discord](https://discord.unraid.net/).
|
||||
|
||||
## License
|
||||
Copyright 2019-2022 Lime Technology Inc. All rights reserved.
|
||||
4
api/package-lock.json
generated
4
api/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@unraid/api",
|
||||
"version": "3.5.3",
|
||||
"version": "3.6.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@unraid/api",
|
||||
"version": "3.5.3",
|
||||
"version": "3.6.0",
|
||||
"license": "UNLICENSED",
|
||||
"dependencies": {
|
||||
"@apollo/client": "^3.8.9",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@unraid/api",
|
||||
"version": "3.5.3",
|
||||
"version": "3.6.0",
|
||||
"main": "dist/index.js",
|
||||
"bin": "dist/unraid-api.cjs",
|
||||
"type": "module",
|
||||
|
||||
@@ -502,24 +502,94 @@ if test -f "${FILE}" && grep -q "top.Shadowbox" "${FILE}" &>/dev/null; then
|
||||
sed -i 's/top.Shadowbox/parent.Shadowbox/gm' "${FILE}"
|
||||
fi
|
||||
|
||||
# ensure _var() is defined
|
||||
# brings older versions of Unraid in sync with 6.12.0
|
||||
# ensure _var() is defined, brings older versions of Unraid in sync with 6.12.0
|
||||
FILE=/usr/local/emhttp/plugins/dynamix/include/Wrappers.php
|
||||
if test -f "${FILE}" && ! grep -q "_var" "${FILE}" &>/dev/null; then
|
||||
TEXT=$(
|
||||
if test -f "${FILE}" && ! grep -q "function _var" "${FILE}" &>/dev/null; then
|
||||
ADDTEXT1=$(
|
||||
cat <<'END_HEREDOC'
|
||||
// backported by Unraid Connect
|
||||
function _var(&$name, $key=null, $default='') {
|
||||
return is_null($key) ? ($name ?? $default) : ($name[$key] ?? $default);
|
||||
}
|
||||
?>
|
||||
END_HEREDOC
|
||||
)
|
||||
fi
|
||||
# ensure my_logger() is defined, brings older versions of Unraid in sync with 6.13.0
|
||||
if test -f "${FILE}" && ! grep -q "function my_logger" "${FILE}" &>/dev/null; then
|
||||
ADDTEXT2=$(
|
||||
cat <<'END_HEREDOC'
|
||||
// backported by Unraid Connect
|
||||
// ensure params passed to logger are properly escaped
|
||||
function my_logger($message, $logger='webgui') {
|
||||
exec('logger -t '.escapeshellarg($logger).' -- '.escapeshellarg($message));
|
||||
}
|
||||
END_HEREDOC
|
||||
)
|
||||
fi
|
||||
# ensure http_get_contents() is defined, brings older versions of Unraid in sync with 6.13.0
|
||||
if test -f "${FILE}" && ! grep -q "function http_get_contents" "${FILE}" &>/dev/null; then
|
||||
ADDTEXT3=$(
|
||||
cat <<'END_HEREDOC'
|
||||
// backported by Unraid Connect
|
||||
// Original PHP code by Chirp Internet: www.chirpinternet.eu
|
||||
// Please acknowledge use of this code by including this header.
|
||||
// https://www.the-art-of-web.com/php/http-get-contents/
|
||||
// Modified for Unraid
|
||||
/**
|
||||
* Fetches URL and returns content
|
||||
* @param string $url The URL to fetch
|
||||
* @param array $opts Array of options to pass to curl_setopt()
|
||||
* @param array $getinfo Empty array passed by reference, will contain results of curl_getinfo and curl_error
|
||||
* @return string|false $out The fetched content
|
||||
*/
|
||||
function http_get_contents(string $url, array $opts = [], array &$getinfo = NULL) {
|
||||
$ch = curl_init();
|
||||
if(isset($getinfo)) {
|
||||
curl_setopt($ch, CURLINFO_HEADER_OUT, TRUE);
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 45);
|
||||
curl_setopt($ch, CURLOPT_ENCODING, "");
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
|
||||
curl_setopt($ch, CURLOPT_REFERER, "");
|
||||
curl_setopt($ch, CURLOPT_FAILONERROR, true);
|
||||
if(is_array($opts) && $opts) {
|
||||
foreach($opts as $key => $val) {
|
||||
curl_setopt($ch, $key, $val);
|
||||
}
|
||||
}
|
||||
$out = curl_exec($ch);
|
||||
if(isset($getinfo)) {
|
||||
$getinfo = curl_getinfo($ch);
|
||||
}
|
||||
if (curl_errno($ch)) {
|
||||
$msg = curl_error($ch) . " {$url}";
|
||||
if(isset($getinfo)) {
|
||||
$getinfo['error'] = $msg;
|
||||
}
|
||||
my_logger($msg, "http_get_contents");
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
END_HEREDOC
|
||||
)
|
||||
fi
|
||||
if [[ -n "${ADDTEXT1}" || -n "${ADDTEXT2}" || -n "${ADDTEXT3}" ]]; then
|
||||
TMP="$FILE.$RANDOM"
|
||||
cp -f "$FILE" "$TMP"
|
||||
cp -f "$FILE" "$FILE-"
|
||||
# delete last line of the file if it contains `?>`
|
||||
if test $( tail -n 1 "${FILE}" ) = '?>' ; then
|
||||
sed -i '$ d' "${FILE}"
|
||||
if test $( tail -n 1 "${TMP}" ) = '?>' ; then
|
||||
sed -i '$ d' "${TMP}"
|
||||
fi
|
||||
echo "${TEXT}" >>"${FILE}"
|
||||
[[ -n "${ADDTEXT1}" ]] && echo "${ADDTEXT1}" >>"${TMP}"
|
||||
[[ -n "${ADDTEXT2}" ]] && echo "${ADDTEXT2}" >>"${TMP}"
|
||||
[[ -n "${ADDTEXT3}" ]] && echo "${ADDTEXT3}" >>"${TMP}"
|
||||
echo "?>" >>"${TMP}"
|
||||
mv "${TMP}" "${FILE}"
|
||||
fi
|
||||
|
||||
# install the main txz
|
||||
@@ -613,6 +683,29 @@ if [[ "${CHANGED}" == "yes" ]]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
# Prevent web component file downgrade if the webgui version is newer than the plugin version
|
||||
plgWebComponentPath="/usr/local/emhttp/plugins/dynamix.my.servers/unraid-components"
|
||||
backupWebComponentPath="/usr/local/emhttp/plugins/dynamix.my.servers/unraid-components-"
|
||||
|
||||
# Function to extract "ts" value from JSON file
|
||||
extract_ts() {
|
||||
local filepath="$1"
|
||||
local ts_value=null
|
||||
ts_value=$(jq -r '.ts' "$filepath" 2>/dev/null)
|
||||
echo "$ts_value"
|
||||
}
|
||||
|
||||
# Extract "ts" values from both files
|
||||
plgManifestTs=$(extract_ts "$plgWebComponentPath/manifest.json")
|
||||
webguiManifestTs=$(extract_ts "$backupWebComponentPath/manifest.json")
|
||||
|
||||
# Compare the "ts" values and return the file path of the higher value
|
||||
if [[ "$webguiManifestTs" -gt "$plgManifestTs" ]]; then
|
||||
rm -rf "$plgWebComponentPath"
|
||||
mv "$backupWebComponentPath" "$plgWebComponentPath"
|
||||
echo "♻️ Reverted to stock web components"
|
||||
fi
|
||||
|
||||
# start background process to install/start the api and flash backup
|
||||
echo
|
||||
if [ -f /var/local/emhttp/var.ini ]; then
|
||||
|
||||
230
plugin/source/dynamix.unraid.net/etc/rc.d/rc.flash_backup
Executable file
230
plugin/source/dynamix.unraid.net/etc/rc.d/rc.flash_backup
Executable file
@@ -0,0 +1,230 @@
|
||||
#!/bin/bash
|
||||
# This file is /etc/rc.d/rc.flash_backup
|
||||
# use at queue "f" for flash backup
|
||||
QUEUE=" -q f "
|
||||
TASKNAME="/etc/rc.d/rc.flash_backup watch"
|
||||
TASKACTION="/usr/local/emhttp/plugins/dynamix.my.servers/scripts/UpdateFlashBackup update"
|
||||
last=$(date +%s)
|
||||
# set GIT_OPTIONAL_LOCKS=0 globally to reduce/eliminate writes to /boot
|
||||
export GIT_OPTIONAL_LOCKS=0
|
||||
|
||||
FAST=1 # 1 second delay when waiting for git
|
||||
SLOW=10 # 10 second delay when waiting for git
|
||||
# wait for existing git commands to complete
|
||||
# $1 is the time in seconds to sleep when waiting. SLOW or FAST
|
||||
_waitforgit() {
|
||||
while [[ $(pgrep -f '^git -C /boot' -c) -ne 0 ]]; do
|
||||
sleep "$1"
|
||||
done
|
||||
}
|
||||
# log to syslog, then wait for existing git commands to complete
|
||||
# $1 is the time in seconds to sleep when waiting. SLOW or FAST
|
||||
_waitforgitlog() {
|
||||
if [[ $(pgrep -f '^git -C /boot' -c) -ne 0 ]]; then
|
||||
logger "waiting for current backup to complete" --tag flash_backup
|
||||
_waitforgit "$1"
|
||||
fi
|
||||
}
|
||||
status() {
|
||||
_connected && CONNECTED="system is connected to Unraid Connect Cloud." || CONNECTED="system is not connected to Unraid Connect Cloud."
|
||||
if _watching; then
|
||||
echo "flash backup monitor is running. ${CONNECTED}"
|
||||
_hasqueue && echo "changes detected, backup queued."
|
||||
exit 0
|
||||
else
|
||||
if _enabled; then
|
||||
echo "flash backup is enabled but the monitor is not running. ${CONNECTED}"
|
||||
else
|
||||
echo "flash backup is disabled so the monitor is disabled. ${CONNECTED}"
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
start() {
|
||||
_start
|
||||
exit 0
|
||||
}
|
||||
stop() {
|
||||
_stop
|
||||
exit 0
|
||||
}
|
||||
reload() {
|
||||
_start
|
||||
sleep 1
|
||||
status
|
||||
}
|
||||
_start() {
|
||||
# Note: can start if not signed in, but watcher loop will not process until signed in
|
||||
# only run if flash_backup is enabled
|
||||
if ! _enabled; then
|
||||
logger "flash backup disabled, exiting" --tag flash_backup
|
||||
exit 1
|
||||
fi
|
||||
_stop
|
||||
# start watcher loop as background process
|
||||
exec ${TASKNAME} &>/dev/null &
|
||||
}
|
||||
_stop() {
|
||||
if _watching; then
|
||||
logger "stop watching for file changes" --tag flash_backup
|
||||
# terminate watcher loop/process
|
||||
pkill --full "${TASKNAME}" &>/dev/null
|
||||
fi
|
||||
# do not flush. better to have unsaved changes than to corrupt the backup during shutdown
|
||||
# note that an existing git process could still be running
|
||||
}
|
||||
flush() {
|
||||
# remove any queued jobs
|
||||
_removequeue
|
||||
# wait for existing git commands to finish before flushing
|
||||
_waitforgitlog "${FAST}"
|
||||
logger "flush: ${TASKACTION}" --tag flash_backup
|
||||
# if _connected, push any changes ad-hoc
|
||||
if _connected; then
|
||||
# shellcheck disable=SC2086
|
||||
echo "${TASKACTION}_nolimit &>/dev/null" | at ${QUEUE} -M now &>/dev/null
|
||||
fi
|
||||
}
|
||||
_watching() {
|
||||
local flash_backup_pid
|
||||
flash_backup_pid=$(pgrep --full "${TASKNAME}")
|
||||
if [[ ${flash_backup_pid} ]]; then
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
_watch() {
|
||||
# safely clean up git *.lock files
|
||||
_clearlocks
|
||||
# update a file in the repo to keep this repo alive
|
||||
_keepalive
|
||||
# flush: if connected, start the watch loop with a clean repo
|
||||
flush
|
||||
# wait for flush to complete
|
||||
sleep 3
|
||||
_waitforgitlog "${FAST}"
|
||||
logger "start watching for file changes" --tag flash_backup
|
||||
# start watcher loop
|
||||
timer=0
|
||||
incr=60
|
||||
max=$((60*60*24*7)) # one week
|
||||
while true; do
|
||||
# if system is connected to Unraid Connect Cloud, see if there are updates to process
|
||||
_connected && _f1
|
||||
if ((timer>max)); then
|
||||
# update a file in the repo once per max seconds to keep this repo alive
|
||||
_keepalive
|
||||
timer=0
|
||||
fi
|
||||
timer=$((timer+incr))
|
||||
sleep $incr
|
||||
done
|
||||
}
|
||||
_f1() {
|
||||
# wait for existing git commands to finish before checking for updates
|
||||
_waitforgit "${SLOW}"
|
||||
if [ "$(git -C /boot status -s)" ]; then
|
||||
_hasqueue || _f2
|
||||
elif _haserror && _beenawhile; then
|
||||
# we are in an error state and it has been 3 hours since we last tried submitting. run the task now.
|
||||
_runtaskaction
|
||||
fi
|
||||
}
|
||||
_f2() {
|
||||
if ! _haserror || [[ $(($(date +"%M") % 10)) -eq 0 ]]; then
|
||||
logger "adding task: ${TASKACTION}" --tag flash_backup
|
||||
fi
|
||||
sed -i "s@uptodate=yes@uptodate=no@" /var/local/emhttp/flashbackup.ini &>/dev/null
|
||||
_runtaskaction
|
||||
}
|
||||
_hasqueue() {
|
||||
# returns false if the queue is empty, true otherwise
|
||||
# shellcheck disable=SC2086
|
||||
if [ -z "$(atq ${QUEUE})" ]; then
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
_removequeue() {
|
||||
# delete any at jobs in queue f
|
||||
# @TODO shellcheck SC2162
|
||||
# shellcheck disable=SC2086
|
||||
atq ${QUEUE} | while read line; do
|
||||
id=$(echo ${line} | cut -d " " -f 1)
|
||||
atrm ${id}
|
||||
done
|
||||
}
|
||||
_runtaskaction() {
|
||||
# shellcheck disable=SC2086
|
||||
echo "${TASKACTION} &>/dev/null" | at ${QUEUE} -M now +1 minute &>/dev/null
|
||||
last=$(date +%s)
|
||||
}
|
||||
_enabled() {
|
||||
local output
|
||||
output=$(git -C /boot config --get remote.origin.url 2>&1)
|
||||
if [[ "${output}" == *"backup.unraid.net"* ]]; then
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
_connected() {
|
||||
CFG=/var/local/emhttp/myservers.cfg
|
||||
[[ ! -f "${CFG}" ]] && return 1
|
||||
# shellcheck disable=SC1090
|
||||
source <(sed -nr '/\[connectionStatus\]/,/\[/{/minigraph/p}' "${CFG}" 2>/dev/null)
|
||||
if [[ -z "${minigraph}" || "${minigraph}" != "CONNECTED" ]]; then
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
_haserror() {
|
||||
errorstring=$(awk -F "=" '/error/ {print $2}' /var/local/emhttp/flashbackup.ini 2>&1 || echo '')
|
||||
if [ ${#errorstring} -le 2 ]; then
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
_beenawhile() {
|
||||
now=$(date +%s)
|
||||
age=$((now - last))
|
||||
maxage=$((3 * 60 * 60)) # three hours
|
||||
[[ $age -gt $maxage ]] && return 0
|
||||
return 1
|
||||
}
|
||||
# wait for git commands to end, then delete any stale lock files
|
||||
_clearlocks() {
|
||||
_waitforgitlog "${FAST}"
|
||||
find /boot/.git -type f -name '*.lock' -delete
|
||||
}
|
||||
# this function updates a file on the flash drive to trigger a git update
|
||||
# do this regardless of whether the system is _connected
|
||||
_keepalive() {
|
||||
file=/boot/config/plugins/dynamix.my.servers/fb_keepalive
|
||||
[[ ! -d "$(dirname "${file}")" ]] && return 1
|
||||
logger "trigger flash backup keepalive" --tag flash_backup
|
||||
date +'%s' > "${file}" 2>/dev/null
|
||||
return 0
|
||||
}
|
||||
case "$1" in
|
||||
'status')
|
||||
status
|
||||
;;
|
||||
'start')
|
||||
start
|
||||
;;
|
||||
'stop')
|
||||
stop
|
||||
;;
|
||||
'reload')
|
||||
reload
|
||||
;;
|
||||
'flush')
|
||||
flush
|
||||
;;
|
||||
'watch')
|
||||
_watch
|
||||
;;
|
||||
*)
|
||||
echo "usage $0 status|start|stop|reload|flush"
|
||||
;;
|
||||
esac
|
||||
182
plugin/source/dynamix.unraid.net/etc/rc.d/rc.unraid-api
Executable file
182
plugin/source/dynamix.unraid.net/etc/rc.d/rc.unraid-api
Executable file
@@ -0,0 +1,182 @@
|
||||
#!/bin/bash
|
||||
# unraid-api-handler
|
||||
flash="/boot/config/plugins/dynamix.my.servers"
|
||||
[[ ! -d "${flash}" ]] && echo "Please reinstall the Unraid Connect plugin" && exit 1
|
||||
[[ ! -f "${flash}/env" ]] && echo 'env=production' >"${flash}/env"
|
||||
# define env to avoid shellcheck SC2154. Will be overridden by the source command below
|
||||
env=production
|
||||
# shellcheck disable=SC1091
|
||||
source "${flash}/env"
|
||||
api_base_directory="/usr/local/bin"
|
||||
|
||||
# Only allow specific envs
|
||||
if [ "${env}" != "staging" ] && [ "${env}" != "production" ]; then
|
||||
echo "\"${env}\" is an unsupported env. Please use \"staging\" or \"production\"."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
switchenv() {
|
||||
stop
|
||||
# Get current environment from file
|
||||
local envFile="${flash}/env"
|
||||
local currentEnv
|
||||
currentEnv=$(
|
||||
# shellcheck disable=SC1090
|
||||
source "${envFile}"
|
||||
echo "${env}"
|
||||
)
|
||||
|
||||
if [[ "${currentEnv}" = "production" ]]; then
|
||||
echo "Switching from production to staging"
|
||||
echo 'env="staging"' >"${envFile}"
|
||||
cp "${api_base_directory}/unraid-api/.env.staging" "${api_base_directory}/unraid-api/.env"
|
||||
elif [[ "${currentEnv}" = "staging" ]]; then
|
||||
echo "Switching from staging to production"
|
||||
echo 'env="production"' >"${envFile}"
|
||||
cp "${api_base_directory}/unraid-api/.env.production" "${api_base_directory}/unraid-api/.env"
|
||||
fi
|
||||
echo "Run \"unraid-api start\" to start the API."
|
||||
}
|
||||
raiseloglevel() {
|
||||
kill -s SIGUSR2 "$(pidof unraid-api)"
|
||||
}
|
||||
lowerloglevel() {
|
||||
kill -s SIGUSR1 "$(pidof unraid-api)"
|
||||
}
|
||||
status() {
|
||||
LOG_TYPE=raw "${api_base_directory}/unraid-api/unraid-api" status
|
||||
}
|
||||
start() {
|
||||
LOG_TYPE=raw "${api_base_directory}/unraid-api/unraid-api" start 2>&1 | logger &
|
||||
}
|
||||
report() {
|
||||
LOG_TYPE=raw "${api_base_directory}/unraid-api/unraid-api" report "$1" "$2"
|
||||
}
|
||||
startdebug() {
|
||||
LOG_CONTEXT=true LOG_STACKTRACE=true LOG_TRACING=true LOG_LEVEL=debug "${api_base_directory}/unraid-api/unraid-api" start --debug
|
||||
}
|
||||
stop() {
|
||||
LOG_TYPE=raw "${api_base_directory}/unraid-api/unraid-api" stop 2>/dev/null
|
||||
}
|
||||
reload() {
|
||||
LOG_TYPE=raw "${api_base_directory}/unraid-api/unraid-api" restart
|
||||
}
|
||||
_install() {
|
||||
# process file from commandline
|
||||
if [[ -n "$1" ]]; then
|
||||
file=$(realpath "${flash}/$1")
|
||||
if [[ "${file}" == "${flash}"* ]] && [[ "${file}" == *".tgz" || "${file}" == *".zip" ]] && [[ -f "${file}" ]]; then
|
||||
[[ "${file}" == *".tgz" ]] && ext=tgz || ext=zip
|
||||
echo "installing $1"
|
||||
cp "${file}" "${flash}/unraid-api.${ext}"
|
||||
else
|
||||
echo "invalid installation file: $1"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# If this was downloaded from a Github action it'll be a zip with a tgz inside
|
||||
# Let's extract the tgz and rename it for the next step
|
||||
if [[ -f "${flash}/unraid-api.zip" ]]; then
|
||||
for f in ${flash}/unraid-api.zip; do unzip -p "${f}" >"${flash}/${f%.zip}.tgz"; done
|
||||
rm -f "${flash}/unraid-api.zip"
|
||||
fi
|
||||
|
||||
# Ensure installation tgz exists
|
||||
[[ ! -f "${flash}/unraid-api.tgz" ]] && echo "Please reinstall the Unraid Connect plugin" && exit 1
|
||||
|
||||
# Stop old process
|
||||
[[ -f "${api_base_directory}/unraid-api/unraid-api" ]] && stop
|
||||
|
||||
# Install unraid-api
|
||||
rm -rf "${api_base_directory}/unraid-api"
|
||||
mkdir -p "${api_base_directory}/unraid-api"
|
||||
tar -C "${api_base_directory}/unraid-api" -xzf "${flash}/unraid-api.tgz" --strip 1
|
||||
|
||||
# Reset permissions
|
||||
rm -f "${flash}/data/permissions.json"
|
||||
|
||||
# Copy env file
|
||||
cp "${api_base_directory}/unraid-api/.env.${env}" "${api_base_directory}/unraid-api/.env"
|
||||
|
||||
# Copy wc files from flash
|
||||
if [ -f "${flash}/webComps/unraid.min.js" ]; then
|
||||
rm -rf /usr/local/emhttp/webGui/webComps
|
||||
mkdir -p /usr/local/emhttp/webGui/webComps
|
||||
cp ${flash}/webComps/* /usr/local/emhttp/webGui/webComps
|
||||
else
|
||||
# not fatal, previous version of unraid.min.js should still exist in /usr/local/emhttp/webGui/webComps
|
||||
echo "Note: ${flash}/webComps/unraid.min.js is missing"
|
||||
fi
|
||||
|
||||
# bail if expected file does not exist
|
||||
[[ ! -f "${api_base_directory}/unraid-api/unraid-api" ]] && echo "unraid-api install failed" && exit 1
|
||||
}
|
||||
install() {
|
||||
# Install the files
|
||||
_install "$1"
|
||||
|
||||
# if nginx is running, start the api. if not, it will be started by rc.nginx
|
||||
if /etc/rc.d/rc.nginx status &>/dev/null; then
|
||||
# Start new process
|
||||
start
|
||||
# Note: do not run another unraid-api command until you see "UNRAID API started successfully!" in syslog
|
||||
sleep 3
|
||||
echo "unraid-api installed and started"
|
||||
else
|
||||
echo "unraid-api installed"
|
||||
fi
|
||||
exit 0
|
||||
}
|
||||
uninstall() {
|
||||
# Stop old process
|
||||
[[ -f "${api_base_directory}/unraid-api/unraid-api" ]] && stop
|
||||
|
||||
# Remove all unraid-api files
|
||||
rm -rf "${api_base_directory}/unraid-api"
|
||||
rm -f /var/run/unraid-api.sock
|
||||
}
|
||||
case "$1" in
|
||||
'status')
|
||||
status
|
||||
;;
|
||||
'start')
|
||||
start
|
||||
;;
|
||||
'report')
|
||||
report "$2" "$3"
|
||||
;;
|
||||
'switch-env')
|
||||
switchenv
|
||||
;;
|
||||
'start-debug')
|
||||
startdebug
|
||||
;;
|
||||
'raise-log-level')
|
||||
raiseloglevel
|
||||
;;
|
||||
'lower-log-level')
|
||||
lowerloglevel
|
||||
;;
|
||||
'stop')
|
||||
stop
|
||||
;;
|
||||
'reload')
|
||||
reload
|
||||
;;
|
||||
'restart')
|
||||
reload
|
||||
;;
|
||||
'install')
|
||||
install "$2"
|
||||
;;
|
||||
'_install')
|
||||
_install "$2"
|
||||
;;
|
||||
'uninstall')
|
||||
uninstall
|
||||
;;
|
||||
*)
|
||||
echo "usage $0 status|start|report|switch-env|start-debug|raise-log-level|lower-log-level|stop|reload|install|uninstall"
|
||||
;;
|
||||
esac
|
||||
@@ -14,6 +14,7 @@ Tag="globe"
|
||||
* all copies or substantial portions of the Software.
|
||||
*/
|
||||
require_once "$docroot/plugins/dynamix.my.servers/include/state.php";
|
||||
require_once "$docroot/webGui/include/Wrappers.php";
|
||||
$serverState = new ServerState();
|
||||
|
||||
$keyfile = $serverState->keyfileBase64;
|
||||
@@ -521,7 +522,7 @@ _(Allow Remote Access)_:
|
||||
<?if(!$isRegistered): // NOTE: manually added close tags so the next section would not be indented ?>
|
||||
: <span><i class="fa fa-warning icon warning"></i> _(Disabled until you have signed in)_</span></dd></dl>
|
||||
<?elseif(!$isMiniGraphConnected && $myServersFlashCfg['remote']['wanaccess']!="yes"): // NOTE: manually added close tags so the next section would not be indented ?>
|
||||
: <span><i class="fa fa-warning icon warning"></i> _(Disabled until connected to Unraid Connect Cloud)_</span></dd></dl>
|
||||
: <span><i class="fa fa-warning icon warning"></i> _(Disabled until connected to Unraid Connect Cloud - try reloading the page)_</span></dd></dl>
|
||||
<?elseif(!$hasMyUnraidNetCert): // NOTE: manually added close tags so the next section would not be indented ?>
|
||||
: <span><i class="fa fa-warning icon warning"></i> _(Disabled until you Provision a myunraid.net SSL Cert)_</span><input type="hidden" id="wanport" value="0"></dd></dl>
|
||||
<?elseif(!$boolWebUIAuth): // NOTE: manually added close tags so the next section would not be indented ?>
|
||||
@@ -546,7 +547,7 @@ _(Allow Remote Access)_:
|
||||
<?endif?>
|
||||
|
||||
|
||||
: <unraid-i18n-host><unraid-wan-ip-check php-wan-ip="<?=@file_get_contents('https://wanip4.unraid.net/')?>"></unraid-wan-ip-check></unraid-i18n-host>
|
||||
: <unraid-i18n-host><unraid-wan-ip-check php-wan-ip="<?=http_get_contents('https://wanip4.unraid.net/')?>"></unraid-wan-ip-check></unraid-i18n-host>
|
||||
|
||||
<div markdown="1" id="wanpanel" style="display:'none'">
|
||||
|
||||
@@ -626,8 +627,8 @@ _(Enable Transparent 2FA for Local Access)_<!-- do not index -->:
|
||||
_(Flash backup)_:
|
||||
<?if(!$isRegistered):?>
|
||||
: <span><i class="fa fa-warning icon warning"></i> _(Disabled until you have signed in)_</span>
|
||||
<?elseif(!$isMiniGraphConnected && empty($flashbackup_status['activated'])):?>
|
||||
: <span><i class="fa fa-warning icon warning"></i> _(Disabled until connected to Unraid Connect Cloud)_</span>
|
||||
<?elseif(!$isMiniGraphConnected):?>
|
||||
: <span><i class="fa fa-warning icon warning"></i> _(Disabled until connected to Unraid Connect Cloud - try reloading the page)_</span>
|
||||
<?else: // begin show flash backup form ?>
|
||||
: <span id='flashbackuptext'><span class='blue p0'>_(Loading)_ <i class="fa fa-spinner fa-spin" aria-hidden="true"></i></span></span>
|
||||
|
||||
|
||||
@@ -70,8 +70,8 @@ function save_flash_backup_state($loading='') {
|
||||
rename($flashbackup_tmp, $flashbackup_ini);
|
||||
}
|
||||
|
||||
function load_flash_backup_state() {
|
||||
global $arrState,$flashbackup_ini,$isRegistered;
|
||||
function default_flash_backup_state() {
|
||||
global $arrState;
|
||||
|
||||
$arrState = [
|
||||
'activated' => 'no',
|
||||
@@ -80,6 +80,12 @@ function load_flash_backup_state() {
|
||||
'error' => '',
|
||||
'remoteerror' => ''
|
||||
];
|
||||
}
|
||||
|
||||
function load_flash_backup_state() {
|
||||
global $arrState,$flashbackup_ini,$isRegistered;
|
||||
|
||||
default_flash_backup_state();
|
||||
|
||||
$arrNewState = (file_exists($flashbackup_ini)) ? @parse_ini_file($flashbackup_ini) : [];
|
||||
if ($arrNewState) {
|
||||
@@ -277,7 +283,14 @@ if ($pgrep_output[0] != "0") {
|
||||
|
||||
// check if signed-in
|
||||
if (!$isRegistered) {
|
||||
response_complete(406, array('error' => 'Must be signed in to My Servers to use Flash Backup'));
|
||||
default_flash_backup_state();
|
||||
response_complete(406, array('error' => 'Must be signed in to Unraid Connect to use Flash Backup'));
|
||||
}
|
||||
|
||||
// check if connected to Unraid Connect Cloud
|
||||
if (!$isConnected) {
|
||||
default_flash_backup_state();
|
||||
response_complete(406, array('error' => 'Must be connected to Unraid Connect Cloud to use Flash Backup'));
|
||||
}
|
||||
|
||||
// keyfile
|
||||
@@ -422,29 +435,29 @@ if (!file_exists('/boot/.git/info/exclude')) {
|
||||
}
|
||||
|
||||
// setup a nice git description
|
||||
$gitdesc_text='Unraid flash drive for '.$var['NAME']."\n";
|
||||
$gitdesc_file='/boot/.git/description';
|
||||
if (!file_exists($gitdesc_file) || strpos(file_get_contents($gitdesc_file),$var['NAME']) === false) {
|
||||
file_put_contents($gitdesc_file, 'Unraid flash drive for '.$var['NAME']."\n");
|
||||
if (!file_exists($gitdesc_file) || (file_get_contents($gitdesc_file) != $gitdesc_text)) {
|
||||
file_put_contents($gitdesc_file, $gitdesc_text);
|
||||
}
|
||||
|
||||
// configure git to use the noprivatekeys filter
|
||||
set_git_config('filter.noprivatekeys.clean', '/usr/local/emhttp/plugins/dynamix.my.servers/scripts/git-noprivatekeys-clean');
|
||||
|
||||
// configure git to apply the noprivatekeys filter to wireguard config files
|
||||
$gitattributes_file='/boot/.gitattributes';
|
||||
if (!file_exists($gitattributes_file) || strpos(file_get_contents($gitattributes_file),'noprivatekeys') === false) {
|
||||
file_put_contents($gitattributes_file, '# file managed by Unraid, do not modify
|
||||
$gitattributes_text='# file managed by Unraid, do not modify
|
||||
config/wireguard/*.cfg filter=noprivatekeys
|
||||
config/wireguard/*.conf filter=noprivatekeys
|
||||
config/wireguard/peers/*.conf filter=noprivatekeys
|
||||
');
|
||||
';
|
||||
$gitattributes_file='/boot/.gitattributes';
|
||||
if (!file_exists($gitattributes_file) || (file_get_contents($gitattributes_file) != $gitattributes_text)) {
|
||||
file_put_contents($gitattributes_file, $gitattributes_text);
|
||||
}
|
||||
|
||||
// setup git ignore for files we dont need in the flash backup
|
||||
$gitexclude_file='/boot/.git/info/exclude';
|
||||
if (!file_exists($gitexclude_file) || strpos(file_get_contents($gitexclude_file),'# version 1.0') === false) {
|
||||
file_put_contents($gitexclude_file, '# file managed by Unraid, do not modify
|
||||
# version 1.0
|
||||
// setup master git exclude file to specify what to include/exclude from repo
|
||||
$gitexclude_text = '# file managed by Unraid, do not modify
|
||||
# version 1.1
|
||||
|
||||
# Blacklist everything
|
||||
/*
|
||||
@@ -480,7 +493,18 @@ config/plugins-error
|
||||
config/plugins-old-versions
|
||||
config/plugins/dockerMan/images
|
||||
config/wireguard/peers/*.png
|
||||
');
|
||||
';
|
||||
|
||||
// find large files to exclude from flash backup
|
||||
$oversize_files = $return_var = null;
|
||||
exec('find /boot/config -type f -size +30M 2>/dev/null | sed "s|^/boot/||g" 2>/dev/null', $oversize_files, $return_var);
|
||||
if ($oversize_files && is_array($oversize_files)) {
|
||||
$gitexclude_text .= "\n# Blacklist large files on this system\n".implode("\n", $oversize_files)."\n";
|
||||
}
|
||||
|
||||
$gitexclude_file='/boot/.git/info/exclude';
|
||||
if (!file_exists($gitexclude_file) || (file_get_contents($gitexclude_file) != $gitexclude_text)) {
|
||||
file_put_contents($gitexclude_file, $gitexclude_text);
|
||||
}
|
||||
|
||||
// ensure git user is configured
|
||||
@@ -529,7 +553,7 @@ if (empty($SSH_PORT)) {
|
||||
} else {
|
||||
$arrState['loading'] = '';
|
||||
if (stripos(implode($ssh_output),'permission denied') !== false) {
|
||||
$arrState['error'] = ($isConnected) ? 'Permission Denied' : 'Permission Denied, ensure you are connected to My Servers Cloud';
|
||||
$arrState['error'] = ($isConnected) ? 'Permission Denied' : 'Permission Denied, ensure you are connected to Unraid Connect Cloud';
|
||||
} else {
|
||||
$arrState['error'] = 'Unable to connect to backup.unraid.net:22';
|
||||
}
|
||||
@@ -557,7 +581,7 @@ if ($command == 'activate') {
|
||||
exec_log('git -C /boot checkout -B master origin/master');
|
||||
|
||||
// establish status
|
||||
exec_log('git -C /boot status --porcelain 2>&1', $status_output, $return_var);
|
||||
exec_log('git -C /boot status --porcelain', $status_output, $return_var);
|
||||
|
||||
if ($return_var != 0) {
|
||||
// detect git submodule
|
||||
@@ -600,7 +624,7 @@ if ($command == 'activate') {
|
||||
}
|
||||
|
||||
// detect corruption #1
|
||||
exec_log('git -C /boot show --summary 2>&1', $show_output, $return_var);
|
||||
exec_log('git -C /boot show --summary', $show_output, $return_var);
|
||||
if ($return_var != 0) {
|
||||
if (stripos(implode($show_output),'fatal: your current branch appears to be broken') !== false) {
|
||||
$arrState['error'] = 'Error: Backup corrupted';
|
||||
@@ -616,11 +640,21 @@ if ($command == 'activate') {
|
||||
} // end check for ($command == 'activate')
|
||||
|
||||
if ($command == 'update' || $command == 'activate') {
|
||||
|
||||
|
||||
// note: this section only runs if there are changes detected
|
||||
if ($arrState['uptodate'] == 'no') {
|
||||
// increment git commit counter
|
||||
appendToFile($commitCountFile, $time."\n");
|
||||
|
||||
// find files that are in repo but should not be, according to /boot/.git/info/exclude and various .gitignore files
|
||||
$invalid_files = $return_var = null;
|
||||
exec_log('git -C /boot ls-files --cached --ignored --exclude-standard', $invalid_files, $return_var);
|
||||
foreach ((array) $invalid_files as $invalid_file) {
|
||||
// remove each of these files from the repo
|
||||
// this prevents future changes from being tracked but does not remove the file from history.
|
||||
exec_log("git -C /boot rm --cached --ignore-unmatch '$invalid_file'");
|
||||
}
|
||||
|
||||
// add and commit all file changes
|
||||
exec_log('git -C /boot add -A');
|
||||
exec_log('git -C /boot commit -m ' . escapeshellarg($commitmsg));
|
||||
@@ -633,7 +667,7 @@ if ($command == 'update' || $command == 'activate') {
|
||||
if ($return_var != 0) {
|
||||
// check for permission denied
|
||||
if (stripos(implode($push_output),'permission denied') !== false) {
|
||||
$arrState['error'] = ($isConnected) ? 'Permission Denied' : 'Permission Denied, ensure you are connected to My Servers Cloud';
|
||||
$arrState['error'] = ($isConnected) ? 'Permission Denied' : 'Permission Denied, ensure you are connected to Unraid Connect Cloud';
|
||||
} elseif (stripos(implode($push_output),'fatal: loose object') !== false && stripos(implode($push_output),'is corrupt') !== false) {
|
||||
// detect corruption #2
|
||||
$arrState['error'] = 'Error: Backup corrupted';
|
||||
|
||||
@@ -47,6 +47,7 @@ class ServerState
|
||||
private $connectPluginVersion;
|
||||
private $configErrorEnum = [
|
||||
"error" => 'UNKNOWN_ERROR',
|
||||
"ineligible" => 'INELIGIBLE',
|
||||
"invalid" => 'INVALID',
|
||||
"nokeyserver" => 'NO_KEY_SERVER',
|
||||
"withdrawn" => 'WITHDRAWN',
|
||||
@@ -235,13 +236,17 @@ class ServerState
|
||||
public function getServerState()
|
||||
{
|
||||
$serverState = [
|
||||
"array" => [
|
||||
"state" => @$this->getWebguiGlobal('var', 'fsState'),
|
||||
"progress" => @$this->getWebguiGlobal('var', 'fsProgress'),
|
||||
],
|
||||
"apiKey" => $this->apiKey,
|
||||
"apiVersion" => $this->apiVersion,
|
||||
"avatar" => $this->avatar,
|
||||
"caseModel" => $this->caseModel,
|
||||
"config" => [
|
||||
'valid' => ($this->var['configValid'] === 'yes'),
|
||||
'error' => isset($this->configErrorEnum[$this->var['configValid']]) ? $this->configErrorEnum[$this->var['configValid']] : 'UNKNOWN_ERROR',
|
||||
'error' => isset($this->configErrorEnum[$this->var['configValid']]) ? $this->configErrorEnum[$this->var['configValid']] : null,
|
||||
],
|
||||
"connectPluginInstalled" => $this->connectPluginInstalled,
|
||||
"connectPluginVersion" => $this->connectPluginVersion,
|
||||
|
||||
@@ -72,13 +72,13 @@ class WebComponentTranslations
|
||||
'<p>To continue using Unraid OS you may purchase a license key. Alternately, you may request a Trial extension.</p>' => '<p>' . _('To continue using Unraid OS you may purchase a license key.') . ' ' . _('Alternately, you may request a Trial extension.') . '</p>',
|
||||
'<p>To support more storage devices as your server grows, click Upgrade Key.</p>' => '<p>' . _('To support more storage devices as your server grows, click Upgrade Key.') . '</p>',
|
||||
'<p>You have used all your Trial extensions. To continue using Unraid OS you may purchase a license key.</p>' => '<p>' . _('You have used all your Trial extensions.') . ' ' . _('To continue using Unraid OS you may purchase a license key.') . '</p>',
|
||||
'<p>Your <em>Trial</em> key includes all the functionality and device support of a <em>Pro</em> key.</p><p>After your <em>Trial</em> has reached expiration, your server <strong>still functions normally</strong> until the next time you Stop the array or reboot your server.</p><p>At that point you may either purchase a license key or request a <em>Trial</em> extension.</p>' => '<p>' . _('Your **Trial** key includes all the functionality and device support of a **Pro** key') . '</p><p>' . _('After your **Trial** has reached expiration, your server *still functions normally* until the next time you Stop the array or reboot your server') . '</p><p>' . _('At that point you may either purchase a license key or request a *Trial* extension.') . '</p>',
|
||||
'<p>Your <em>Trial</em> key includes all the functionality and device support of an <em>Unleashed</em> key.</p><p>After your <em>Trial</em> has reached expiration, your server <strong>still functions normally</strong> until the next time you Stop the array or reboot your server.</p><p>At that point you may either purchase a license key or request a <em>Trial</em> extension.</p>' => '<p>' . _('Your **Trial** key includes all the functionality and device support of an **Unleashed** key') . '</p><p>' . _('After your **Trial** has reached expiration, your server *still functions normally* until the next time you Stop the array or reboot your server') . '</p><p>' . _('At that point you may either purchase a license key or request a *Trial* extension.') . '</p>',
|
||||
'<p>Your license key file is corrupted or missing. The key file should be located in the /config directory on your USB Flash boot device.</p><p>If you do not have a backup copy of your license key file you may attempt to recover your key.</p><p>If this was an expired Trial installation, you may purchase a license key.</p>' => '<p>' . _('Your license key file is corrupted or missing.') . ' ' . _('The key file should be located in the /config directory on your USB Flash boot device') . '</p><p>' . _('If you do not have a backup copy of your license key file you may attempt to recover your key with your Unraid.net account') . '</p><p>' . _('If this was an expired Trial installation, you may purchase a license key.') . '</p>',
|
||||
'<p>Your license key file is corrupted or missing. The key file should be located in the /config directory on your USB Flash boot device.</p><p>You may attempt to recover your key with your Unraid.net account.</p><p>If this was an expired Trial installation, you may purchase a license key.</p>' => '<p>' . _('Your license key file is corrupted or missing.') . ' ' . _('The key file should be located in the /config directory on your USB Flash boot device') . '</p><p>' . _('If you do not have a backup copy of your license key file you may attempt to recover your key with your Unraid.net account') . '</p><p>' . _('If this was an expired Trial installation, you may purchase a license key.') . '</p>',
|
||||
'<p>Your server will not be usable until you purchase a Registration key or install a free 30 day <em>Trial</em> key. A <em>Trial</em> key provides all the functionality of a Pro Registration key.</p><p>Registration keys are bound to your USB Flash boot device serial number (GUID). Please use a high quality name brand device at least 1GB in size.</p><p>Note: USB memory card readers are generally not supported because most do not present unique serial numbers.</p><p><strong>Important:</strong></p><ul class="list-disc pl-16px"><li>Please make sure your server time is accurate to within 5 minutes</li><li>Please make sure there is a DNS server specified</li></ul>' => '<p>' . _('Your server will not be usable until you purchase a Registration key or install a free 30 day <em>Trial</em> key.') . ' ' . _('A <em>Trial</em> key provides all the functionality of a Pro Registration key.') . '</p><p>' . _('Registration keys are bound to your USB Flash boot device serial number (GUID).') . ' ' . _('Please use a high quality name brand device at least 1GB in size.') . '</p><p>' . _('Note: USB memory card readers are generally not supported because most do not present unique serial numbers.') . '</p><p>' . _('*Important:*') . '</p><ul class="list-disc pl-16px"><li>' . _('Please make sure your server time is accurate to within 5 minutes') . '</li><li>' . _('Please make sure there is a DNS server specified') . '</li>>' . '</ul>',
|
||||
'<p>Your server will not be usable until you purchase a Registration key or install a free 30 day <em>Trial</em> key. A <em>Trial</em> key provides all the functionality of an Unleashed Registration key.</p><p>Registration keys are bound to your USB Flash boot device serial number (GUID). Please use a high quality name brand device at least 1GB in size.</p><p>Note: USB memory card readers are generally not supported because most do not present unique serial numbers.</p><p><strong>Important:</strong></p><ul class="list-disc pl-16px"><li>Please make sure your server time is accurate to within 5 minutes</li><li>Please make sure there is a DNS server specified</li></ul>' => '<p>' . _('Your server will not be usable until you purchase a Registration key or install a free 30 day <em>Trial</em> key.') . ' ' . _('A <em>Trial</em> key provides all the functionality of an Unleashed Registration key.') . '</p><p>' . _('Registration keys are bound to your USB Flash boot device serial number (GUID).') . ' ' . _('Please use a high quality name brand device at least 1GB in size.') . '</p><p>' . _('Note: USB memory card readers are generally not supported because most do not present unique serial numbers.') . '</p><p>' . _('*Important:*') . '</p><ul class="list-disc pl-16px"><li>' . _('Please make sure your server time is accurate to within 5 minutes') . '</li><li>' . _('Please make sure there is a DNS server specified') . '</li>>' . '</ul>',
|
||||
'<p>Your Trial key requires an internet connection.</p><p><a href="/Settings/NetworkSettings" class="underline">Please check Settings > Network</a></p>' => '<p>' . _('Your Trial key requires an internet connection') . '</p><p><a href="/Settings/NetworkSettings" class="underline">' . _('Please check Settings > Network') . '</a></p>',
|
||||
'<p>Your Unraid registration key is ineligible for replacement as it has been replaced within the last 12 months.</p>' => '<p>' . _('Your Unraid registration key is ineligible for replacement as it has been replaced within the last 12 months.') . '</p>',
|
||||
'A Trial key provides all the functionality of a Pro Registration key' => _('A Trial key provides all the functionality of a Pro Registration key'),
|
||||
'A Trial key provides all the functionality of an Unleashed Registration key' => _('A Trial key provides all the functionality of an Unleashed Registration key'),
|
||||
'Acklowledge that you have made a Flash Backup to enable this action' => _('Acklowledge that you have made a Flash Backup to enable this action'),
|
||||
'ago' => _('ago'),
|
||||
'All you need is an active internet connection, an Unraid.net account, and the Connect plugin. Get started by installing the plugin.' => _('All you need is an active internet connection, an Unraid.net account, and the Connect plugin.') . ' ' . _('Get started by installing the plugin.'),
|
||||
@@ -339,7 +339,7 @@ class WebComponentTranslations
|
||||
'You may still update to releases dated prior to your update expiration date.' => _('You may still update to releases dated prior to your update expiration date.'),
|
||||
'You\'re one step closer to enhancing your Unraid experience' => _('You\'re one step closer to enhancing your Unraid experience'),
|
||||
'Your {0} Key has been replaced!' => sprintf(_('Your %s Key has been replaced!'), '{0}'),
|
||||
'Your free Trial key provides all the functionality of a Pro Registration key' => _('Your free Trial key provides all the functionality of a Pro Registration key'),
|
||||
'Your free Trial key provides all the functionality of an Unleashed Registration key' => _('Your free Trial key provides all the functionality of an Unleashed Registration key'),
|
||||
'Your Trial has expired' => _('Your Trial has expired'),
|
||||
'Your Trial key has been extended!' => _('Your Trial key has been extended!'),
|
||||
];
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
$cli = php_sapi_name() == 'cli';
|
||||
|
||||
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
|
||||
require_once "$docroot/webGui/include/Wrappers.php";
|
||||
|
||||
/**
|
||||
* @name response_complete
|
||||
@@ -85,7 +86,7 @@ switch ($command) {
|
||||
response_complete(200, array('result' => $output), $output);
|
||||
break;
|
||||
case 'wanip':
|
||||
$wanip = trim(@file_get_contents("https://wanip4.unraid.net/"));
|
||||
$wanip = trim(http_get_contents("https://wanip4.unraid.net/"));
|
||||
response_complete(200, array('result' => $wanip), $wanip);
|
||||
break;
|
||||
case 'none':
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
/* Copyright 2005-2024, Lime Technology
|
||||
* Copyright 2012-2024, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -108,6 +108,7 @@ class UnraidOsCheck
|
||||
function _($text) {return $text;}
|
||||
}
|
||||
|
||||
// this command will set the $notify array
|
||||
extract(parse_plugin_cfg('dynamix', true));
|
||||
|
||||
$var = (array)@parse_ini_file('/var/local/emhttp/var.ini');
|
||||
@@ -123,21 +124,12 @@ class UnraidOsCheck
|
||||
if ($parsedAltUrl) $params['altUrl'] = $parsedAltUrl;
|
||||
|
||||
$urlbase = $parsedAltUrl ?? $defaultUrl;
|
||||
$url = $urlbase.'?'.http_build_query($params);
|
||||
|
||||
$response = "";
|
||||
// use error handler to convert warnings from file_get_contents to errors so they can be captured
|
||||
function warning_as_error($severity, $message, $filename, $lineno) {
|
||||
throw new ErrorException($message, 0, $severity, $filename, $lineno);
|
||||
$url = $urlbase.'?'.http_build_query($params);
|
||||
$curlinfo = [];
|
||||
$response = http_get_contents($url,[],$curlinfo);
|
||||
if (array_key_exists('error', $curlinfo)) {
|
||||
$response = json_encode(array('error' => $curlinfo['error']), JSON_PRETTY_PRINT);
|
||||
}
|
||||
set_error_handler("warning_as_error");
|
||||
try {
|
||||
$response = file_get_contents($url);
|
||||
} catch (Exception $e) {
|
||||
$response = json_encode(array('error' => $e->getMessage()), JSON_PRETTY_PRINT);
|
||||
}
|
||||
restore_error_handler();
|
||||
|
||||
$responseMutated = json_decode($response, true);
|
||||
if (!$responseMutated) {
|
||||
$response = json_encode(array('error' => 'Invalid response from '.$urlbase), JSON_PRETTY_PRINT);
|
||||
@@ -159,14 +151,17 @@ class UnraidOsCheck
|
||||
|
||||
// send notification if a newer version is available and not ignored
|
||||
$isNewerVersion = array_key_exists('isNewer',$responseMutated) ? $responseMutated['isNewer'] : false;
|
||||
$isReleaseIgnored = in_array($responseMutated['version'], $this->getIgnoredReleases());
|
||||
$isReleaseIgnored = array_key_exists('version',$responseMutated) ? in_array($responseMutated['version'], $this->getIgnoredReleases()) : false;
|
||||
|
||||
if ($responseMutated && $isNewerVersion && !$isReleaseIgnored) {
|
||||
$output = _var($notify,'plugin');
|
||||
$server = strtoupper(_var($var,'NAME','server'));
|
||||
$newver = (array_key_exists('version',$responseMutated) && $responseMutated['version']) ? $responseMutated['version'] : 'unknown';
|
||||
$script = '/usr/local/emhttp/webGui/scripts/notify';
|
||||
exec("$script -e ".escapeshellarg("System - Unraid [$newver]")." -s ".escapeshellarg("Notice [$server] - Version update $newver")." -d ".escapeshellarg("A new version of Unraid is available")." -i ".escapeshellarg("normal $output")." -l '/Tools/Update' -x");
|
||||
$event = "System - Unraid [$newver]";
|
||||
$subject = "Notice [$server] - Version update $newver";
|
||||
$description = "A new version of Unraid is available";
|
||||
exec("$script -e ".escapeshellarg($event)." -s ".escapeshellarg($subject)." -d ".escapeshellarg($description)." -i ".escapeshellarg("normal $output")." -l '/Tools/Update' -x");
|
||||
}
|
||||
|
||||
exit(0);
|
||||
|
||||
@@ -24,8 +24,32 @@ import type {
|
||||
// return result;
|
||||
// }
|
||||
|
||||
// ENOKEYFILE
|
||||
// TRIAL
|
||||
// BASIC
|
||||
// PLUS
|
||||
// PRO
|
||||
// STARTER
|
||||
// UNLEASHED
|
||||
// LIFETIME
|
||||
// EEXPIRED
|
||||
// EGUID
|
||||
// EGUID1
|
||||
// ETRIAL
|
||||
// ENOKEYFILE2
|
||||
// ENOKEYFILE1
|
||||
// ENOFLASH
|
||||
// EBLACKLISTED
|
||||
// EBLACKLISTED1
|
||||
// EBLACKLISTED2
|
||||
// ENOCONN
|
||||
|
||||
// '1111-1111-5GDB-123412341234' Starter.key = TkJCrVyXMLWWGKZF6TCEvf0C86UYI9KfUDSOm7JoFP19tOMTMgLKcJ6QIOt9_9Psg_t0yF-ANmzSgZzCo94ljXoPm4BESFByR0K7nyY9KVvU8szLEUcBUT3xC2adxLrAXFNxiPeK-mZqt34n16uETKYvLKL_Sr5_JziG5L5lJFBqYZCPmfLMiguFo1vp0xL8pnBH7q8bYoBnePrAcAVb9mAGxFVPEInSPkMBfC67JLHz7XY1Y_K5bYIq3go9XPtLltJ53_U4BQiMHooXUBJCKXodpqoGxq0eV0IhNEYdauAhnTsG90qmGZig0hZalQ0soouc4JZEMiYEcZbn9mBxPg
|
||||
const staticGuid = '1111-1111-5GDB-123412341234';
|
||||
|
||||
const state: ServerState = 'TRIAL';
|
||||
const currentFlashGuid = '1111-1111-NUIK-TEST1234ZACK'; // this is the flash drive that's been booted from
|
||||
const regGuid = '1111-1111-NUIK-TEST1234ZACK'; // this guid is registered in key server
|
||||
const keyfileBase64 = ''; // @todo raycast download key to base64
|
||||
|
||||
// const randomGuid = `1111-1111-${makeid(4)}-123412341234`; // this guid is registered in key server
|
||||
// const newGuid = `1234-1234-${makeid(4)}-123412341234`; // this is a new USB, not registered
|
||||
@@ -42,23 +66,6 @@ const oneHourFromNow = Date.now() + 60 * 60 * 1000; // 1 hour from now
|
||||
let expireTime = 0;
|
||||
let regExp: number | undefined;
|
||||
|
||||
// ENOKEYFILE
|
||||
// TRIAL
|
||||
// BASIC
|
||||
// PLUS
|
||||
// PRO
|
||||
// EEXPIRED
|
||||
// EGUID
|
||||
// EGUID1
|
||||
// ETRIAL
|
||||
// ENOKEYFILE2
|
||||
// ENOKEYFILE1
|
||||
// ENOFLASH
|
||||
// EBLACKLISTED
|
||||
// EBLACKLISTED1
|
||||
// EBLACKLISTED2
|
||||
// ENOCONN
|
||||
const state: ServerState = 'TRIAL';
|
||||
let regDevs = 0;
|
||||
let regTy = '';
|
||||
switch (state) {
|
||||
@@ -101,10 +108,10 @@ switch (state) {
|
||||
break;
|
||||
}
|
||||
|
||||
const connectPluginInstalled = 'dynamix.unraid.net.staging.plg';
|
||||
// const connectPluginInstalled = '';
|
||||
// const connectPluginInstalled = 'dynamix.unraid.net.staging.plg';
|
||||
const connectPluginInstalled = '';
|
||||
|
||||
const osVersion = '6.12.5';
|
||||
const osVersion = '6.12.8';
|
||||
const osVersionBranch = 'stable';
|
||||
// const parsedRegExp = regExp ? dayjs(regExp).format('YYYY-MM-DD') : undefined;
|
||||
|
||||
@@ -133,8 +140,8 @@ export const serverState: Server = {
|
||||
apiKey: 'unupc_fab6ff6ffe51040595c6d9ffb63a353ba16cc2ad7d93f813a2e80a5810',
|
||||
avatar: 'https://source.unsplash.com/300x300/?portrait',
|
||||
config: {
|
||||
// error: 'INVALID',
|
||||
valid: true,
|
||||
error: null,
|
||||
valid: false,
|
||||
},
|
||||
connectPluginInstalled,
|
||||
description: 'DevServer9000',
|
||||
@@ -143,11 +150,11 @@ export const serverState: Server = {
|
||||
flashBackupActivated: !!connectPluginInstalled,
|
||||
flashProduct: 'SanDisk_3.2Gen1',
|
||||
flashVendor: 'USB',
|
||||
guid: staticGuid,
|
||||
guid: currentFlashGuid,
|
||||
// "guid": "0781-5583-8355-81071A2B0211",
|
||||
inIframe: false,
|
||||
// keyfile: 'DUMMY_KEYFILE',
|
||||
keyfile: 'TkJCrVyXMLWWGKZF6TCEvf0C86UYI9KfUDSOm7JoFP19tOMTMgLKcJ6QIOt9_9Psg_t0yF-ANmzSgZzCo94ljXoPm4BESFByR0K7nyY9KVvU8szLEUcBUT3xC2adxLrAXFNxiPeK-mZqt34n16uETKYvLKL_Sr5_JziG5L5lJFBqYZCPmfLMiguFo1vp0xL8pnBH7q8bYoBnePrAcAVb9mAGxFVPEInSPkMBfC67JLHz7XY1Y_K5bYIq3go9XPtLltJ53_U4BQiMHooXUBJCKXodpqoGxq0eV0IhNEYdauAhnTsG90qmGZig0hZalQ0soouc4JZEMiYEcZbn9mBxPg',
|
||||
keyfile: keyfileBase64,
|
||||
lanIp: '192.168.254.36',
|
||||
license: '',
|
||||
locale: 'en_US', // en_US, ja
|
||||
@@ -161,7 +168,7 @@ export const serverState: Server = {
|
||||
regTo: 'Zack Spear',
|
||||
regTy,
|
||||
regExp,
|
||||
// "regGuid": "0781-5583-8355-81071A2B0211",
|
||||
regGuid,
|
||||
site: 'http://localhost:4321',
|
||||
state,
|
||||
theme: {
|
||||
@@ -173,15 +180,15 @@ export const serverState: Server = {
|
||||
name: 'white',
|
||||
textColor: ''
|
||||
},
|
||||
updateOsResponse: {
|
||||
version: '6.12.6',
|
||||
name: 'Unraid 6.12.6',
|
||||
date: '2023-12-13',
|
||||
isNewer: true,
|
||||
isEligible: false,
|
||||
changelog: 'https://docs.unraid.net/unraid-os/release-notes/6.12.6/',
|
||||
sha256: '2f5debaf80549029cf6dfab0db59180e7e3391c059e6521aace7971419c9c4bf',
|
||||
},
|
||||
// updateOsResponse: {
|
||||
// version: '6.12.6',
|
||||
// name: 'Unraid 6.12.6',
|
||||
// date: '2023-12-13',
|
||||
// isNewer: true,
|
||||
// isEligible: false,
|
||||
// changelog: 'https://docs.unraid.net/unraid-os/release-notes/6.12.6/',
|
||||
// sha256: '2f5debaf80549029cf6dfab0db59180e7e3391c059e6521aace7971419c9c4bf',
|
||||
// },
|
||||
uptime,
|
||||
username: 'zspearmint',
|
||||
wanFQDN: ''
|
||||
|
||||
@@ -7,6 +7,8 @@ Tag="globe"
|
||||
/**
|
||||
* @todo create web component env switcher liker upcEnv(). If we utilize manifest.json then we'll be switching its path.
|
||||
*/
|
||||
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
|
||||
require_once "$docroot/webGui/include/Wrappers.php";
|
||||
$myservers_flash_cfg_path='/boot/config/plugins/dynamix.my.servers/myservers.cfg';
|
||||
$myservers = file_exists($myservers_flash_cfg_path) ? @parse_ini_file($myservers_flash_cfg_path,true) : [];
|
||||
// print_r($mystatus);
|
||||
@@ -142,7 +144,7 @@ if ($display['theme'] === 'black' || $display['theme'] === 'azure') {
|
||||
<unraid-key-actions></connect-key-actions>
|
||||
</div>
|
||||
<div class="ComponentWrapper">
|
||||
<unraid-wan-ip-check php-wan-ip="<?=@file_get_contents('https://wanip4.unraid.net/')?>"></connect-wan-ip-check>
|
||||
<unraid-wan-ip-check php-wan-ip="<?=http_get_contents('https://wanip4.unraid.net/')?>"></connect-wan-ip-check>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
@@ -25,6 +25,7 @@ import { storeToRefs } from 'pinia';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import useDateTimeHelper from '~/composables/dateTime';
|
||||
|
||||
import { useReplaceRenewStore } from '~/store/replaceRenew';
|
||||
import { useServerStore } from '~/store/server';
|
||||
import type { RegistrationItemProps } from '~/types/registration';
|
||||
@@ -39,6 +40,8 @@ const { t } = useI18n();
|
||||
const replaceRenewCheckStore = useReplaceRenewStore();
|
||||
const serverStore = useServerStore();
|
||||
const {
|
||||
computedArray,
|
||||
arrayWarning,
|
||||
authAction,
|
||||
dateTimeFormat,
|
||||
deviceCount,
|
||||
@@ -54,6 +57,7 @@ const {
|
||||
regTy,
|
||||
regExp,
|
||||
regUpdatesExpired,
|
||||
serverErrors,
|
||||
state,
|
||||
stateData,
|
||||
stateDataError,
|
||||
@@ -76,6 +80,24 @@ watch(regTm, (_newV) => {
|
||||
});
|
||||
onBeforeMount(() => {
|
||||
setFormattedRegTm();
|
||||
/** automatically check for replacement and renewal eligibility…will prompt user if eligible for a renewal / key re-roll for legacy keys */
|
||||
if (guid.value && keyfile.value) {
|
||||
replaceRenewCheckStore.check();
|
||||
}
|
||||
});
|
||||
|
||||
const headingIcon = computed(() => serverErrors.value.length ? ShieldExclamationIcon : ShieldCheckIcon);
|
||||
const heading = computed(() => {
|
||||
if (serverErrors.value.length) { // It's rare to have multiple errors but for the time being only show the first error
|
||||
return serverErrors.value[0]?.heading;
|
||||
}
|
||||
return stateData.value.heading;
|
||||
});
|
||||
const subheading = computed(() => {
|
||||
if (serverErrors.value.length) { // It's rare to have multiple errors but for the time being only show the first error
|
||||
return serverErrors.value[0]?.message;
|
||||
}
|
||||
return stateData.value.message;
|
||||
});
|
||||
|
||||
const showTrialExpiration = computed((): boolean => state.value === 'TRIAL' || state.value === 'EEXPIRED');
|
||||
@@ -87,6 +109,13 @@ const showFilteredKeyActions = computed((): boolean => !!(keyActions.value && ke
|
||||
|
||||
const items = computed((): RegistrationItemProps[] => {
|
||||
return [
|
||||
...(computedArray.value
|
||||
? [{
|
||||
label: t('Array status'),
|
||||
text: computedArray.value,
|
||||
warning: arrayWarning.value,
|
||||
}]
|
||||
: []),
|
||||
...(regTy.value
|
||||
? [{
|
||||
label: t('License key type'),
|
||||
@@ -153,7 +182,7 @@ const items = computed((): RegistrationItemProps[] => {
|
||||
: []),
|
||||
...(keyInstalled.value
|
||||
? [{
|
||||
error: !!tooManyDevices.value,
|
||||
error: tooManyDevices.value,
|
||||
label: t('Attached Storage Devices'),
|
||||
text: tooManyDevices.value
|
||||
? t('{0} out of {1} allowed devices – upgrade your key to support more devices', [deviceCount.value, computedRegDevs.value])
|
||||
@@ -167,6 +196,7 @@ const items = computed((): RegistrationItemProps[] => {
|
||||
componentProps: { t },
|
||||
}]
|
||||
: []),
|
||||
|
||||
...(showFilteredKeyActions.value
|
||||
? [{
|
||||
component: KeyActions,
|
||||
@@ -178,13 +208,6 @@ const items = computed((): RegistrationItemProps[] => {
|
||||
: []),
|
||||
];
|
||||
});
|
||||
|
||||
onBeforeMount(() => {
|
||||
/** automatically check for replacement and renewal eligibility…will prompt user if eligible for a renewal / key re-roll for legacy keys */
|
||||
if (guid.value && keyfile.value) {
|
||||
replaceRenewCheckStore.check();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -194,17 +217,17 @@ onBeforeMount(() => {
|
||||
<header class="flex flex-col gap-y-16px">
|
||||
<h3
|
||||
class="text-20px md:text-24px font-semibold leading-normal flex flex-row items-center gap-8px"
|
||||
:class="stateDataError ? 'text-unraid-red' : 'text-green-500'"
|
||||
:class="serverErrors.length ? 'text-unraid-red' : 'text-green-500'"
|
||||
>
|
||||
<component :is="stateDataError ? ShieldExclamationIcon : ShieldCheckIcon" class="w-24px h-24px" />
|
||||
<component :is="headingIcon" class="w-24px h-24px" />
|
||||
<span>
|
||||
{{ stateData.heading }}
|
||||
{{ heading }}
|
||||
</span>
|
||||
</h3>
|
||||
<div
|
||||
v-if="stateData.message"
|
||||
v-if="subheading"
|
||||
class="prose text-16px leading-relaxed whitespace-normal opacity-75"
|
||||
v-html="stateData.message"
|
||||
v-html="subheading"
|
||||
/>
|
||||
<span v-if="authAction" class="grow-0">
|
||||
<BrandButton
|
||||
|
||||
@@ -25,9 +25,9 @@ const evenBgColor = computed(() => {
|
||||
error && 'text-white bg-unraid-red',
|
||||
warning && 'text-black bg-yellow-100',
|
||||
]"
|
||||
class="text-16px p-12px grid grid-cols-1 gap-4px sm:px-20px sm:grid-cols-5 sm:gap-16px items-start rounded"
|
||||
class="text-16px p-12px grid grid-cols-1 gap-4px sm:px-20px sm:grid-cols-5 sm:gap-16px items-baseline rounded"
|
||||
>
|
||||
<dt v-if="label" class="font-semibold sm:col-span-2 flex flex-row sm:justify-end sm:text-right items-center gap-x-8px">
|
||||
<dt v-if="label" class="font-semibold leading-normal sm:col-span-2 flex flex-row sm:justify-end sm:text-right items-center gap-x-8px">
|
||||
<ShieldExclamationIcon v-if="error" class="w-16px h-16px fill-current" />
|
||||
<span v-html="label" />
|
||||
</dt>
|
||||
|
||||
@@ -102,7 +102,7 @@ const subheading = computed(() => {
|
||||
if (keyActionType.value === 'purchase') { return props.t('Thank you for purchasing an Unraid {0} Key!', [keyType.value]); }
|
||||
if (keyActionType.value === 'replace') { return props.t('Your {0} Key has been replaced!', [keyType.value]); }
|
||||
if (keyActionType.value === 'trialExtend') { return props.t('Your Trial key has been extended!'); }
|
||||
if (keyActionType.value === 'trialStart') { return props.t('Your free Trial key provides all the functionality of a Pro Registration key'); }
|
||||
if (keyActionType.value === 'trialStart') { return props.t('Your free Trial key provides all the functionality of an Unleashed Registration key'); }
|
||||
if (keyActionType.value === 'upgrade') { return props.t('Thank you for upgrading to an Unraid {0} Key!', [keyType.value]); }
|
||||
return '';
|
||||
}
|
||||
|
||||
@@ -242,6 +242,7 @@ export type Config = {
|
||||
};
|
||||
|
||||
export enum ConfigErrorState {
|
||||
Ineligible = 'INELIGIBLE',
|
||||
Invalid = 'INVALID',
|
||||
NoKeyServer = 'NO_KEY_SERVER',
|
||||
UnknownError = 'UNKNOWN_ERROR',
|
||||
|
||||
@@ -9,7 +9,7 @@ const CONNECT_DOCS = new URL('category/unraid-connect', DOCS);
|
||||
const CONNECT_DASHBOARD = new URL(import.meta.env.VITE_CONNECT ?? 'https://connect.myunraid.net');
|
||||
const CONNECT_FORUMS = new URL('/forum/94-connect-plugin-support/', FORUMS);
|
||||
const CONTACT = new URL('/contact', UNRAID_NET);
|
||||
const DISCORD = new URL('https://discord.gg/unraid');
|
||||
const DISCORD = new URL('https://discord.unraid.net');
|
||||
const PURCHASE_CALLBACK = new URL('/c', UNRAID_NET);
|
||||
|
||||
const WEBGUI = new URL(import.meta.env.VITE_WEBGUI ?? window.location.origin);
|
||||
|
||||
@@ -126,10 +126,10 @@
|
||||
"Learn More": "",
|
||||
"No Keyfile": "",
|
||||
"Let's Unleash your Hardware!": "",
|
||||
"<p>Your server will not be usable until you purchase a Registration key or install a free 30 day <em>Trial</em> key. A <em>Trial</em> key provides all the functionality of a Pro Registration key.</p><p>Registration keys are bound to your USB Flash boot device serial number (GUID). Please use a high quality name brand device at least 1GB in size.</p><p>Note: USB memory card readers are generally not supported because most do not present unique serial numbers.</p><p><strong>Important:</strong></p><ul class='list-disc pl-16px'><li>Please make sure your server time is accurate to within 5 minutes</li><li>Please make sure there is a DNS server specified</li></ul>": "",
|
||||
"<p>Your server will not be usable until you purchase a Registration key or install a free 30 day <em>Trial</em> key. A <em>Trial</em> key provides all the functionality of an Unleashed Registration key.</p><p>Registration keys are bound to your USB Flash boot device serial number (GUID). Please use a high quality name brand device at least 1GB in size.</p><p>Note: USB memory card readers are generally not supported because most do not present unique serial numbers.</p><p><strong>Important:</strong></p><ul class='list-disc pl-16px'><li>Please make sure your server time is accurate to within 5 minutes</li><li>Please make sure there is a DNS server specified</li></ul>": "",
|
||||
"Trial": "",
|
||||
"Thank you for choosing Unraid OS!": "",
|
||||
"<p>Your <em>Trial</em> key includes all the functionality and device support of a <em>Pro</em> key.</p><p>After your <em>Trial</em> has reached expiration, your server <strong>still functions normally</strong> until the next time you Stop the array or reboot your server.</p><p>At that point you may either purchase a license key or request a <em>Trial</em> extension.</p>": "",
|
||||
"<p>Your <em>Trial</em> key includes all the functionality and device support of an <em>Unleashed</em> key.</p><p>After your <em>Trial</em> has reached expiration, your server <strong>still functions normally</strong> until the next time you Stop the array or reboot your server.</p><p>At that point you may either purchase a license key or request a <em>Trial</em> extension.</p>": "",
|
||||
"Trial Expired": "",
|
||||
"Your Trial has expired": "",
|
||||
"<p>To continue using Unraid OS you may purchase a license key. Alternately, you may request a Trial extension.</p>": "",
|
||||
@@ -186,7 +186,7 @@
|
||||
"Starting your free 30 day trial": "",
|
||||
"Trial Key Created": "",
|
||||
"Please wait while the page reloads to install your trial key": "",
|
||||
"A Trial key provides all the functionality of a Pro Registration key": "",
|
||||
"A Trial key provides all the functionality of an Unleashed Registration key": "",
|
||||
"Extension Installed": "",
|
||||
"Recovered": "",
|
||||
"Replaced": "",
|
||||
@@ -196,5 +196,5 @@
|
||||
"Install Extended": "",
|
||||
"Install Recovered": "",
|
||||
"Install Replaced": "",
|
||||
"Your free Trial key provides all the functionality of a Pro Registration key": ""
|
||||
"Your free Trial key provides all the functionality of an Unleashed Registration key": ""
|
||||
}
|
||||
|
||||
@@ -129,10 +129,10 @@
|
||||
"Learn More": "Learn More",
|
||||
"No Keyfile": "No Keyfile",
|
||||
"Let's Unleash your Hardware!": "Let's Unleash your Hardware!",
|
||||
"<p>Your server will not be usable until you purchase a Registration key or install a free 30 day <em>Trial</em> key. A <em>Trial</em> key provides all the functionality of a Pro Registration key.</p><p>Registration keys are bound to your USB Flash boot device serial number (GUID). Please use a high quality name brand device at least 1GB in size.</p><p>Note: USB memory card readers are generally not supported because most do not present unique serial numbers.</p><p><strong>Important:</strong></p><ul class='list-disc pl-16px'><li>Please make sure your server time is accurate to within 5 minutes</li><li>Please make sure there is a DNS server specified</li></ul>": "<p>Your server will not be usable until you purchase a Registration key or install a free 30 day <em>Trial</em> key. A <em>Trial</em> key provides all the functionality of a Pro Registration key.</p><p>Registration keys are bound to your USB Flash boot device serial number (GUID). Please use a high quality name brand device at least 1GB in size.</p><p>Note: USB memory card readers are generally not supported because most do not present unique serial numbers.</p><p><strong>Important:</strong></p><ul class='list-disc pl-16px'><li>Please make sure your server time is accurate to within 5 minutes</li><li>Please make sure there is a DNS server specified</li></ul>",
|
||||
"<p>Your server will not be usable until you purchase a Registration key or install a free 30 day <em>Trial</em> key. A <em>Trial</em> key provides all the functionality of an Unleashed Registration key.</p><p>Registration keys are bound to your USB Flash boot device serial number (GUID). Please use a high quality name brand device at least 1GB in size.</p><p>Note: USB memory card readers are generally not supported because most do not present unique serial numbers.</p><p><strong>Important:</strong></p><ul class='list-disc pl-16px'><li>Please make sure your server time is accurate to within 5 minutes</li><li>Please make sure there is a DNS server specified</li></ul>": "<p>Your server will not be usable until you purchase a Registration key or install a free 30 day <em>Trial</em> key. A <em>Trial</em> key provides all the functionality of an Unleashed Registration key.</p><p>Registration keys are bound to your USB Flash boot device serial number (GUID). Please use a high quality name brand device at least 1GB in size.</p><p>Note: USB memory card readers are generally not supported because most do not present unique serial numbers.</p><p><strong>Important:</strong></p><ul class='list-disc pl-16px'><li>Please make sure your server time is accurate to within 5 minutes</li><li>Please make sure there is a DNS server specified</li></ul>",
|
||||
"Trial": "Trial",
|
||||
"Thank you for choosing Unraid OS!": "Thank you for choosing Unraid OS!",
|
||||
"<p>Your <em>Trial</em> key includes all the functionality and device support of a <em>Pro</em> key.</p><p>After your <em>Trial</em> has reached expiration, your server <strong>still functions normally</strong> until the next time you Stop the array or reboot your server.</p><p>At that point you may either purchase a license key or request a <em>Trial</em> extension.</p>": "<p>Your <em>Trial</em> key includes all the functionality and device support of a <em>Pro</em> key.</p><p>After your <em>Trial</em> has reached expiration, your server <strong>still functions normally</strong> until the next time you Stop the array or reboot your server.</p><p>At that point you may either purchase a license key or request a <em>Trial</em> extension.</p>",
|
||||
"<p>Your <em>Trial</em> key includes all the functionality and device support of an <em>Unleashed</em> key.</p><p>After your <em>Trial</em> has reached expiration, your server <strong>still functions normally</strong> until the next time you Stop the array or reboot your server.</p><p>At that point you may either purchase a license key or request a <em>Trial</em> extension.</p>": "<p>Your <em>Trial</em> key includes all the functionality and device support of an <em>Unleashed</em> key.</p><p>After your <em>Trial</em> has reached expiration, your server <strong>still functions normally</strong> until the next time you Stop the array or reboot your server.</p><p>At that point you may either purchase a license key or request a <em>Trial</em> extension.</p>",
|
||||
"Trial Expired": "Trial Expired",
|
||||
"Your Trial has expired": "Your Trial has expired",
|
||||
"<p>To continue using Unraid OS you may purchase a license key. Alternately, you may request a Trial extension.</p>": "<p>To continue using Unraid OS you may purchase a license key. Alternately, you may request a Trial extension.</p>",
|
||||
@@ -189,7 +189,7 @@
|
||||
"Starting your free 30 day trial": "Starting your free 30 day trial",
|
||||
"Trial Key Created": "Trial Key Created",
|
||||
"Please wait while the page reloads to install your trial key": "Please wait while the page reloads to install your trial key",
|
||||
"A Trial key provides all the functionality of a Pro Registration key": "A Trial key provides all the functionality of a Pro Registration key.",
|
||||
"A Trial key provides all the functionality of an Unleashed Registration key": "A Trial key provides all the functionality of an Unleashed Registration key.",
|
||||
"Extension Installed": "Extension Installed",
|
||||
"Recovered": "Recovered",
|
||||
"Replaced": "Replaced",
|
||||
@@ -199,7 +199,7 @@
|
||||
"Install Extended": "Install Extended",
|
||||
"Install Recovered": "Install Recovered",
|
||||
"Install Replaced": "Install Replaced",
|
||||
"Your free Trial key provides all the functionality of a Pro Registration key": "Your free Trial key provides all the functionality of a Pro Registration key",
|
||||
"Your free Trial key provides all the functionality of an Unleashed Registration key": "Your free Trial key provides all the functionality of an Unleashed Registration key",
|
||||
"Calculating trial expiration…": "Calculating trial expiration…",
|
||||
"Signing In": "Signing In",
|
||||
"Signing Out": "Signing Out",
|
||||
|
||||
@@ -126,10 +126,10 @@
|
||||
"Learn More": "もっと詳しく知る",
|
||||
"No Keyfile": "キーファイルがありません",
|
||||
"Let's Unleash your Hardware!": "ハードウェアを解き放ちましょう!",
|
||||
"<p>Your server will not be usable until you purchase a Registration key or install a free 30 day <em>Trial</em> key. A <em>Trial</em> key provides all the functionality of a Pro Registration key.</p><p>Registration keys are bound to your USB Flash boot device serial number (GUID). Please use a high quality name brand device at least 1GB in size.</p><p>Note: USB memory card readers are generally not supported because most do not present unique serial numbers.</p><p><strong>Important:</strong></p><ul class='list-disc pl-16px'><li>Please make sure your server time is accurate to within 5 minutes</li><li>Please make sure there is a DNS server specified</li></ul>": "<p>登録キーを購入するか、30 日間の無料の<em>トライアル</em>キーをインストールするまで、サーバーは使用できません。 \n<em>トライアル</em> キーは、Pro 登録キーのすべての機能を提供します。</p><p>登録キーは、USB フラッシュ ブート デバイスのシリアル番号 (GUID) にバインドされています。\nサイズが少なくとも 1 GB の高品質の有名ブランドのデバイスを使用してください。</p><p>注: USB メモリ カード リーダーのほとんどは固有のシリアル番号を提示していないため、通常はサポートされていません。</p><p><strong>\n重要:</strong></p><ul class='list-disc pl-16px'><li>サーバー時間が 5 分以内であることを確認してください。</li><li>\n指定された DNS サーバー</li></ul>",
|
||||
"<p>Your server will not be usable until you purchase a Registration key or install a free 30 day <em>Trial</em> key. A <em>Trial</em> key provides all the functionality of an Unleashed Registration key.</p><p>Registration keys are bound to your USB Flash boot device serial number (GUID). Please use a high quality name brand device at least 1GB in size.</p><p>Note: USB memory card readers are generally not supported because most do not present unique serial numbers.</p><p><strong>Important:</strong></p><ul class='list-disc pl-16px'><li>Please make sure your server time is accurate to within 5 minutes</li><li>Please make sure there is a DNS server specified</li></ul>": "<p>登録キーを購入するか、30 日間の無料の<em>トライアル</em>キーをインストールするまで、サーバーは使用できません。 \n<em>トライアル</em> キーは、Pro 登録キーのすべての機能を提供します。</p><p>登録キーは、USB フラッシュ ブート デバイスのシリアル番号 (GUID) にバインドされています。\nサイズが少なくとも 1 GB の高品質の有名ブランドのデバイスを使用してください。</p><p>注: USB メモリ カード リーダーのほとんどは固有のシリアル番号を提示していないため、通常はサポートされていません。</p><p><strong>\n重要:</strong></p><ul class='list-disc pl-16px'><li>サーバー時間が 5 分以内であることを確認してください。</li><li>\n指定された DNS サーバー</li></ul>",
|
||||
"Trial": "トライアル",
|
||||
"Thank you for choosing Unraid OS!": "Unraid OS をお選びいただきありがとうございます。",
|
||||
"<p>Your <em>Trial</em> key includes all the functionality and device support of a <em>Pro</em> key.</p><p>After your <em>Trial</em> has reached expiration, your server <strong>still functions normally</strong> until the next time you Stop the array or reboot your server.</p><p>At that point you may either purchase a license key or request a <em>Trial</em> extension.</p>": "<p><em>トライアル</em> キーには、<em>プロ</em> キーのすべての機能とデバイス サポートが含まれています。</p><p><em>トライアル</em> の終了後\n有効期限に達しても、次回アレイを停止するかサーバーを再起動するまで、 サーバーは<strong>通常どおり機能</strong>します。</p><p>その時点で、ライセンス キーを購入するか、<em>ライセンス キーをリクエストすることができます。 \n> トライアル</em>拡張機能。</p>",
|
||||
"<p>Your <em>Trial</em> key includes all the functionality and device support of an <em>Unleashed</em> key.</p><p>After your <em>Trial</em> has reached expiration, your server <strong>still functions normally</strong> until the next time you Stop the array or reboot your server.</p><p>At that point you may either purchase a license key or request a <em>Trial</em> extension.</p>": "<p><em>トライアル</em> キーには、<em>プロ</em> キーのすべての機能とデバイス サポートが含まれています。</p><p><em>トライアル</em> の終了後\n有効期限に達しても、次回アレイを停止するかサーバーを再起動するまで、 サーバーは<strong>通常どおり機能</strong>します。</p><p>その時点で、ライセンス キーを購入するか、<em>ライセンス キーをリクエストすることができます。 \n> トライアル</em>拡張機能。</p>",
|
||||
"Trial Expired": "トライアル期間が終了しました",
|
||||
"Your Trial has expired": "トライアル版の有効期限が切れました",
|
||||
"<p>To continue using Unraid OS you may purchase a license key. Alternately, you may request a Trial extension.</p>": "<p>Unraid OS を引き続き使用するには、ライセンス キーを購入することができます。\nあるいは、トライアルの延長をリクエストすることもできます。</p>",
|
||||
@@ -186,7 +186,7 @@
|
||||
"Starting your free 30 day trial": "30 日間の無料トライアルを開始する",
|
||||
"Trial Key Created": "トライアルキーが作成されました",
|
||||
"Please wait while the page reloads to install your trial key": "試用版キーをインストールするには、ページがリロードされるまでお待ちください。",
|
||||
"A Trial key provides all the functionality of a Pro Registration key": "トライアル キーは、Pro 登録キーのすべての機能を提供します。",
|
||||
"A Trial key provides all the functionality of an Unleashed Registration key": "トライアル キーは、Pro 登録キーのすべての機能を提供します。",
|
||||
"Extension Installed": "拡張機能がインストールされました",
|
||||
"Recovered": "回復しました",
|
||||
"Replaced": "交換されました",
|
||||
@@ -196,5 +196,5 @@
|
||||
"Install Extended": "拡張インストール",
|
||||
"Install Recovered": "インストールが回復しました",
|
||||
"Install Replaced": "インストールと置き換え",
|
||||
"Your free Trial key provides all the functionality of a Pro Registration key": "無料のトライアル キーは、プロ登録キーのすべての機能を提供します"
|
||||
"Your free Trial key provides all the functionality of an Unleashed Registration key": "無料のトライアル キーは、プロ登録キーのすべての機能を提供します"
|
||||
}
|
||||
|
||||
@@ -5,11 +5,12 @@
|
||||
"dev": "nuxt dev",
|
||||
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix",
|
||||
"type-check": "nuxi typecheck",
|
||||
"build:dev": "npm run lint && npm run type-check && nuxt build && npm run deploy-wc:dev",
|
||||
"build:webgui": "npm run lint && npm run type-check && nuxt build && npm run copy-to-webgui-repo",
|
||||
"build": "npm run type-check && nuxt build",
|
||||
"build:dev": "npm run lint && npm run type-check && nuxt build && npm run manifest-ts && npm run deploy-wc:dev",
|
||||
"build:webgui": "npm run lint && npm run type-check && nuxt build && npm run manifest-ts && npm run copy-to-webgui-repo",
|
||||
"build": "npm run type-check && nuxt build && npm run manifest-ts",
|
||||
"deploy-wc:dev": "./scripts/deploy-dev.sh",
|
||||
"copy-to-webgui-repo": "./scripts/copy-to-webgui-repo.sh",
|
||||
"manifest-ts": "node ./scripts/add-timestamp-webcomponent-manifest.js",
|
||||
"generate": "nuxt generate",
|
||||
"preview": "nuxt preview",
|
||||
"postinstall": "nuxt prepare",
|
||||
|
||||
15
web/scripts/add-timestamp-webcomponent-manifest.js
Normal file
15
web/scripts/add-timestamp-webcomponent-manifest.js
Normal file
@@ -0,0 +1,15 @@
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const fs = require('fs');
|
||||
|
||||
// Read the JSON file
|
||||
const filePath = '../web/.nuxt/nuxt-custom-elements/dist/unraid-components/manifest.json';
|
||||
const jsonData = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
|
||||
|
||||
// Add timestamp (ts) to the JSON data
|
||||
const timestamp = Math.floor(new Date().getTime() / 1000); // Current timestamp epoch
|
||||
jsonData.ts = timestamp;
|
||||
|
||||
// Write the updated JSON back to the file
|
||||
fs.writeFileSync(filePath, JSON.stringify(jsonData, null, 2));
|
||||
|
||||
console.log(`Timestamp: ${timestamp} added to the web component manifest.`);
|
||||
@@ -5,6 +5,7 @@ import dayjs from 'dayjs';
|
||||
import { defineStore, createPinia, setActivePinia } from 'pinia';
|
||||
import prerelease from 'semver/functions/prerelease';
|
||||
import {
|
||||
ArrowPathIcon,
|
||||
ArrowRightOnRectangleIcon,
|
||||
CogIcon,
|
||||
GlobeAltIcon,
|
||||
@@ -17,7 +18,11 @@ import { useQuery } from '@vue/apollo-composable';
|
||||
import { SERVER_CLOUD_FRAGMENT, SERVER_STATE_QUERY } from './server.fragment';
|
||||
import { useFragment } from '~/composables/gql/fragment-masking';
|
||||
import { WebguiState, WebguiUpdateIgnore } from '~/composables/services/webgui';
|
||||
import { WEBGUI_SETTINGS_MANAGMENT_ACCESS } from '~/helpers/urls';
|
||||
import {
|
||||
WEBGUI_SETTINGS_MANAGMENT_ACCESS,
|
||||
WEBGUI_TOOLS_REGISTRATION,
|
||||
WEBGUI_TOOLS_UPDATE,
|
||||
} from '~/helpers/urls';
|
||||
import { useAccountStore } from '~/store/account';
|
||||
import { useErrorsStore, type Error } from '~/store/errors';
|
||||
import { usePurchaseStore } from '~/store/purchase';
|
||||
@@ -36,6 +41,7 @@ import type {
|
||||
ServerconnectPluginInstalled,
|
||||
ServerDateTimeFormat,
|
||||
ServerStateDataKeyActions,
|
||||
ServerStateArray,
|
||||
ServerOsVersionBranch,
|
||||
ServerUpdateOsResponse,
|
||||
} from '~/types/server';
|
||||
@@ -65,6 +71,18 @@ export const useServerStore = defineStore('server', () => {
|
||||
}
|
||||
});
|
||||
const apiVersion = ref<string>('');
|
||||
const array = ref<ServerStateArray | undefined>();
|
||||
// helps to display warning next to array status
|
||||
const arrayWarning = computed(() => !!(stateDataError.value || serverConfigError.value));
|
||||
const computedArray = computed(() => {
|
||||
if (arrayWarning.value) {
|
||||
if (array.value?.state === 'Stopped') {
|
||||
return 'Stopped. The Array will not start until the above issue is resolved.';
|
||||
}
|
||||
return 'Started. If stopped, the Array will not restart until the above issue is resolved.';
|
||||
}
|
||||
return array.value?.state;
|
||||
});
|
||||
const avatar = ref<string>(''); // @todo potentially move to a user store
|
||||
const caseModel = ref<string>('');
|
||||
const cloud = ref<PartialCloudFragment | undefined>();
|
||||
@@ -165,6 +183,7 @@ export const useServerStore = defineStore('server', () => {
|
||||
return {
|
||||
apiKey: apiKey.value,
|
||||
apiVersion: apiVersion.value,
|
||||
array: array.value,
|
||||
avatar: avatar.value,
|
||||
connectPluginVersion: connectPluginVersion.value,
|
||||
connectPluginInstalled: connectPluginInstalled.value,
|
||||
@@ -451,7 +470,7 @@ export const useServerStore = defineStore('server', () => {
|
||||
],
|
||||
humanReadable: 'Trial',
|
||||
heading: 'Thank you for choosing Unraid OS!',
|
||||
message: '<p>Your <em>Trial</em> key includes all the functionality and device support of a <em>Pro</em> key.</p><p>After your <em>Trial</em> has reached expiration, your server <strong>still functions normally</strong> until the next time you Stop the array or reboot your server.</p><p>At that point you may either purchase a license key or request a <em>Trial</em> extension.</p>',
|
||||
message: '<p>Your <em>Trial</em> key includes all the functionality and device support of an <em>Unleashed</em> key.</p><p>After your <em>Trial</em> has reached expiration, your server <strong>still functions normally</strong> until the next time you Stop the array or reboot your server.</p><p>At that point you may either purchase a license key or request a <em>Trial</em> extension.</p>',
|
||||
};
|
||||
case 'EEXPIRED':
|
||||
return {
|
||||
@@ -683,24 +702,73 @@ export const useServerStore = defineStore('server', () => {
|
||||
});
|
||||
const trialExtensionEligible = computed(() => !regGen.value || regGen.value < 2);
|
||||
|
||||
const tooManyDevices = computed((): Error | undefined => {
|
||||
if ((deviceCount.value !== 0 && computedRegDevs.value > 0 && deviceCount.value > computedRegDevs.value) ||
|
||||
(!config.value?.valid && config.value?.error === 'INVALID')) {
|
||||
return {
|
||||
heading: 'Too Many Devices',
|
||||
level: 'error',
|
||||
message: 'You have exceeded the number of devices allowed for your license. Please remove a device before adding another.',
|
||||
ref: 'tooManyDevices',
|
||||
type: 'server',
|
||||
};
|
||||
const serverConfigError = computed((): Error | undefined => {
|
||||
if (!config.value?.valid && config.value?.error) {
|
||||
switch (config.value?.error) {
|
||||
// case 'UNKNOWN_ERROR':
|
||||
// return {
|
||||
// heading: 'Unknown Error',
|
||||
// level: 'error',
|
||||
// message: 'An unknown internal error occurred.',
|
||||
// ref: 'configError',
|
||||
// type: 'server',
|
||||
// };
|
||||
case 'INELIGIBLE':
|
||||
return {
|
||||
heading: 'Ineligible for OS Version',
|
||||
level: 'error',
|
||||
message: 'Your License Key does not support this OS Version. OS build date greater than key expiration. Please consider extending your registration key.',
|
||||
actions: [{
|
||||
href: WEBGUI_TOOLS_REGISTRATION.toString(),
|
||||
icon: CogIcon,
|
||||
text: 'Learn More at Tools > Registration',
|
||||
}],
|
||||
ref: 'configError',
|
||||
type: 'server',
|
||||
};
|
||||
case 'INVALID':
|
||||
return {
|
||||
heading: 'Too Many Devices',
|
||||
level: 'error',
|
||||
message: 'You have exceeded the number of devices allowed for your license. Please remove a device to start the array, or upgrade your key to support more devices.',
|
||||
ref: 'configError',
|
||||
type: 'server',
|
||||
};
|
||||
case 'NO_KEY_SERVER':
|
||||
return {
|
||||
heading: 'Check Network Connection',
|
||||
level: 'error',
|
||||
message: 'Unable to validate your trial key. Please check your network connection.',
|
||||
ref: 'configError',
|
||||
type: 'server',
|
||||
};
|
||||
case 'WITHDRAWN':
|
||||
return {
|
||||
heading: 'OS Version Withdrawn',
|
||||
level: 'error',
|
||||
message: 'This OS release should not be run. OS Update Required.',
|
||||
actions: [{
|
||||
href: WEBGUI_TOOLS_UPDATE.toString(),
|
||||
icon: ArrowPathIcon,
|
||||
text: 'Check for Update',
|
||||
}],
|
||||
ref: 'configError',
|
||||
type: 'server',
|
||||
};
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
watch(tooManyDevices, (newVal, oldVal) => {
|
||||
watch(serverConfigError, (newVal, oldVal) => {
|
||||
if (oldVal && oldVal.ref) { errorsStore.removeErrorByRef(oldVal.ref); }
|
||||
if (newVal) { errorsStore.setError(newVal); }
|
||||
});
|
||||
|
||||
const tooManyDevices = computed((): boolean => {
|
||||
return ((deviceCount.value !== 0 && computedRegDevs.value > 0 && deviceCount.value > computedRegDevs.value) ||
|
||||
(!config.value?.valid && config.value?.error === 'INVALID'));
|
||||
});
|
||||
|
||||
const pluginInstallFailed = computed((): Error | undefined => {
|
||||
if (connectPluginInstalled.value && connectPluginInstalled.value.includes('_installFailed')) {
|
||||
return {
|
||||
@@ -730,7 +798,7 @@ export const useServerStore = defineStore('server', () => {
|
||||
* Deprecation warning for [hash].unraid.net SSL certs. Deprecation started 2023-01-01
|
||||
*/
|
||||
const deprecatedUnraidSSL = ref<Error | undefined>(
|
||||
(window.location.hostname.includes('localhost')
|
||||
(window.location.hostname.includes('localhost') && window.location.port !== '4321'
|
||||
? {
|
||||
actions: [
|
||||
{
|
||||
@@ -797,18 +865,20 @@ export const useServerStore = defineStore('server', () => {
|
||||
const serverErrors = computed(() => {
|
||||
return [
|
||||
stateDataError.value,
|
||||
tooManyDevices.value,
|
||||
serverConfigError.value,
|
||||
pluginInstallFailed.value,
|
||||
deprecatedUnraidSSL.value,
|
||||
cloudError.value,
|
||||
].filter(Boolean);
|
||||
});
|
||||
|
||||
/**
|
||||
* Actions
|
||||
*/
|
||||
const setServer = (data: Server) => {
|
||||
console.debug('[setServer]', data);
|
||||
if (typeof data?.apiKey !== 'undefined') { apiKey.value = data.apiKey; }
|
||||
if (typeof data?.array !== 'undefined') { array.value = data.array; }
|
||||
if (typeof data?.apiVersion !== 'undefined') { apiVersion.value = data.apiVersion; }
|
||||
if (typeof data?.avatar !== 'undefined') { avatar.value = data.avatar; }
|
||||
if (typeof data?.caseModel !== 'undefined') { caseModel.value = data.caseModel; }
|
||||
@@ -1020,6 +1090,7 @@ export const useServerStore = defineStore('server', () => {
|
||||
return {
|
||||
// state
|
||||
apiKey,
|
||||
array,
|
||||
avatar,
|
||||
cloud,
|
||||
config,
|
||||
@@ -1077,6 +1148,9 @@ export const useServerStore = defineStore('server', () => {
|
||||
stateDataError,
|
||||
serverErrors,
|
||||
tooManyDevices,
|
||||
serverConfigError,
|
||||
arrayWarning,
|
||||
computedArray,
|
||||
// actions
|
||||
setServer,
|
||||
setUpdateOsResponse,
|
||||
|
||||
@@ -60,9 +60,15 @@ export interface ServerUpdateOsResponse {
|
||||
sha256: string | null;
|
||||
}
|
||||
|
||||
export interface ServerStateArray {
|
||||
state: 'Stopped' | 'Started' | 'Starting' | 'Stopping';
|
||||
progress: string;
|
||||
}
|
||||
|
||||
export interface Server {
|
||||
apiKey?: string;
|
||||
apiVersion?: string;
|
||||
array?: ServerStateArray;
|
||||
avatar?: string;
|
||||
caseModel?: string;
|
||||
cloud?: PartialCloudFragment | undefined;
|
||||
|
||||
Reference in New Issue
Block a user