mirror of
https://github.com/community-scripts/ProxmoxVE.git
synced 2026-03-02 17:05:55 +01:00
Compare commits
23 Commits
feat_bump_
...
exit_code_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ee74c8f158 | ||
|
|
7dbb0a75ef | ||
|
|
ab1e1cc66e | ||
|
|
256143af42 | ||
|
|
5dc244a8c1 | ||
|
|
9f15ca6242 | ||
|
|
750b904abc | ||
|
|
96b5411d1d | ||
|
|
a3404102ce | ||
|
|
374c4492d9 | ||
|
|
3cfe86512d | ||
|
|
47e3e415b9 | ||
|
|
3373533725 | ||
|
|
62c7c329d7 | ||
|
|
da04899558 | ||
|
|
e49f09b5ec | ||
|
|
53efcdc9df | ||
|
|
d9e53d5a16 | ||
|
|
8699013eef | ||
|
|
e3af8ad287 | ||
|
|
f2970522a9 | ||
|
|
e1a45c4831 | ||
|
|
d258ff476f |
12
CHANGELOG.md
12
CHANGELOG.md
@@ -412,6 +412,10 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
||||
|
||||
## 2026-03-02
|
||||
|
||||
### 🆕 New Scripts
|
||||
|
||||
- Profilarr ([#12441](https://github.com/community-scripts/ProxmoxVE/pull/12441))
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 💥 Breaking Changes
|
||||
@@ -424,6 +428,14 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
||||
|
||||
- tools.func: Improve stability with retry logic, caching, and debug mode [@MickLesk](https://github.com/MickLesk) ([#10351](https://github.com/community-scripts/ProxmoxVE/pull/10351))
|
||||
|
||||
- #### 🔧 Refactor
|
||||
|
||||
- core: standardize exit codes and add mappings [@MickLesk](https://github.com/MickLesk) ([#12467](https://github.com/community-scripts/ProxmoxVE/pull/12467))
|
||||
|
||||
### 🌐 Website
|
||||
|
||||
- frontend: improve detail view badges, addon texts, and HTML title [@MickLesk](https://github.com/MickLesk) ([#12461](https://github.com/community-scripts/ProxmoxVE/pull/12461))
|
||||
|
||||
## 2026-03-01
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
@@ -39,7 +39,7 @@ function update_script() {
|
||||
COMPOSE_FILE=$(find /opt/komodo -maxdepth 1 -type f -name '*.compose.yaml' ! -name 'compose.env' | head -n1)
|
||||
if [[ -z "$COMPOSE_FILE" ]]; then
|
||||
msg_error "No valid compose file found in /opt/komodo!"
|
||||
exit 1
|
||||
exit 252
|
||||
fi
|
||||
$STD docker compose -p komodo -f "$COMPOSE_FILE" --env-file /opt/komodo/compose.env pull
|
||||
$STD docker compose -p komodo -f "$COMPOSE_FILE" --env-file /opt/komodo/compose.env up -d
|
||||
|
||||
@@ -26,7 +26,7 @@ function update_script() {
|
||||
|
||||
if [[ ! -d /opt/endurain ]]; then
|
||||
msg_error "No ${APP} installation found!"
|
||||
exit 1
|
||||
exit 233
|
||||
fi
|
||||
if check_for_gh_release "endurain" "endurain-project/endurain"; then
|
||||
msg_info "Stopping Service"
|
||||
|
||||
@@ -25,7 +25,7 @@ function update_script() {
|
||||
check_container_resources
|
||||
if ! command -v evcc >/dev/null 2>&1; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit 1
|
||||
exit 233
|
||||
fi
|
||||
|
||||
if [[ -f /etc/apt/sources.list.d/evcc-stable.list ]]; then
|
||||
|
||||
@@ -26,7 +26,7 @@ function update_script() {
|
||||
|
||||
if ! dpkg -s grafana >/dev/null 2>&1; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit 1
|
||||
exit 233
|
||||
fi
|
||||
|
||||
if [[ -f /etc/apt/sources.list.d/grafana.list ]] || [[ ! -f /etc/apt/sources.list.d/grafana.sources ]]; then
|
||||
|
||||
6
ct/headers/profilarr
Normal file
6
ct/headers/profilarr
Normal file
@@ -0,0 +1,6 @@
|
||||
____ _____ __
|
||||
/ __ \_________ / __(_) /___ ___________
|
||||
/ /_/ / ___/ __ \/ /_/ / / __ `/ ___/ ___/
|
||||
/ ____/ / / /_/ / __/ / / /_/ / / / /
|
||||
/_/ /_/ \____/_/ /_/_/\__,_/_/ /_/
|
||||
|
||||
@@ -26,7 +26,7 @@ function update_script() {
|
||||
|
||||
if [[ ! -f /etc/itsm-ng/config_db.php ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit 1
|
||||
exit 233
|
||||
fi
|
||||
setup_mariadb
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ function update_script() {
|
||||
|
||||
if [[ -z "$KASM_URL" ]] || [[ -z "$KASM_VERSION" ]]; then
|
||||
msg_error "Unable to detect latest Kasm release URL."
|
||||
exit 1
|
||||
exit 250
|
||||
fi
|
||||
msg_info "Checked for new version"
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ function update_script() {
|
||||
COMPOSE_FILE=$(find /opt/komodo -maxdepth 1 -type f -name '*.compose.yaml' ! -name 'compose.env' | head -n1)
|
||||
if [[ -z "$COMPOSE_FILE" ]]; then
|
||||
msg_error "No valid compose file found in /opt/komodo!"
|
||||
exit 1
|
||||
exit 252
|
||||
fi
|
||||
$STD docker compose -p komodo -f "$COMPOSE_FILE" --env-file /opt/komodo/compose.env pull
|
||||
$STD docker compose -p komodo -f "$COMPOSE_FILE" --env-file /opt/komodo/compose.env up -d
|
||||
|
||||
@@ -26,7 +26,7 @@ function update_script() {
|
||||
|
||||
if ! dpkg -s loki >/dev/null 2>&1; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit 1
|
||||
exit 233
|
||||
fi
|
||||
|
||||
CHOICE=$(msg_menu "Loki Update Options" \
|
||||
|
||||
@@ -44,7 +44,7 @@ function update_script() {
|
||||
echo -e "${TAB}${GATEWAY}${BGN}https://github.com/community-scripts/ProxmoxVE/discussions/9223${CL}"
|
||||
echo -e ""
|
||||
msg_custom "⚠️" "Update aborted. Please migrate your data first."
|
||||
exit 1
|
||||
exit 253
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
85
ct/profilarr.sh
Normal file
85
ct/profilarr.sh
Normal file
@@ -0,0 +1,85 @@
|
||||
#!/usr/bin/env bash
|
||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: michelroegl-brunner
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://github.com/Dictionarry-Hub/profilarr
|
||||
|
||||
APP="Profilarr"
|
||||
var_tags="${var_tags:-arr;radarr;sonarr;config}"
|
||||
var_cpu="${var_cpu:-2}"
|
||||
var_ram="${var_ram:-2048}"
|
||||
var_disk="${var_disk:-8}"
|
||||
var_os="${var_os:-debian}"
|
||||
var_version="${var_version:-13}"
|
||||
var_unprivileged="${var_unprivileged:-1}"
|
||||
|
||||
header_info "$APP"
|
||||
variables
|
||||
color
|
||||
catch_errors
|
||||
|
||||
function update_script() {
|
||||
header_info
|
||||
check_container_storage
|
||||
check_container_resources
|
||||
|
||||
if [[ ! -d /opt/profilarr ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
|
||||
if check_for_gh_release "profilarr" "Dictionarry-Hub/profilarr"; then
|
||||
msg_info "Stopping Service"
|
||||
systemctl stop profilarr
|
||||
msg_ok "Stopped Service"
|
||||
|
||||
msg_info "Backing up Data"
|
||||
if [[ -d /config ]]; then
|
||||
cp -r /config /opt/profilarr_config_backup
|
||||
fi
|
||||
msg_ok "Backed up Data"
|
||||
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "profilarr" "Dictionarry-Hub/profilarr" "tarball"
|
||||
|
||||
msg_info "Installing Python Dependencies"
|
||||
cd /opt/profilarr/backend
|
||||
$STD uv venv /opt/profilarr/backend/.venv
|
||||
sed 's/==/>=/g' requirements.txt >requirements-relaxed.txt
|
||||
$STD uv pip install --python /opt/profilarr/backend/.venv/bin/python -r requirements-relaxed.txt
|
||||
rm -f requirements-relaxed.txt
|
||||
msg_ok "Installed Python Dependencies"
|
||||
|
||||
msg_info "Building Frontend"
|
||||
if [[ -d /opt/profilarr/frontend ]]; then
|
||||
cd /opt/profilarr/frontend
|
||||
$STD npm install
|
||||
$STD npm run build
|
||||
cp -r dist /opt/profilarr/backend/app/static
|
||||
fi
|
||||
msg_ok "Built Frontend"
|
||||
|
||||
msg_info "Restoring Data"
|
||||
if [[ -d /opt/profilarr_config_backup ]]; then
|
||||
mkdir -p /config
|
||||
cp -r /opt/profilarr_config_backup/. /config/
|
||||
rm -rf /opt/profilarr_config_backup
|
||||
fi
|
||||
msg_ok "Restored Data"
|
||||
|
||||
msg_info "Starting Service"
|
||||
systemctl start profilarr
|
||||
msg_ok "Started Service"
|
||||
msg_ok "Updated successfully!"
|
||||
fi
|
||||
exit
|
||||
}
|
||||
|
||||
start
|
||||
build_container
|
||||
description
|
||||
|
||||
msg_ok "Completed Successfully!\n"
|
||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:6868${CL}"
|
||||
@@ -34,14 +34,14 @@ function update_script() {
|
||||
msg_warn "This requires MANUAL config changes in /etc/vikunja/config.yml."
|
||||
msg_warn "See: https://vikunja.io/changelog/whats-new-in-vikunja-1.0.0/#config-changes"
|
||||
|
||||
read -rp "Continue with update? (y to proceed): " -t 30 CONFIRM1 || exit 1
|
||||
read -rp "Continue with update? (y to proceed): " -t 30 CONFIRM1 || exit 254
|
||||
[[ "$CONFIRM1" =~ ^[yY]$ ]] || exit 0
|
||||
|
||||
echo
|
||||
msg_warn "Vikunja may not start after the update until you manually adjust the config."
|
||||
msg_warn "Details: https://vikunja.io/changelog/whats-new-in-vikunja-1.0.0/#config-changes"
|
||||
|
||||
read -rp "Acknowledge and continue? (y): " -t 30 CONFIRM2 || exit 1
|
||||
read -rp "Acknowledge and continue? (y): " -t 30 CONFIRM2 || exit 254
|
||||
[[ "$CONFIRM2" =~ ^[yY]$ ]] || exit 0
|
||||
fi
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"generated": "2026-03-02T06:20:15Z",
|
||||
"generated": "2026-03-02T12:12:21Z",
|
||||
"versions": [
|
||||
{
|
||||
"slug": "2fauth",
|
||||
@@ -312,9 +312,9 @@
|
||||
{
|
||||
"slug": "domain-monitor",
|
||||
"repo": "Hosteroid/domain-monitor",
|
||||
"version": "v1.1.3",
|
||||
"version": "v1.1.4",
|
||||
"pinned": false,
|
||||
"date": "2026-02-11T15:48:18Z"
|
||||
"date": "2026-03-02T09:25:01Z"
|
||||
},
|
||||
{
|
||||
"slug": "donetick",
|
||||
@@ -452,9 +452,9 @@
|
||||
{
|
||||
"slug": "gitea-mirror",
|
||||
"repo": "RayLabsHQ/gitea-mirror",
|
||||
"version": "v3.10.1",
|
||||
"version": "v3.11.0",
|
||||
"pinned": false,
|
||||
"date": "2026-03-01T03:08:07Z"
|
||||
"date": "2026-03-02T10:19:59Z"
|
||||
},
|
||||
{
|
||||
"slug": "glance",
|
||||
@@ -634,9 +634,9 @@
|
||||
{
|
||||
"slug": "jotty",
|
||||
"repo": "fccview/jotty",
|
||||
"version": "1.20.0",
|
||||
"version": "1.21.0",
|
||||
"pinned": false,
|
||||
"date": "2026-02-12T09:23:30Z"
|
||||
"date": "2026-03-02T11:08:54Z"
|
||||
},
|
||||
{
|
||||
"slug": "kapowarr",
|
||||
@@ -1156,6 +1156,13 @@
|
||||
"pinned": false,
|
||||
"date": "2025-11-12T07:10:14Z"
|
||||
},
|
||||
{
|
||||
"slug": "profilarr",
|
||||
"repo": "Dictionarry-Hub/profilarr",
|
||||
"version": "v1.1.4",
|
||||
"pinned": false,
|
||||
"date": "2026-01-29T14:57:25Z"
|
||||
},
|
||||
{
|
||||
"slug": "projectsend",
|
||||
"repo": "projectsend/projectsend",
|
||||
@@ -1418,9 +1425,9 @@
|
||||
{
|
||||
"slug": "snowshare",
|
||||
"repo": "TuroYT/snowshare",
|
||||
"version": "v1.3.7",
|
||||
"version": "v1.3.8",
|
||||
"pinned": false,
|
||||
"date": "2026-02-23T15:51:39Z"
|
||||
"date": "2026-03-02T07:43:42Z"
|
||||
},
|
||||
{
|
||||
"slug": "sonarr",
|
||||
@@ -1656,9 +1663,9 @@
|
||||
{
|
||||
"slug": "victoriametrics",
|
||||
"repo": "VictoriaMetrics/VictoriaMetrics",
|
||||
"version": "v1.136.0",
|
||||
"version": "v1.137.0",
|
||||
"pinned": false,
|
||||
"date": "2026-02-16T13:17:50Z"
|
||||
"date": "2026-03-02T10:09:29Z"
|
||||
},
|
||||
{
|
||||
"slug": "vikunja",
|
||||
@@ -1684,9 +1691,9 @@
|
||||
{
|
||||
"slug": "wanderer",
|
||||
"repo": "meilisearch/meilisearch",
|
||||
"version": "v1.36.0",
|
||||
"version": "v1.37.0",
|
||||
"pinned": false,
|
||||
"date": "2026-02-23T08:13:32Z"
|
||||
"date": "2026-03-02T09:16:36Z"
|
||||
},
|
||||
{
|
||||
"slug": "warracker",
|
||||
@@ -1789,9 +1796,9 @@
|
||||
{
|
||||
"slug": "zigbee2mqtt",
|
||||
"repo": "Koenkk/zigbee2mqtt",
|
||||
"version": "2.9.0",
|
||||
"version": "2.9.1",
|
||||
"pinned": false,
|
||||
"date": "2026-03-01T13:58:14Z"
|
||||
"date": "2026-03-02T11:16:46Z"
|
||||
},
|
||||
{
|
||||
"slug": "zipline",
|
||||
@@ -1803,9 +1810,9 @@
|
||||
{
|
||||
"slug": "zitadel",
|
||||
"repo": "zitadel/zitadel",
|
||||
"version": "v4.11.1",
|
||||
"version": "v4.12.0",
|
||||
"pinned": false,
|
||||
"date": "2026-02-25T06:13:13Z"
|
||||
"date": "2026-03-02T08:16:10Z"
|
||||
},
|
||||
{
|
||||
"slug": "zoraxy",
|
||||
|
||||
35
frontend/public/json/profilarr.json
Normal file
35
frontend/public/json/profilarr.json
Normal file
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"name": "Profilarr",
|
||||
"slug": "profilarr",
|
||||
"categories": [
|
||||
14
|
||||
],
|
||||
"date_created": "2026-03-02",
|
||||
"type": "ct",
|
||||
"updateable": true,
|
||||
"privileged": false,
|
||||
"interface_port": 6868,
|
||||
"documentation": "https://github.com/Dictionarry-Hub/profilarr#readme",
|
||||
"website": "https://github.com/Dictionarry-Hub/profilarr",
|
||||
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/profilarr.webp",
|
||||
"config_path": "/config",
|
||||
"description": "Profilarr is a configuration management platform for Radarr and Sonarr that simplifies importing, syncing, and managing quality profiles, custom formats, and release profiles.",
|
||||
"install_methods": [
|
||||
{
|
||||
"type": "default",
|
||||
"script": "ct/profilarr.sh",
|
||||
"resources": {
|
||||
"cpu": 2,
|
||||
"ram": 2048,
|
||||
"hdd": 8,
|
||||
"os": "Debian",
|
||||
"version": "13"
|
||||
}
|
||||
}
|
||||
],
|
||||
"default_credentials": {
|
||||
"username": null,
|
||||
"password": null
|
||||
},
|
||||
"notes": []
|
||||
}
|
||||
@@ -19,8 +19,9 @@ export function getDisplayValueFromType(type: string) {
|
||||
case "vm":
|
||||
return "VM";
|
||||
case "pve":
|
||||
return "PVE";
|
||||
case "addon":
|
||||
return "";
|
||||
return "ADDON";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
@@ -36,10 +37,9 @@ export function LatestScripts({
|
||||
onPageChange: (page: number) => void;
|
||||
}) {
|
||||
const latestScripts = useMemo(() => {
|
||||
if (!items)
|
||||
return [];
|
||||
if (!items) return [];
|
||||
|
||||
const scripts = items.flatMap(category => category.scripts || []);
|
||||
const scripts = items.flatMap((category) => category.scripts || []);
|
||||
|
||||
// Filter out duplicates by slug
|
||||
const uniqueScriptsMap = new Map<string, Script>();
|
||||
@@ -97,7 +97,7 @@ export function LatestScripts({
|
||||
</div>
|
||||
)}
|
||||
<div className="min-w flex w-full flex-row flex-wrap gap-4">
|
||||
{latestScripts.slice(startIndex, endIndex).map(script => (
|
||||
{latestScripts.slice(startIndex, endIndex).map((script) => (
|
||||
<Card key={script.slug} className="min-w-[250px] flex-1 flex-grow bg-accent/30">
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center gap-3">
|
||||
@@ -108,15 +108,13 @@ export function LatestScripts({
|
||||
height={64}
|
||||
width={64}
|
||||
alt=""
|
||||
onError={e => ((e.currentTarget as HTMLImageElement).src = `/${basePath}/logo.png`)}
|
||||
onError={(e) => ((e.currentTarget as HTMLImageElement).src = `/${basePath}/logo.png`)}
|
||||
className="h-11 w-11 object-contain"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<p className="text-lg line-clamp-1">
|
||||
{script.name}
|
||||
{" "}
|
||||
{getDisplayValueFromType(script.type)}
|
||||
{script.name} {getDisplayValueFromType(script.type)}
|
||||
</p>
|
||||
<p className="text-sm text-muted-foreground flex items-center gap-1">
|
||||
<CalendarPlus className="h-4 w-4" />
|
||||
@@ -149,7 +147,7 @@ export function LatestScripts({
|
||||
|
||||
export function MostViewedScripts({ items }: { items: Category[] }) {
|
||||
const mostViewedScripts = items.reduce((acc: Script[], category) => {
|
||||
const foundScripts = category.scripts.filter(script => mostPopularScripts.includes(script.slug));
|
||||
const foundScripts = category.scripts.filter((script) => mostPopularScripts.includes(script.slug));
|
||||
return acc.concat(foundScripts);
|
||||
}, []);
|
||||
|
||||
@@ -161,7 +159,7 @@ export function MostViewedScripts({ items }: { items: Category[] }) {
|
||||
</>
|
||||
)}
|
||||
<div className="min-w flex w-full flex-row flex-wrap gap-4">
|
||||
{mostViewedScripts.map(script => (
|
||||
{mostViewedScripts.map((script) => (
|
||||
<Card key={script.slug} className="min-w-[250px] flex-1 flex-grow bg-accent/30">
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center gap-3">
|
||||
@@ -172,15 +170,13 @@ export function MostViewedScripts({ items }: { items: Category[] }) {
|
||||
height={64}
|
||||
width={64}
|
||||
alt=""
|
||||
onError={e => ((e.currentTarget as HTMLImageElement).src = `/${basePath}/logo.png`)}
|
||||
onError={(e) => ((e.currentTarget as HTMLImageElement).src = `/${basePath}/logo.png`)}
|
||||
className="h-11 w-11 object-contain"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<p className="line-clamp-1 text-lg">
|
||||
{script.name}
|
||||
{" "}
|
||||
{getDisplayValueFromType(script.type)}
|
||||
{script.name} {getDisplayValueFromType(script.type)}
|
||||
</p>
|
||||
<p className="flex items-center gap-1 text-sm text-muted-foreground">
|
||||
<CalendarPlus className="h-4 w-4" />
|
||||
|
||||
@@ -14,6 +14,7 @@ import { basePath } from "@/config/site-config";
|
||||
import { extractDate } from "@/lib/time";
|
||||
|
||||
import DisableDescription from "./script-items/disable-description";
|
||||
import { formattedBadge } from "@/components/command-menu";
|
||||
import { getDisplayValueFromType } from "./script-info-blocks";
|
||||
import DefaultPassword from "./script-items/default-password";
|
||||
import InstallCommand from "./script-items/install-command";
|
||||
@@ -31,7 +32,7 @@ type ScriptItemProps = {
|
||||
|
||||
function ScriptHeader({ item }: { item: Script }) {
|
||||
const defaultInstallMethod = item.install_methods?.[0];
|
||||
const os = defaultInstallMethod?.resources?.os || "Proxmox Node";
|
||||
const os = defaultInstallMethod?.resources?.os || (item.type === "addon" ? "Existing LXC or Proxmox Node" : "Proxmox Node");
|
||||
const version = defaultInstallMethod?.resources?.version || "";
|
||||
|
||||
return (
|
||||
@@ -55,9 +56,7 @@ function ScriptHeader({ item }: { item: Script }) {
|
||||
<h1 className="text-2xl font-semibold tracking-tight flex items-center gap-2">
|
||||
{item.name}
|
||||
<VersionInfo item={item} />
|
||||
<span className="inline-flex items-center rounded-md bg-accent/30 px-2 py-1 text-sm">
|
||||
{getDisplayValueFromType(item.type)}
|
||||
</span>
|
||||
{formattedBadge(item.type)}
|
||||
</h1>
|
||||
<div className="mt-1 flex items-center gap-3 text-sm text-muted-foreground">
|
||||
<span>
|
||||
|
||||
@@ -36,17 +36,24 @@ const TooltipBadge: React.FC<TooltipProps> = ({ variant, label, content }) => (
|
||||
export default function Tooltips({ item }: { item: Script }) {
|
||||
return (
|
||||
<div className="flex items-center gap-2">
|
||||
{item.privileged && (
|
||||
{item.privileged && item.type !== "addon" && (
|
||||
<TooltipBadge variant="warning" label="Privileged" content="This script will be run in a privileged LXC" />
|
||||
)}
|
||||
{item.updateable && item.type !== "pve" && (
|
||||
{item.updateable && item.type !== "pve" && item.type !== "addon" && (
|
||||
<TooltipBadge
|
||||
variant="success"
|
||||
label="Updateable"
|
||||
content={`To Update ${item.name}, run the command below (or type update) in the LXC Console.`}
|
||||
/>
|
||||
)}
|
||||
{!item.updateable && item.type !== "pve" && <TooltipBadge variant="failure" label="Not Updateable" />}
|
||||
{item.updateable && item.type === "addon" && (
|
||||
<TooltipBadge
|
||||
variant="success"
|
||||
label="Updateable"
|
||||
content={`Run update_${item.slug} to update or use the bash command inside the LXC.`}
|
||||
/>
|
||||
)}
|
||||
{!item.updateable && item.type !== "pve" && item.type !== "addon" && <TooltipBadge variant="failure" label="Not Updateable" />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -32,6 +32,11 @@ function ScriptContent() {
|
||||
.flat()
|
||||
.find(script => script.slug === selectedScript);
|
||||
setItem(script);
|
||||
if (script) {
|
||||
document.title = `${script.name} | Proxmox VE Helper-Scripts`;
|
||||
}
|
||||
} else {
|
||||
document.title = "Proxmox VE Helper-Scripts";
|
||||
}
|
||||
}, [selectedScript, links]);
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ network_check
|
||||
update_os
|
||||
|
||||
read -r -p "${TAB3}Enter PostgreSQL version (15/16/17): " ver
|
||||
[[ $ver =~ ^(15|16|17)$ ]] || { echo "Invalid version"; exit 1; }
|
||||
[[ $ver =~ ^(15|16|17)$ ]] || { echo "Invalid version"; exit 64; }
|
||||
|
||||
msg_info "Installing PostgreSQL ${ver}"
|
||||
$STD apk add --no-cache postgresql${ver} postgresql${ver}-contrib postgresql${ver}-openrc sudo
|
||||
|
||||
@@ -25,7 +25,7 @@ case $version in
|
||||
;;
|
||||
*)
|
||||
msg_error "Invalid JDK version selected. Please enter 8, 11, 17 or 21."
|
||||
exit 1
|
||||
exit 64
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
@@ -39,7 +39,7 @@ case $version in
|
||||
;;
|
||||
*)
|
||||
msg_error "Invalid JDK version selected. Please enter 11, 17 or 21."
|
||||
exit 1
|
||||
exit 64
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
@@ -53,13 +53,13 @@ case $version in
|
||||
;;
|
||||
*)
|
||||
msg_error "Invalid JDK version selected. Please enter 17 or 21."
|
||||
exit 1
|
||||
exit 64
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
msg_error "Invalid Tomcat version selected. Please enter 9, 10.1 or 11."
|
||||
exit 1
|
||||
exit 64
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ mkdir -p /opt/booklore/dist
|
||||
JAR_PATH=$(find /opt/booklore/booklore-api/build/libs -maxdepth 1 -type f -name "booklore-api-*.jar" ! -name "*plain*" | head -n1)
|
||||
if [[ -z "$JAR_PATH" ]]; then
|
||||
msg_error "Backend JAR not found"
|
||||
exit 1
|
||||
exit 153
|
||||
fi
|
||||
cp "$JAR_PATH" /opt/booklore/dist/app.jar
|
||||
msg_ok "Built Backend"
|
||||
|
||||
@@ -86,7 +86,7 @@ EOF
|
||||
msg_ok "Docker TCP socket available on $socket"
|
||||
else
|
||||
msg_error "Docker failed to restart. Check journalctl -xeu docker.service"
|
||||
exit 1
|
||||
exit 150
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ msg_info "Fetching latest EMQX Enterprise version"
|
||||
LATEST_VERSION=$(curl -fsSL https://www.emqx.com/en/downloads/enterprise | grep -oP '/en/downloads/enterprise/v\K[0-9]+\.[0-9]+\.[0-9]+' | sort -V | tail -n1)
|
||||
if [[ -z "$LATEST_VERSION" ]]; then
|
||||
msg_error "Failed to determine latest EMQX version"
|
||||
exit 1
|
||||
exit 250
|
||||
fi
|
||||
msg_ok "Latest version: v$LATEST_VERSION"
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ update_os
|
||||
source /etc/os-release
|
||||
if [[ "$VERSION_ID" != "12" ]]; then
|
||||
msg_error "Frigate requires Debian 12 (Bookworm) due to Python 3.11 dependencies"
|
||||
exit 1
|
||||
exit 238
|
||||
fi
|
||||
|
||||
msg_info "Converting APT sources to DEB822 format"
|
||||
|
||||
@@ -31,7 +31,7 @@ fi
|
||||
|
||||
if [[ -z "$KASM_URL" ]] || [[ -z "$KASM_VERSION" ]]; then
|
||||
msg_error "Unable to detect latest Kasm release URL."
|
||||
exit 1
|
||||
exit 250
|
||||
fi
|
||||
msg_ok "Detected Kasm Workspaces version $KASM_VERSION"
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ $STD apt install -y \
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
PYTHON_VERSION="3.12" setup_uv
|
||||
POSTGRES_VERSION="16" setup_postgresql
|
||||
PG_VERSION="16" setup_postgresql
|
||||
NODE_MODULE="yarn" NODE_VERSION="24" setup_nodejs
|
||||
fetch_and_deploy_gh_release "mealie" "mealie-recipes/mealie" "tarball" "latest" "/opt/mealie"
|
||||
PG_DB_NAME="mealie_db" PG_DB_USER="mealie_user" PG_DB_GRANT_SUPERUSER="true" setup_postgresql_db
|
||||
|
||||
@@ -51,7 +51,7 @@ while true; do
|
||||
attempts=$((attempts + 1))
|
||||
if [[ "$attempts" -ge 3 ]]; then
|
||||
msg_error "Maximum attempts reached. Exiting."
|
||||
exit 1
|
||||
exit 254
|
||||
fi
|
||||
done
|
||||
|
||||
@@ -76,11 +76,11 @@ for i in {1..60}; do
|
||||
elif [[ "$STATUS" == "unhealthy" ]]; then
|
||||
msg_error "NPMplus container is unhealthy! Check logs."
|
||||
docker logs "$CONTAINER_ID"
|
||||
exit 1
|
||||
exit 150
|
||||
fi
|
||||
fi
|
||||
sleep 2
|
||||
[[ $i -eq 60 ]] && msg_error "NPMplus container did not become healthy within 120s." && docker logs "$CONTAINER_ID" && exit 1
|
||||
[[ $i -eq 60 ]] && msg_error "NPMplus container did not become healthy within 120s." && docker logs "$CONTAINER_ID" && exit 150
|
||||
done
|
||||
msg_ok "Builded and started NPMplus"
|
||||
|
||||
|
||||
@@ -78,11 +78,11 @@ if curl -fL# -C - -o "$TMP_TAR" "$OLLAMA_URL"; then
|
||||
msg_ok "Installed Ollama ${RELEASE}"
|
||||
else
|
||||
msg_error "Extraction failed – archive corrupt or incomplete"
|
||||
exit 1
|
||||
exit 251
|
||||
fi
|
||||
else
|
||||
msg_error "Download failed – $OLLAMA_URL not reachable"
|
||||
exit 1
|
||||
exit 250
|
||||
fi
|
||||
|
||||
msg_info "Creating ollama User and Group"
|
||||
|
||||
@@ -59,7 +59,7 @@ EOF
|
||||
else
|
||||
msg_error "Failed to download or verify GPG key from $KEY_URL"
|
||||
[[ -f "$TMP_KEY_CONTENT" ]] && rm -f "$TMP_KEY_CONTENT"
|
||||
exit 1
|
||||
exit 250
|
||||
fi
|
||||
rm -f "$TMP_KEY_CONTENT"
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ for server in "${servers[@]}"; do
|
||||
done
|
||||
if ((attempt >= MAX_ATTEMPTS)); then
|
||||
msg_error "No more attempts - aborting script!"
|
||||
exit 1
|
||||
exit 254
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ update_os
|
||||
read -r -p "${TAB3}Enter PostgreSQL version (15/16/17/18): " ver
|
||||
[[ $ver =~ ^(15|16|17|18)$ ]] || {
|
||||
echo "Invalid version"
|
||||
exit 1
|
||||
exit 64
|
||||
}
|
||||
PG_VERSION=$ver setup_postgresql
|
||||
|
||||
|
||||
74
install/profilarr-install.sh
Normal file
74
install/profilarr-install.sh
Normal file
@@ -0,0 +1,74 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: michelroegl-brunner
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://github.com/Dictionarry-Hub/profilarr
|
||||
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
color
|
||||
verb_ip6
|
||||
catch_errors
|
||||
setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
|
||||
msg_info "Installing Dependencies"
|
||||
$STD apt install -y \
|
||||
build-essential \
|
||||
python3-dev \
|
||||
libffi-dev \
|
||||
libssl-dev \
|
||||
git
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
PYTHON_VERSION="3.12" setup_uv
|
||||
NODE_VERSION="22" setup_nodejs
|
||||
|
||||
msg_info "Creating directories"
|
||||
mkdir -p /opt/profilarr \
|
||||
/config
|
||||
msg_ok "Created directories"
|
||||
|
||||
fetch_and_deploy_gh_release "profilarr" "Dictionarry-Hub/profilarr" "tarball"
|
||||
|
||||
msg_info "Installing Python Dependencies"
|
||||
cd /opt/profilarr/backend
|
||||
$STD uv venv /opt/profilarr/backend/.venv
|
||||
sed 's/==/>=/g' requirements.txt >requirements-relaxed.txt
|
||||
$STD uv pip install --python /opt/profilarr/backend/.venv/bin/python -r requirements-relaxed.txt
|
||||
rm -f requirements-relaxed.txt
|
||||
msg_ok "Installed Python Dependencies"
|
||||
|
||||
msg_info "Building Frontend"
|
||||
cd /opt/profilarr/frontend
|
||||
$STD npm install
|
||||
$STD npm run build
|
||||
cp -r dist /opt/profilarr/backend/app/static
|
||||
msg_ok "Built Frontend"
|
||||
|
||||
msg_info "Creating Service"
|
||||
cat <<EOF >/etc/systemd/system/profilarr.service
|
||||
[Unit]
|
||||
Description=Profilarr - Configuration Management Platform for Radarr/Sonarr
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=/opt/profilarr/backend
|
||||
Environment="PATH=/opt/profilarr/backend/.venv/bin:/usr/local/bin:/usr/bin:/bin"
|
||||
Environment="PYTHONPATH=/opt/profilarr/backend"
|
||||
ExecStart=/opt/profilarr/backend/.venv/bin/gunicorn --bind 0.0.0.0:6868 --timeout 600 app.main:create_app()
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
systemctl enable -q --now profilarr
|
||||
msg_ok "Created Service"
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
@@ -25,7 +25,7 @@ if useradd -r -m -d /opt/pulse-home -s /usr/sbin/nologin pulse; then
|
||||
msg_ok "Created User"
|
||||
else
|
||||
msg_error "User creation failed"
|
||||
exit 1
|
||||
exit 71
|
||||
fi
|
||||
|
||||
mkdir -p /etc/pulse
|
||||
|
||||
@@ -34,7 +34,7 @@ while true; do
|
||||
[Nn]|[Nn][Oo]|"")
|
||||
msg_error "Terms not accepted. Installation cannot proceed."
|
||||
msg_error "Please review the terms and run the script again if you wish to proceed."
|
||||
exit 1
|
||||
exit 254
|
||||
;;
|
||||
*)
|
||||
msg_error "Invalid response. Please enter 'y' for yes or 'n' for no."
|
||||
@@ -47,7 +47,7 @@ DOWNLOAD_URL=$(curl -s "https://www.splunk.com/en_us/download/splunk-enterprise.
|
||||
RELEASE=$(echo "$DOWNLOAD_URL" | sed 's|.*/releases/\([^/]*\)/.*|\1|')
|
||||
$STD curl -fsSL -o "splunk-enterprise.tgz" "$DOWNLOAD_URL" || {
|
||||
msg_error "Failed to download Splunk Enterprise from the provided link."
|
||||
exit 1
|
||||
exit 250
|
||||
}
|
||||
$STD tar -xzf "splunk-enterprise.tgz" -C /opt
|
||||
rm -f "splunk-enterprise.tgz"
|
||||
|
||||
@@ -16,13 +16,13 @@ update_os
|
||||
if [[ "${CTTYPE:-1}" != "0" ]]; then
|
||||
msg_error "UniFi OS Server requires a privileged LXC container."
|
||||
msg_error "Recreate the container with unprivileged=0."
|
||||
exit 1
|
||||
exit 10
|
||||
fi
|
||||
|
||||
if [[ ! -e /dev/net/tun ]]; then
|
||||
msg_error "Missing /dev/net/tun in container."
|
||||
msg_error "Enable TUN/TAP (var_tun=yes) or add /dev/net/tun passthrough."
|
||||
exit 1
|
||||
exit 236
|
||||
fi
|
||||
|
||||
msg_info "Installing dependencies"
|
||||
@@ -48,7 +48,7 @@ TEMP_JSON="$(mktemp)"
|
||||
if ! curl -fsSL "$API_URL" -o "$TEMP_JSON"; then
|
||||
rm -f "$TEMP_JSON"
|
||||
msg_error "Failed to fetch data from Ubiquiti API"
|
||||
exit 1
|
||||
exit 250
|
||||
fi
|
||||
LATEST=$(jq -r '
|
||||
._embedded.firmware
|
||||
@@ -62,7 +62,7 @@ UOS_URL=$(echo "$LATEST" | jq -r '._links.data.href')
|
||||
rm -f "$TEMP_JSON"
|
||||
if [[ -z "$UOS_URL" || -z "$UOS_VERSION" || "$UOS_URL" == "null" ]]; then
|
||||
msg_error "Failed to parse UniFi OS Server version or download URL"
|
||||
exit 1
|
||||
exit 250
|
||||
fi
|
||||
msg_ok "Found UniFi OS Server ${UOS_VERSION}"
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ if gpg --verify /tmp/zerotier-install.sh >/dev/null 2>&1; then
|
||||
$STD bash /tmp/zerotier-install.sh
|
||||
else
|
||||
msg_warn "Could not verify signature of Zerotier-One install script. Exiting..."
|
||||
exit 1
|
||||
exit 250
|
||||
fi
|
||||
msg_ok "Setup Zerotier-One"
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ setting_up_container() {
|
||||
if [ "$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d'/' -f1)" = "" ]; then
|
||||
echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}"
|
||||
echo -e "${NETWORK}Check Network Settings"
|
||||
exit 1
|
||||
exit 121
|
||||
fi
|
||||
msg_ok "Set up Container OS"
|
||||
msg_ok "Network Connected: ${BL}$(ip addr show | grep 'inet ' | awk '{print $2}' | cut -d'/' -f1 | tail -n1)${CL}"
|
||||
@@ -99,7 +99,7 @@ network_check() {
|
||||
echo -e "${INFO}${RD}Expect Issues Without Internet${CL}"
|
||||
else
|
||||
echo -e "${NETWORK}Check Network Settings"
|
||||
exit 1
|
||||
exit 122
|
||||
fi
|
||||
fi
|
||||
RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }')
|
||||
@@ -119,12 +119,12 @@ update_os() {
|
||||
local tools_content
|
||||
tools_content=$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func) || {
|
||||
msg_error "Failed to download tools.func"
|
||||
exit 6
|
||||
exit 115
|
||||
}
|
||||
source /dev/stdin <<<"$tools_content"
|
||||
if ! declare -f fetch_and_deploy_gh_release >/dev/null 2>&1; then
|
||||
msg_error "tools.func loaded but incomplete — missing expected functions"
|
||||
exit 6
|
||||
exit 115
|
||||
fi
|
||||
msg_ok "Updated Container OS"
|
||||
post_progress_to_api
|
||||
|
||||
@@ -124,6 +124,7 @@ detect_repo_source
|
||||
# * Generic/Shell errors (1-3, 10, 124-132, 134, 137, 139, 141, 143-146)
|
||||
# * curl/wget errors (4-8, 16, 18, 22-28, 30, 32-36, 39, 44-48, 51-52, 55-57, 59, 61, 63, 75, 78-79, 92, 95)
|
||||
# * Package manager errors (APT, DPKG: 100-102, 255)
|
||||
# * Script Validation & Setup (103-123)
|
||||
# * BSD sysexits (64-78)
|
||||
# * Systemd/Service errors (150-154)
|
||||
# * Python/pip/uv errors (160-162)
|
||||
@@ -131,7 +132,9 @@ detect_repo_source
|
||||
# * MySQL/MariaDB errors (180-183)
|
||||
# * MongoDB errors (190-193)
|
||||
# * Proxmox custom codes (200-231)
|
||||
# * Tools & Addon Scripts (232-238)
|
||||
# * Node.js/npm errors (239, 243, 245-249)
|
||||
# * Application Install/Update errors (250-254)
|
||||
# - Returns description string for given exit code
|
||||
# ------------------------------------------------------------------------------
|
||||
explain_exit_code() {
|
||||
@@ -189,6 +192,29 @@ explain_exit_code() {
|
||||
101) echo "APT: Configuration error (bad sources.list, malformed config)" ;;
|
||||
102) echo "APT: Lock held by another process (dpkg/apt still running)" ;;
|
||||
|
||||
# --- Script Validation & Setup (103-123) ---
|
||||
103) echo "Validation: Shell is not Bash" ;;
|
||||
104) echo "Validation: Not running as root (or invoked via sudo)" ;;
|
||||
105) echo "Validation: Proxmox VE version not supported" ;;
|
||||
106) echo "Validation: Architecture not supported (ARM / PiMox)" ;;
|
||||
107) echo "Validation: Kernel key parameters unreadable" ;;
|
||||
108) echo "Validation: Kernel key limits exceeded" ;;
|
||||
109) echo "Proxmox: No available container ID after max attempts" ;;
|
||||
110) echo "Proxmox: Failed to apply default.vars" ;;
|
||||
111) echo "Proxmox: App defaults file not available" ;;
|
||||
112) echo "Proxmox: Invalid install menu option" ;;
|
||||
113) echo "LXC: Under-provisioned — user aborted update" ;;
|
||||
114) echo "LXC: Storage too low — user aborted update" ;;
|
||||
115) echo "Download: install.func download failed or incomplete" ;;
|
||||
116) echo "Proxmox: Default bridge vmbr0 not found" ;;
|
||||
117) echo "LXC: Container did not reach running state" ;;
|
||||
118) echo "LXC: No IP assigned to container after timeout" ;;
|
||||
119) echo "Proxmox: No valid storage for rootdir content" ;;
|
||||
120) echo "Proxmox: No valid storage for vztmpl content" ;;
|
||||
121) echo "LXC: Container network not ready (no IP after retries)" ;;
|
||||
122) echo "LXC: No internet connectivity — user declined to continue" ;;
|
||||
123) echo "LXC: Local IP detection failed" ;;
|
||||
|
||||
# --- BSD sysexits.h (64-78) ---
|
||||
64) echo "Usage error (wrong arguments)" ;;
|
||||
65) echo "Data format error (bad input data)" ;;
|
||||
@@ -276,8 +302,18 @@ explain_exit_code() {
|
||||
223) echo "Proxmox: Template not available after download" ;;
|
||||
224) echo "Proxmox: PBS storage is for backups only" ;;
|
||||
225) echo "Proxmox: No template available for OS/Version" ;;
|
||||
226) echo "Proxmox: VM disk import or post-creation setup failed" ;;
|
||||
231) echo "Proxmox: LXC stack upgrade failed" ;;
|
||||
|
||||
# --- Tools & Addon Scripts (232-238) ---
|
||||
232) echo "Tools: Wrong execution environment (run on PVE host, not inside LXC)" ;;
|
||||
233) echo "Tools: Application not installed (update prerequisite missing)" ;;
|
||||
234) echo "Tools: No LXC containers found or available" ;;
|
||||
235) echo "Tools: Backup or restore operation failed" ;;
|
||||
236) echo "Tools: Required hardware not detected" ;;
|
||||
237) echo "Tools: Dependency package installation failed" ;;
|
||||
238) echo "Tools: OS or distribution not supported for this addon" ;;
|
||||
|
||||
# --- Node.js / npm / pnpm / yarn (239-249) ---
|
||||
239) echo "npm/Node.js: Unexpected runtime error or dependency failure" ;;
|
||||
243) echo "Node.js: Out of memory (JavaScript heap out of memory)" ;;
|
||||
@@ -287,6 +323,13 @@ explain_exit_code() {
|
||||
248) echo "Node.js: Invalid C++ addon / N-API failure" ;;
|
||||
249) echo "npm/pnpm/yarn: Unknown fatal error" ;;
|
||||
|
||||
# --- Application Install/Update Errors (250-254) ---
|
||||
250) echo "App: Download failed or version not determined" ;;
|
||||
251) echo "App: File extraction failed (corrupt or incomplete archive)" ;;
|
||||
252) echo "App: Required file or resource not found" ;;
|
||||
253) echo "App: Data migration required — update aborted" ;;
|
||||
254) echo "App: User declined prompt or input timed out" ;;
|
||||
|
||||
# --- DPKG ---
|
||||
255) echo "DPKG: Fatal internal error" ;;
|
||||
|
||||
@@ -350,6 +393,11 @@ get_error_text() {
|
||||
logfile="$BUILD_LOG"
|
||||
fi
|
||||
|
||||
# Try SILENT_LOGFILE as last resort (captures $STD command output)
|
||||
if [[ -z "$logfile" || ! -s "$logfile" ]] && [[ -n "${SILENT_LOGFILE:-}" && -s "${SILENT_LOGFILE}" ]]; then
|
||||
logfile="$SILENT_LOGFILE"
|
||||
fi
|
||||
|
||||
if [[ -n "$logfile" && -s "$logfile" ]]; then
|
||||
tail -n 20 "$logfile" 2>/dev/null | sed 's/\r$//' | sed 's/\x1b\[[0-9;]*[a-zA-Z]//g'
|
||||
fi
|
||||
@@ -395,6 +443,13 @@ get_full_log() {
|
||||
fi
|
||||
fi
|
||||
|
||||
# Fall back to SILENT_LOGFILE (captures $STD command output)
|
||||
if [[ -z "$logfile" || ! -s "$logfile" ]]; then
|
||||
if [[ -n "${SILENT_LOGFILE:-}" && -s "${SILENT_LOGFILE}" ]]; then
|
||||
logfile="$SILENT_LOGFILE"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -n "$logfile" && -s "$logfile" ]]; then
|
||||
# Strip ANSI codes, carriage returns, and anonymize IP addresses (GDPR)
|
||||
sed 's/\r$//' "$logfile" 2>/dev/null |
|
||||
@@ -833,7 +888,7 @@ post_update_to_api() {
|
||||
esac
|
||||
|
||||
# For failed/unknown status, resolve exit code and error description
|
||||
local short_error=""
|
||||
local short_error="" medium_error=""
|
||||
if [[ "$pb_status" == "failed" ]] || [[ "$pb_status" == "unknown" ]]; then
|
||||
if [[ "$raw_exit_code" =~ ^[0-9]+$ ]]; then
|
||||
exit_code="$raw_exit_code"
|
||||
@@ -853,6 +908,18 @@ post_update_to_api() {
|
||||
short_error=$(json_escape "$(explain_exit_code "$exit_code")")
|
||||
error_category=$(categorize_error "$exit_code")
|
||||
[[ -z "$error" ]] && error="Unknown error"
|
||||
|
||||
# Build medium error for attempt 2: explanation + last 100 log lines (≤16KB)
|
||||
# This is the critical middle ground between full 120KB log and generic-only description
|
||||
local medium_log=""
|
||||
medium_log=$(get_full_log 16384) || true # 16KB max
|
||||
if [[ -z "$medium_log" ]]; then
|
||||
medium_log=$(get_error_text) || true
|
||||
fi
|
||||
local medium_full
|
||||
medium_full=$(build_error_string "$exit_code" "$medium_log")
|
||||
medium_error=$(json_escape "$medium_full")
|
||||
[[ -z "$medium_error" ]] && medium_error="$short_error"
|
||||
fi
|
||||
|
||||
# Calculate duration if timer was started
|
||||
@@ -911,7 +978,7 @@ EOF
|
||||
return 0
|
||||
fi
|
||||
|
||||
# ── Attempt 2: Short error text (no full log) ──
|
||||
# ── Attempt 2: Medium error text (truncated log ≤16KB instead of full 120KB) ──
|
||||
sleep 1
|
||||
local RETRY_PAYLOAD
|
||||
RETRY_PAYLOAD=$(
|
||||
@@ -931,7 +998,7 @@ EOF
|
||||
"pve_version": "${pve_version}",
|
||||
"method": "${METHOD:-default}",
|
||||
"exit_code": ${exit_code},
|
||||
"error": "${short_error}",
|
||||
"error": "${medium_error}",
|
||||
"error_category": "${error_category}",
|
||||
"install_duration": ${duration},
|
||||
"cpu_vendor": "${cpu_vendor}",
|
||||
@@ -954,7 +1021,7 @@ EOF
|
||||
return 0
|
||||
fi
|
||||
|
||||
# ── Attempt 3: Minimal payload (bare minimum to set status) ──
|
||||
# ── Attempt 3: Minimal payload with medium error (bare minimum to set status) ──
|
||||
sleep 2
|
||||
local MINIMAL_PAYLOAD
|
||||
MINIMAL_PAYLOAD=$(
|
||||
@@ -966,7 +1033,7 @@ EOF
|
||||
"nsapp": "${NSAPP:-unknown}",
|
||||
"status": "${pb_status}",
|
||||
"exit_code": ${exit_code},
|
||||
"error": "${short_error}",
|
||||
"error": "${medium_error}",
|
||||
"error_category": "${error_category}",
|
||||
"install_duration": ${duration}
|
||||
}
|
||||
|
||||
@@ -119,7 +119,7 @@ maxkeys_check() {
|
||||
# Exit if kernel parameters are unavailable
|
||||
if [[ "$per_user_maxkeys" -eq 0 || "$per_user_maxbytes" -eq 0 ]]; then
|
||||
msg_error "Unable to read kernel key parameters. Ensure proper permissions."
|
||||
exit 1
|
||||
exit 107
|
||||
fi
|
||||
|
||||
# Fetch key usage for user ID 100000 (typical for containers)
|
||||
@@ -148,7 +148,7 @@ maxkeys_check() {
|
||||
# Provide next steps if issues are detected
|
||||
if [[ "$failure" -eq 1 ]]; then
|
||||
msg_error "Kernel key limits exceeded - see suggestions above"
|
||||
exit 1
|
||||
exit 108
|
||||
fi
|
||||
|
||||
# Silent success - only show errors if they exist
|
||||
@@ -355,7 +355,7 @@ get_valid_container_id() {
|
||||
attempts=$((attempts + 1))
|
||||
if [[ $attempts -ge $max_attempts ]]; then
|
||||
msg_error "Could not find available container ID after $max_attempts attempts"
|
||||
exit 1
|
||||
exit 109
|
||||
fi
|
||||
done
|
||||
|
||||
@@ -2035,7 +2035,7 @@ advanced_settings() {
|
||||
else
|
||||
whiptail --msgbox "Default bridge 'vmbr0' not found!\n\nPlease configure a network bridge in Proxmox first." 10 58
|
||||
msg_error "Default bridge 'vmbr0' not found"
|
||||
exit 1
|
||||
exit 116
|
||||
fi
|
||||
else
|
||||
if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \
|
||||
@@ -3023,7 +3023,7 @@ install_script() {
|
||||
3 | mydefaults | MYDEFAULTS | userdefaults | USERDEFAULTS)
|
||||
default_var_settings || {
|
||||
msg_error "Failed to apply default.vars"
|
||||
exit 1
|
||||
exit 110
|
||||
}
|
||||
defaults_target="/usr/local/community-scripts/default.vars"
|
||||
break
|
||||
@@ -3040,7 +3040,7 @@ install_script() {
|
||||
break
|
||||
else
|
||||
msg_error "No App Defaults available for ${APP}"
|
||||
exit 1
|
||||
exit 111
|
||||
fi
|
||||
;;
|
||||
"$SETTINGS_OPTION" | settings | SETTINGS)
|
||||
@@ -3051,7 +3051,7 @@ install_script() {
|
||||
;;
|
||||
*)
|
||||
msg_error "Invalid option: $CHOICE"
|
||||
exit 1
|
||||
exit 112
|
||||
;;
|
||||
esac
|
||||
done
|
||||
@@ -3135,7 +3135,7 @@ check_container_resources() {
|
||||
read -r prompt </dev/tty
|
||||
if [[ ! ${prompt,,} =~ ^(yes)$ ]]; then
|
||||
msg_error "Aborted: under-provisioned LXC (${current_cpu} CPU/${current_ram}MB RAM < ${var_cpu} CPU/${var_ram}MB RAM)"
|
||||
exit 1
|
||||
exit 113
|
||||
fi
|
||||
else
|
||||
echo -e ""
|
||||
@@ -3158,7 +3158,7 @@ check_container_storage() {
|
||||
read -r prompt </dev/tty
|
||||
if [[ ! ${prompt,,} =~ ^(y|yes)$ ]]; then
|
||||
msg_error "Aborted: storage too low (${usage}% used)"
|
||||
exit 1
|
||||
exit 114
|
||||
fi
|
||||
fi
|
||||
}
|
||||
@@ -3446,7 +3446,7 @@ start() {
|
||||
3)
|
||||
clear
|
||||
exit_script
|
||||
exit
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
ensure_profile_loaded
|
||||
@@ -3556,7 +3556,7 @@ build_container() {
|
||||
export FUNCTIONS_FILE_PATH="$(curl -fsSL "$_func_url")"
|
||||
if [[ -z "$FUNCTIONS_FILE_PATH" || ${#FUNCTIONS_FILE_PATH} -lt 100 ]]; then
|
||||
msg_error "Failed to download install functions from: $_func_url"
|
||||
exit 1
|
||||
exit 115
|
||||
fi
|
||||
|
||||
# Core exports for install.func
|
||||
@@ -3938,7 +3938,7 @@ EOF
|
||||
local ct_status
|
||||
ct_status=$(pct status "$CTID" 2>/dev/null || echo "unknown")
|
||||
msg_error "LXC Container did not reach running state (status: ${ct_status})"
|
||||
exit 1
|
||||
exit 117
|
||||
fi
|
||||
done
|
||||
|
||||
@@ -3967,7 +3967,7 @@ EOF
|
||||
echo " • Verify static IP configuration (if using static IP)"
|
||||
echo " • Check Proxmox firewall rules"
|
||||
echo " • If using Tailscale: Disable MagicDNS temporarily"
|
||||
exit 1
|
||||
exit 118
|
||||
fi
|
||||
|
||||
# Verify basic connectivity (ping test)
|
||||
@@ -4094,15 +4094,8 @@ EOF'
|
||||
# that sends "configuring" status AFTER the host already reported "failed"
|
||||
export CONTAINER_INSTALLING=true
|
||||
|
||||
# Capture lxc-attach terminal output to host-side log via tee.
|
||||
# This is the ONLY reliable way to get install output when:
|
||||
# - install.func fails to load (DNS error) → no container-side logging
|
||||
# - install script crashes before logging starts
|
||||
# - $STD/silent() not used for some commands
|
||||
# PIPESTATUS[0] gets the real exit code from lxc-attach (not from tee).
|
||||
local _LXC_CAPTURE_LOG="/tmp/.install-capture-${SESSION_ID}.log"
|
||||
lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/install/${var_install}.sh)" 2>&1 | tee "$_LXC_CAPTURE_LOG"
|
||||
local lxc_exit=${PIPESTATUS[0]}
|
||||
lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/install/${var_install}.sh)"
|
||||
local lxc_exit=$?
|
||||
|
||||
unset CONTAINER_INSTALLING
|
||||
|
||||
@@ -4164,19 +4157,9 @@ EOF'
|
||||
build_log_copied=true
|
||||
fi
|
||||
|
||||
# Copy and append INSTALL_LOG from container (with timeout to prevent hangs)
|
||||
# Copy and append INSTALL_LOG from container
|
||||
local temp_install_log="/tmp/.install-temp-${SESSION_ID}.log"
|
||||
local container_log_ok=false
|
||||
if timeout 8 pct pull "$CTID" "/root/.install-${SESSION_ID}.log" "$temp_install_log" 2>/dev/null; then
|
||||
# Only use container log if it has meaningful content (>100 bytes)
|
||||
if [[ -s "$temp_install_log" ]] && [[ $(stat -c%s "$temp_install_log" 2>/dev/null || echo 0) -gt 100 ]]; then
|
||||
container_log_ok=true
|
||||
fi
|
||||
fi
|
||||
|
||||
# PHASE 2: Use container-side log if available, otherwise use host-captured tee output
|
||||
local _LXC_CAPTURE_LOG="/tmp/.install-capture-${SESSION_ID}.log"
|
||||
if [[ "$container_log_ok" == true ]]; then
|
||||
if pct pull "$CTID" "/root/.install-${SESSION_ID}.log" "$temp_install_log" 2>/dev/null; then
|
||||
{
|
||||
echo "================================================================================"
|
||||
echo "PHASE 2: APPLICATION INSTALLATION (Container)"
|
||||
@@ -4184,24 +4167,8 @@ EOF'
|
||||
cat "$temp_install_log"
|
||||
echo ""
|
||||
} >>"$combined_log"
|
||||
rm -f "$temp_install_log"
|
||||
install_log_copied=true
|
||||
elif [[ -s "$_LXC_CAPTURE_LOG" ]]; then
|
||||
# Fallback: host-captured terminal output from lxc-attach
|
||||
# This captures everything the user saw, including errors when install.func
|
||||
# failed to load (DNS issues, etc.) and no container-side logging was set up.
|
||||
{
|
||||
echo "================================================================================"
|
||||
echo "PHASE 2: APPLICATION INSTALLATION (Container - captured from terminal)"
|
||||
echo "================================================================================"
|
||||
# Strip ANSI escape codes from terminal capture
|
||||
sed 's/\x1b\[[0-9;]*[a-zA-Z]//g' "$_LXC_CAPTURE_LOG" | sed 's/\r$//'
|
||||
echo ""
|
||||
} >>"$combined_log"
|
||||
install_log_copied=true
|
||||
fi
|
||||
rm -f "$temp_install_log"
|
||||
|
||||
if [[ "$install_log_copied" == true ]]; then
|
||||
# Point INSTALL_LOG to combined log so get_full_log() finds it
|
||||
INSTALL_LOG="$combined_log"
|
||||
fi
|
||||
@@ -4387,7 +4354,8 @@ EOF'
|
||||
echo ""
|
||||
echo -en "${YW}Select option [1-${max_option}] (default: 1, auto-remove in 60s): ${CL}"
|
||||
|
||||
if read -t 60 -r response </dev/tty; then
|
||||
local response=""
|
||||
if read -t 60 -r response; then
|
||||
case "${response:-1}" in
|
||||
1)
|
||||
# Remove container
|
||||
@@ -4474,9 +4442,8 @@ EOF'
|
||||
# Re-run install script in existing container (don't destroy/recreate)
|
||||
set +Eeuo pipefail
|
||||
trap - ERR
|
||||
local _LXC_CAPTURE_LOG="/tmp/.install-capture-${SESSION_ID}.log"
|
||||
lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/install/${var_install}.sh)" 2>&1 | tee "$_LXC_CAPTURE_LOG"
|
||||
local apt_retry_exit=${PIPESTATUS[0]}
|
||||
lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/install/${var_install}.sh)"
|
||||
local apt_retry_exit=$?
|
||||
set -Eeuo pipefail
|
||||
trap 'error_handler' ERR
|
||||
|
||||
@@ -4586,9 +4553,6 @@ EOF'
|
||||
exit $install_exit_code
|
||||
fi
|
||||
|
||||
# Clean up host-side capture log (not needed on success, already in combined_log on failure)
|
||||
rm -f "/tmp/.install-capture-${SESSION_ID}.log" 2>/dev/null
|
||||
|
||||
# Re-enable error handling after successful install or recovery menu completion
|
||||
set -Eeuo pipefail
|
||||
trap 'error_handler' ERR
|
||||
@@ -5004,11 +4968,11 @@ create_lxc_container() {
|
||||
# Storage capability check
|
||||
check_storage_support "rootdir" || {
|
||||
msg_error "No valid storage found for 'rootdir' [Container]"
|
||||
exit 1
|
||||
exit 119
|
||||
}
|
||||
check_storage_support "vztmpl" || {
|
||||
msg_error "No valid storage found for 'vztmpl' [Template]"
|
||||
exit 1
|
||||
exit 120
|
||||
}
|
||||
|
||||
# Template storage selection
|
||||
@@ -5286,7 +5250,7 @@ create_lxc_container() {
|
||||
}
|
||||
else
|
||||
msg_custom "🚫" "${YW}" "Installation cancelled"
|
||||
exit 1
|
||||
exit 0
|
||||
fi
|
||||
else
|
||||
msg_error "No ${PCT_OSTYPE} templates available"
|
||||
|
||||
@@ -276,7 +276,7 @@ shell_check() {
|
||||
msg_error "Your default shell is currently not set to Bash. To use these scripts, please switch to the Bash shell."
|
||||
echo -e "\nExiting..."
|
||||
sleep 2
|
||||
exit 1
|
||||
exit 103
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -293,7 +293,7 @@ root_check() {
|
||||
msg_error "Please run this script as root."
|
||||
echo -e "\nExiting..."
|
||||
sleep 2
|
||||
exit 1
|
||||
exit 104
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -314,7 +314,7 @@ pve_check() {
|
||||
if ((MINOR < 0 || MINOR > 9)); then
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported: Proxmox VE version 8.0 – 8.9"
|
||||
exit 1
|
||||
exit 105
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
@@ -325,7 +325,7 @@ pve_check() {
|
||||
if ((MINOR < 0 || MINOR > 1)); then
|
||||
msg_error "This version of Proxmox VE is not yet supported."
|
||||
msg_error "Supported: Proxmox VE version 9.0 – 9.1"
|
||||
exit 1
|
||||
exit 105
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
@@ -333,7 +333,7 @@ pve_check() {
|
||||
# All other unsupported versions
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported versions: Proxmox VE 8.0 – 8.9 or 9.0 – 9.1"
|
||||
exit 1
|
||||
exit 105
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
@@ -348,7 +348,7 @@ arch_check() {
|
||||
msg_error "This script will not work with PiMox (ARM architecture detected)."
|
||||
msg_warn "Visit https://github.com/asylumexp/Proxmox for ARM64 support."
|
||||
sleep 2
|
||||
exit 1
|
||||
exit 106
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -932,18 +932,13 @@ is_alpine() {
|
||||
#
|
||||
# - Determines if script should run in verbose mode
|
||||
# - Checks VERBOSE and var_verbose variables
|
||||
# - Also returns true if not running in TTY (pipe/redirect scenario)
|
||||
# - Used by msg_info() to decide between spinner and static output
|
||||
# - Note: Non-TTY (pipe) scenarios are handled separately in msg_info()
|
||||
# to allow spinner output to pass through pipes (e.g. lxc-attach | tee)
|
||||
# ------------------------------------------------------------------------------
|
||||
is_verbose_mode() {
|
||||
local verbose="${VERBOSE:-${var_verbose:-no}}"
|
||||
local tty_status
|
||||
if [[ -t 2 ]]; then
|
||||
tty_status="interactive"
|
||||
else
|
||||
tty_status="not-a-tty"
|
||||
fi
|
||||
[[ "$verbose" != "no" || ! -t 2 ]]
|
||||
[[ "$verbose" != "no" ]]
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
@@ -94,6 +94,29 @@ if ! declare -f explain_exit_code &>/dev/null; then
|
||||
100) echo "APT: Package manager error (broken packages / dependency problems)" ;;
|
||||
101) echo "APT: Configuration error (bad sources.list, malformed config)" ;;
|
||||
102) echo "APT: Lock held by another process (dpkg/apt still running)" ;;
|
||||
|
||||
# --- Script Validation & Setup (103-123) ---
|
||||
103) echo "Validation: Shell is not Bash" ;;
|
||||
104) echo "Validation: Not running as root (or invoked via sudo)" ;;
|
||||
105) echo "Validation: Proxmox VE version not supported" ;;
|
||||
106) echo "Validation: Architecture not supported (ARM / PiMox)" ;;
|
||||
107) echo "Validation: Kernel key parameters unreadable" ;;
|
||||
108) echo "Validation: Kernel key limits exceeded" ;;
|
||||
109) echo "Proxmox: No available container ID after max attempts" ;;
|
||||
110) echo "Proxmox: Failed to apply default.vars" ;;
|
||||
111) echo "Proxmox: App defaults file not available" ;;
|
||||
112) echo "Proxmox: Invalid install menu option" ;;
|
||||
113) echo "LXC: Under-provisioned — user aborted update" ;;
|
||||
114) echo "LXC: Storage too low — user aborted update" ;;
|
||||
115) echo "Download: install.func download failed or incomplete" ;;
|
||||
116) echo "Proxmox: Default bridge vmbr0 not found" ;;
|
||||
117) echo "LXC: Container did not reach running state" ;;
|
||||
118) echo "LXC: No IP assigned to container after timeout" ;;
|
||||
119) echo "Proxmox: No valid storage for rootdir content" ;;
|
||||
120) echo "Proxmox: No valid storage for vztmpl content" ;;
|
||||
121) echo "LXC: Container network not ready (no IP after retries)" ;;
|
||||
122) echo "LXC: No internet connectivity — user declined to continue" ;;
|
||||
123) echo "LXC: Local IP detection failed" ;;
|
||||
124) echo "Command timed out (timeout command)" ;;
|
||||
125) echo "Command failed to start (Docker daemon or execution error)" ;;
|
||||
126) echo "Command invoked cannot execute (permission problem?)" ;;
|
||||
@@ -155,6 +178,16 @@ if ! declare -f explain_exit_code &>/dev/null; then
|
||||
224) echo "Proxmox: PBS storage is for backups only" ;;
|
||||
225) echo "Proxmox: No template available for OS/Version" ;;
|
||||
231) echo "Proxmox: LXC stack upgrade failed" ;;
|
||||
|
||||
# --- Tools & Addon Scripts (232-238) ---
|
||||
232) echo "Tools: Wrong execution environment (run on PVE host, not inside LXC)" ;;
|
||||
233) echo "Tools: Application not installed (update prerequisite missing)" ;;
|
||||
234) echo "Tools: No LXC containers found or available" ;;
|
||||
235) echo "Tools: Backup or restore operation failed" ;;
|
||||
236) echo "Tools: Required hardware not detected" ;;
|
||||
237) echo "Tools: Dependency package installation failed" ;;
|
||||
238) echo "Tools: OS or distribution not supported for this addon" ;;
|
||||
|
||||
239) echo "npm/Node.js: Unexpected runtime error or dependency failure" ;;
|
||||
243) echo "Node.js: Out of memory (JavaScript heap out of memory)" ;;
|
||||
245) echo "Node.js: Invalid command-line option" ;;
|
||||
@@ -162,6 +195,14 @@ if ! declare -f explain_exit_code &>/dev/null; then
|
||||
247) echo "Node.js: Fatal internal error" ;;
|
||||
248) echo "Node.js: Invalid C++ addon / N-API failure" ;;
|
||||
249) echo "npm/pnpm/yarn: Unknown fatal error" ;;
|
||||
|
||||
# --- Application Install/Update Errors (250-254) ---
|
||||
250) echo "App: Download failed or version not determined" ;;
|
||||
251) echo "App: File extraction failed (corrupt or incomplete archive)" ;;
|
||||
252) echo "App: Required file or resource not found" ;;
|
||||
253) echo "App: Data migration required — update aborted" ;;
|
||||
254) echo "App: User declined prompt or input timed out" ;;
|
||||
|
||||
255) echo "DPKG: Fatal internal error" ;;
|
||||
*) echo "Unknown error" ;;
|
||||
esac
|
||||
@@ -286,7 +327,9 @@ error_handler() {
|
||||
echo -en "${YW}Remove broken container ${CTID}? (Y/n) [auto-remove in 60s]: ${CL}"
|
||||
fi
|
||||
|
||||
if read -t 60 -r response </dev/tty; then
|
||||
# Read user response
|
||||
local response=""
|
||||
if read -t 60 -r response; then
|
||||
if [[ -z "$response" || "$response" =~ ^[Yy]$ ]]; then
|
||||
echo ""
|
||||
if declare -f msg_info >/dev/null 2>&1; then
|
||||
@@ -365,10 +408,29 @@ _send_abort_telemetry() {
|
||||
[[ "${DIAGNOSTICS:-no}" == "no" ]] && return 0
|
||||
[[ -z "${RANDOM_UUID:-}" ]] && return 0
|
||||
|
||||
# Collect last 20 log lines for error diagnosis (best-effort)
|
||||
# Collect last 200 log lines for error diagnosis (best-effort)
|
||||
# Container context has no get_full_log(), so we gather as much as possible
|
||||
local error_text=""
|
||||
local logfile=""
|
||||
if [[ -n "${INSTALL_LOG:-}" && -s "${INSTALL_LOG}" ]]; then
|
||||
error_text=$(tail -n 20 "$INSTALL_LOG" 2>/dev/null | sed 's/\x1b\[[0-9;]*[a-zA-Z]//g; s/\\/\\\\/g; s/"/\\"/g; s/\r//g' | tr '\n' '|' | sed 's/|$//' | tr -d '\000-\010\013\014\016-\037\177') || true
|
||||
logfile="${INSTALL_LOG}"
|
||||
elif [[ -n "${SILENT_LOGFILE:-}" && -s "${SILENT_LOGFILE}" ]]; then
|
||||
logfile="${SILENT_LOGFILE}"
|
||||
fi
|
||||
|
||||
if [[ -n "$logfile" ]]; then
|
||||
error_text=$(tail -n 200 "$logfile" 2>/dev/null | sed 's/\x1b\[[0-9;]*[a-zA-Z]//g; s/\\/\\\\/g; s/"/\\"/g; s/\r//g' | tr '\n' '|' | sed 's/|$//' | head -c 16384 | tr -d '\000-\010\013\014\016-\037\177') || true
|
||||
fi
|
||||
|
||||
# Prepend exit code explanation header (like build_error_string does on host)
|
||||
local explanation=""
|
||||
if declare -f explain_exit_code &>/dev/null; then
|
||||
explanation=$(explain_exit_code "$exit_code" 2>/dev/null) || true
|
||||
fi
|
||||
if [[ -n "$explanation" && -n "$error_text" ]]; then
|
||||
error_text="exit_code=${exit_code} | ${explanation}|---|${error_text}"
|
||||
elif [[ -n "$explanation" && -z "$error_text" ]]; then
|
||||
error_text="exit_code=${exit_code} | ${explanation}"
|
||||
fi
|
||||
|
||||
# Calculate duration if start time is available
|
||||
@@ -377,10 +439,17 @@ _send_abort_telemetry() {
|
||||
duration=$(($(date +%s) - DIAGNOSTICS_START_TIME))
|
||||
fi
|
||||
|
||||
# Categorize error if function is available (may not be in minimal container context)
|
||||
local error_category=""
|
||||
if declare -f categorize_error &>/dev/null; then
|
||||
error_category=$(categorize_error "$exit_code" 2>/dev/null) || true
|
||||
fi
|
||||
|
||||
# Build JSON payload with error context
|
||||
local payload
|
||||
payload="{\"random_id\":\"${RANDOM_UUID}\",\"execution_id\":\"${EXECUTION_ID:-${RANDOM_UUID}}\",\"type\":\"${TELEMETRY_TYPE:-lxc}\",\"nsapp\":\"${NSAPP:-${app:-unknown}}\",\"status\":\"failed\",\"exit_code\":${exit_code}"
|
||||
[[ -n "$error_text" ]] && payload="${payload},\"error\":\"${error_text}\""
|
||||
[[ -n "$error_category" ]] && payload="${payload},\"error_category\":\"${error_category}\""
|
||||
[[ -n "$duration" ]] && payload="${payload},\"duration\":${duration}"
|
||||
payload="${payload}}"
|
||||
|
||||
|
||||
@@ -126,7 +126,7 @@ setting_up_container() {
|
||||
if [ "$(hostname -I)" = "" ]; then
|
||||
echo 1>&2 -e "\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}"
|
||||
echo -e "${NETWORK}Check Network Settings"
|
||||
exit 1
|
||||
exit 121
|
||||
fi
|
||||
rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
|
||||
systemctl disable -q --now systemd-networkd-wait-online.service
|
||||
@@ -177,7 +177,7 @@ network_check() {
|
||||
echo -e "${INFO}${RD}Expect Issues Without Internet${CL}"
|
||||
else
|
||||
echo -e "${NETWORK}Check Network Settings"
|
||||
exit 1
|
||||
exit 122
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -242,12 +242,12 @@ EOF
|
||||
local tools_content
|
||||
tools_content=$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func) || {
|
||||
msg_error "Failed to download tools.func"
|
||||
exit 6
|
||||
exit 115
|
||||
}
|
||||
source /dev/stdin <<<"$tools_content"
|
||||
if ! declare -f fetch_and_deploy_gh_release >/dev/null 2>&1; then
|
||||
msg_error "tools.func loaded but incomplete — missing expected functions"
|
||||
exit 6
|
||||
exit 115
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
@@ -934,7 +934,11 @@ upgrade_package() {
|
||||
# ------------------------------------------------------------------------------
|
||||
# Repository availability check with caching
|
||||
# ------------------------------------------------------------------------------
|
||||
declare -A _REPO_CACHE 2>/dev/null || true
|
||||
# Note: Must use -gA (global) because tools.func is sourced inside update_os()
|
||||
# function scope. Plain 'declare -A' would create a local variable that gets
|
||||
# destroyed when update_os() returns, causing "unbound variable" errors later
|
||||
# when setup_postgresql/verify_repo_available tries to access the cache key.
|
||||
declare -gA _REPO_CACHE 2>/dev/null || declare -A _REPO_CACHE 2>/dev/null || true
|
||||
|
||||
verify_repo_available() {
|
||||
local repo_url="$1"
|
||||
@@ -1732,6 +1736,13 @@ setup_deb822_repo() {
|
||||
rm -f "$tmp_gpg"
|
||||
return 1
|
||||
}
|
||||
else
|
||||
# Already binary — copy directly
|
||||
cp -f "$tmp_gpg" "/etc/apt/keyrings/${name}.gpg" || {
|
||||
msg_error "Failed to install GPG key for ${name}"
|
||||
rm -f "$tmp_gpg"
|
||||
return 1
|
||||
}
|
||||
fi
|
||||
rm -f "$tmp_gpg"
|
||||
chmod 644 "/etc/apt/keyrings/${name}.gpg"
|
||||
@@ -2195,7 +2206,12 @@ check_for_gh_release() {
|
||||
|
||||
local clean_tags=()
|
||||
for t in "${raw_tags[@]}"; do
|
||||
clean_tags+=("${t#v}")
|
||||
# Only strip leading 'v' when followed by a digit (e.g. v1.2.3)
|
||||
if [[ "$t" =~ ^v[0-9] ]]; then
|
||||
clean_tags+=("${t:1}")
|
||||
else
|
||||
clean_tags+=("$t")
|
||||
fi
|
||||
done
|
||||
|
||||
local latest_raw="${raw_tags[0]}"
|
||||
@@ -2308,7 +2324,12 @@ check_for_codeberg_release() {
|
||||
|
||||
local clean_tags=()
|
||||
for t in "${raw_tags[@]}"; do
|
||||
clean_tags+=("${t#v}")
|
||||
# Only strip leading 'v' when followed by a digit (e.g. v1.2.3)
|
||||
if [[ "$t" =~ ^v[0-9] ]]; then
|
||||
clean_tags+=("${t:1}")
|
||||
else
|
||||
clean_tags+=("$t")
|
||||
fi
|
||||
done
|
||||
|
||||
local latest_raw="${raw_tags[0]}"
|
||||
@@ -3138,7 +3159,10 @@ function fetch_and_deploy_gh_release() {
|
||||
local json tag_name
|
||||
json=$(</tmp/gh_rel.json)
|
||||
tag_name=$(echo "$json" | jq -r '.tag_name // .name // empty')
|
||||
[[ "$tag_name" =~ ^v ]] && version="${tag_name:1}" || version="$tag_name"
|
||||
# Only strip leading 'v' when followed by a digit (e.g. v1.2.3), not words like "version/..."
|
||||
[[ "$tag_name" =~ ^v[0-9] ]] && version="${tag_name:1}" || version="$tag_name"
|
||||
# Sanitize version for use in filenames (replace / with -)
|
||||
local version_safe="${version//\//-}"
|
||||
|
||||
if [[ "$current_version" == "$version" ]]; then
|
||||
$STD msg_ok "$app is already up-to-date (v$version)"
|
||||
@@ -3159,7 +3183,7 @@ function fetch_and_deploy_gh_release() {
|
||||
# GitHub API's tarball_url/zipball_url can return HTTP 300 Multiple Choices
|
||||
# when a branch and tag share the same name. Use explicit refs/tags/ URL instead.
|
||||
local direct_tarball_url="https://github.com/$repo/archive/refs/tags/$tag_name.tar.gz"
|
||||
filename="${app_lc}-${version}.tar.gz"
|
||||
filename="${app_lc}-${version_safe}.tar.gz"
|
||||
|
||||
curl $download_timeout -fsSL -o "$tmpdir/$filename" "$direct_tarball_url" || {
|
||||
msg_error "Download failed: $direct_tarball_url"
|
||||
@@ -5129,7 +5153,7 @@ current_ip="$(get_current_ip)"
|
||||
|
||||
if [[ -z "$current_ip" ]]; then
|
||||
echo "[ERROR] Could not detect local IP" >&2
|
||||
exit 1
|
||||
exit 123
|
||||
fi
|
||||
|
||||
if [[ -f "$IP_FILE" ]]; then
|
||||
@@ -5630,20 +5654,20 @@ function setup_mongodb() {
|
||||
# - Handles Debian Trixie libaio1t64 transition
|
||||
#
|
||||
# Variables:
|
||||
# USE_MYSQL_REPO - Set to "true" to use official MySQL repository
|
||||
# (default: false, uses distro packages)
|
||||
# USE_MYSQL_REPO - Use official MySQL repository (default: true)
|
||||
# Set to "false" to use distro packages instead
|
||||
# MYSQL_VERSION - MySQL version to install when using official repo
|
||||
# (e.g. 8.0, 8.4) (default: 8.0)
|
||||
#
|
||||
# Examples:
|
||||
# setup_mysql # Uses distro package (recommended)
|
||||
# USE_MYSQL_REPO=true setup_mysql # Uses official MySQL repo
|
||||
# USE_MYSQL_REPO=true MYSQL_VERSION="8.4" setup_mysql # Specific version
|
||||
# setup_mysql # Uses official MySQL repo, 8.0
|
||||
# MYSQL_VERSION="8.4" setup_mysql # Specific version from MySQL repo
|
||||
# USE_MYSQL_REPO=false setup_mysql # Uses distro package instead
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
function setup_mysql() {
|
||||
local MYSQL_VERSION="${MYSQL_VERSION:-8.0}"
|
||||
local USE_MYSQL_REPO="${USE_MYSQL_REPO:-false}"
|
||||
local USE_MYSQL_REPO="${USE_MYSQL_REPO:-true}"
|
||||
local DISTRO_ID DISTRO_CODENAME
|
||||
DISTRO_ID=$(awk -F= '/^ID=/{print $2}' /etc/os-release | tr -d '"')
|
||||
DISTRO_CODENAME=$(awk -F= '/^VERSION_CODENAME=/{print $2}' /etc/os-release)
|
||||
@@ -6344,21 +6368,21 @@ EOF
|
||||
# - Restores dumped data post-upgrade
|
||||
#
|
||||
# Variables:
|
||||
# USE_PGDG_REPO - Set to "true" to use official PGDG repository
|
||||
# (default: false, uses distro packages)
|
||||
# USE_PGDG_REPO - Use official PGDG repository (default: true)
|
||||
# Set to "false" to use distro packages instead
|
||||
# PG_VERSION - Major PostgreSQL version (e.g. 15, 16) (default: 16)
|
||||
# PG_MODULES - Comma-separated list of modules (e.g. "postgis,contrib")
|
||||
#
|
||||
# Examples:
|
||||
# setup_postgresql # Uses distro package (recommended)
|
||||
# USE_PGDG_REPO=true setup_postgresql # Uses official PGDG repo
|
||||
# USE_PGDG_REPO=true PG_VERSION="17" setup_postgresql # Specific version from PGDG
|
||||
# setup_postgresql # Uses PGDG repo, PG 16
|
||||
# PG_VERSION="17" setup_postgresql # Specific version from PGDG
|
||||
# USE_PGDG_REPO=false setup_postgresql # Uses distro package instead
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
function setup_postgresql() {
|
||||
local PG_VERSION="${PG_VERSION:-16}"
|
||||
local PG_MODULES="${PG_MODULES:-}"
|
||||
local USE_PGDG_REPO="${USE_PGDG_REPO:-false}"
|
||||
local USE_PGDG_REPO="${USE_PGDG_REPO:-true}"
|
||||
local DISTRO_ID DISTRO_CODENAME
|
||||
DISTRO_ID=$(awk -F= '/^ID=/{print $2}' /etc/os-release | tr -d '"')
|
||||
DISTRO_CODENAME=$(awk -F= '/^VERSION_CODENAME=/{print $2}' /etc/os-release)
|
||||
|
||||
@@ -244,7 +244,7 @@ curl_handler() {
|
||||
|
||||
if [[ -z "$url" ]]; then
|
||||
msg_error "no valid url or option entered for curl_handler"
|
||||
exit 1
|
||||
exit 64
|
||||
fi
|
||||
|
||||
$STD msg_info "Fetching: $url"
|
||||
@@ -273,7 +273,7 @@ curl_handler() {
|
||||
rm -f /tmp/curl_error.log
|
||||
fi
|
||||
__curl_err_handler "$exit_code" "$url" "$curl_stderr"
|
||||
exit 1 # hard exit if exit_code is not 0
|
||||
exit "$exit_code"
|
||||
fi
|
||||
|
||||
$STD printf "\r\033[K${INFO}${YW}Retry $attempt/$max_retries in ${delay}s...${CL}" >&2
|
||||
@@ -316,7 +316,7 @@ __curl_err_handler() {
|
||||
esac
|
||||
|
||||
[[ -n "$curl_msg" ]] && printf "%s\n" "$curl_msg" >&2
|
||||
exit 1
|
||||
exit "$exit_code"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
@@ -331,7 +331,7 @@ shell_check() {
|
||||
msg_error "Your default shell is currently not set to Bash. To use these scripts, please switch to the Bash shell."
|
||||
echo -e "\nExiting..."
|
||||
sleep 2
|
||||
exit
|
||||
exit 103
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -352,11 +352,11 @@ clear_line() {
|
||||
#
|
||||
# - Determines if script should run in verbose mode
|
||||
# - Checks VERBOSE and var_verbose variables
|
||||
# - Also returns true if not running in TTY (pipe/redirect scenario)
|
||||
# - Note: Non-TTY (pipe) scenarios are handled separately in msg_info()
|
||||
# ------------------------------------------------------------------------------
|
||||
is_verbose_mode() {
|
||||
local verbose="${VERBOSE:-${var_verbose:-no}}"
|
||||
[[ "$verbose" != "no" || ! -t 2 ]]
|
||||
[[ "$verbose" != "no" ]]
|
||||
}
|
||||
|
||||
### dev spinner ###
|
||||
@@ -552,7 +552,7 @@ check_root() {
|
||||
msg_error "Please run this script as root."
|
||||
echo -e "\nExiting..."
|
||||
sleep 2
|
||||
exit
|
||||
exit 104
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -562,7 +562,7 @@ pve_check() {
|
||||
echo -e "Requires Proxmox Virtual Environment Version 8.1 - 8.4 or 9.0 - 9.1."
|
||||
echo -e "Exiting..."
|
||||
sleep 2
|
||||
exit
|
||||
exit 105
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -572,21 +572,21 @@ arch_check() {
|
||||
echo -e "\n ${YWB}Visit https://github.com/asylumexp/Proxmox for ARM64 support. \n"
|
||||
echo -e "Exiting..."
|
||||
sleep 2
|
||||
exit
|
||||
exit 106
|
||||
fi
|
||||
}
|
||||
|
||||
exit_script() {
|
||||
clear
|
||||
echo -e "\n${CROSS}${RD}User exited script${CL}\n"
|
||||
exit
|
||||
exit 0
|
||||
}
|
||||
|
||||
check_hostname_conflict() {
|
||||
local hostname="$1"
|
||||
if qm list | awk '{print $2}' | grep -qx "$hostname"; then
|
||||
msg_error "Hostname $hostname already in use by another VM."
|
||||
exit 1
|
||||
exit 206
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ fi
|
||||
DISTRO=$(pct exec "$CTID" -- cat /etc/os-release | grep -w "ID" | cut -d'=' -f2 | tr -d '"')
|
||||
if [[ "$DISTRO" != "debian" && "$DISTRO" != "ubuntu" ]]; then
|
||||
msg "\e[1;31m Error: This script only supports Debian or Ubuntu LXC containers. Detected: $DISTRO. Aborting...\e[0m"
|
||||
exit 1
|
||||
exit 238
|
||||
fi
|
||||
|
||||
CTID_CONFIG_PATH=/etc/pve/lxc/${CTID}.conf
|
||||
|
||||
@@ -32,7 +32,7 @@ header_info
|
||||
|
||||
if ! command -v pveversion &>/dev/null; then
|
||||
msg_error "This script must be run on the Proxmox VE host (not inside an LXC container)"
|
||||
exit 1
|
||||
exit 232
|
||||
fi
|
||||
|
||||
while true; do
|
||||
@@ -64,7 +64,7 @@ while [[ -z "${CTID}" ]]; do
|
||||
CTID=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Containers on $NODE" --radiolist \
|
||||
"\nSelect a container to add Tailscale to:\n" \
|
||||
16 $((MSG_MAX_LENGTH + 23)) 6 \
|
||||
"${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit 1
|
||||
"${CTID_MENU[@]}" 3>&1 1>&2 2>&3) || exit 0
|
||||
done
|
||||
|
||||
CTID_CONFIG_PATH="/etc/pve/lxc/${CTID}.conf"
|
||||
|
||||
@@ -69,7 +69,7 @@ elif [[ -f "/etc/debian_version" ]]; then
|
||||
SERVICE_PATH="/etc/systemd/system/adguardhome-sync.service"
|
||||
else
|
||||
msg_error "Unsupported OS detected. Exiting."
|
||||
exit 1
|
||||
exit 238
|
||||
fi
|
||||
|
||||
# ==============================================================================
|
||||
@@ -312,7 +312,7 @@ if [[ "${type:-}" == "update" ]]; then
|
||||
update
|
||||
else
|
||||
msg_error "${APP} is not installed. Nothing to update."
|
||||
exit 1
|
||||
exit 233
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
@@ -87,11 +87,11 @@ function update() {
|
||||
function check_docker() {
|
||||
if ! command -v docker &>/dev/null; then
|
||||
msg_error "Docker is not installed. This script requires an existing Docker LXC. Exiting."
|
||||
exit 1
|
||||
exit 10
|
||||
fi
|
||||
if ! docker compose version &>/dev/null; then
|
||||
msg_error "Docker Compose plugin is not available. Please install it before running this script. Exiting."
|
||||
exit 1
|
||||
exit 10
|
||||
fi
|
||||
msg_ok "Docker $(docker --version | cut -d' ' -f3 | tr -d ',') and Docker Compose are available"
|
||||
}
|
||||
@@ -171,7 +171,7 @@ if [[ "${type:-}" == "update" ]]; then
|
||||
update
|
||||
else
|
||||
msg_error "${APP} is not installed. Nothing to update."
|
||||
exit 1
|
||||
exit 233
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
@@ -93,7 +93,7 @@ function check_or_install_docker() {
|
||||
msg_ok "Docker Compose is available"
|
||||
else
|
||||
msg_error "Docker Compose plugin is not available. Please install it."
|
||||
exit 1
|
||||
exit 10
|
||||
fi
|
||||
return
|
||||
fi
|
||||
@@ -103,7 +103,7 @@ function check_or_install_docker() {
|
||||
read -r install_docker_prompt
|
||||
if [[ ! "${install_docker_prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||
msg_error "Docker is required for ${APP}. Exiting."
|
||||
exit 1
|
||||
exit 10
|
||||
fi
|
||||
|
||||
msg_info "Installing Docker"
|
||||
@@ -165,7 +165,7 @@ if [[ "${type:-}" == "update" ]]; then
|
||||
update
|
||||
else
|
||||
msg_error "${APP} is not installed. Nothing to update."
|
||||
exit 1
|
||||
exit 233
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
@@ -49,7 +49,7 @@ elif grep -qE 'ID=debian|ID=ubuntu' /etc/os-release; then
|
||||
SERVICE_PATH="/etc/systemd/system/copyparty.service"
|
||||
else
|
||||
msg_error "Unsupported OS detected. Exiting."
|
||||
exit 1
|
||||
exit 238
|
||||
fi
|
||||
|
||||
# ==============================================================================
|
||||
@@ -318,7 +318,7 @@ if [[ "${type:-}" == "update" ]]; then
|
||||
update
|
||||
else
|
||||
msg_error "${APP} is not installed. Nothing to update."
|
||||
exit 1
|
||||
exit 233
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
@@ -51,7 +51,7 @@ EOF
|
||||
# ==============================================================================
|
||||
if ! grep -qE 'ID=debian|ID=ubuntu' /etc/os-release 2>/dev/null; then
|
||||
echo -e "${CROSS} Unsupported OS detected. This script only supports Debian and Ubuntu."
|
||||
exit 1
|
||||
exit 238
|
||||
fi
|
||||
|
||||
# ==============================================================================
|
||||
@@ -183,7 +183,7 @@ if [[ "${type:-}" == "update" ]]; then
|
||||
update
|
||||
else
|
||||
msg_error "${APP} is not installed. Nothing to update."
|
||||
exit 1
|
||||
exit 233
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
@@ -99,7 +99,7 @@ function check_or_install_docker() {
|
||||
msg_ok "Docker Compose is available"
|
||||
else
|
||||
msg_error "Docker Compose plugin is not available. Please install it."
|
||||
exit 1
|
||||
exit 10
|
||||
fi
|
||||
return
|
||||
fi
|
||||
@@ -109,7 +109,7 @@ function check_or_install_docker() {
|
||||
read -r install_docker_prompt
|
||||
if [[ ! "${install_docker_prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||
msg_error "Docker is required for ${APP}. Exiting."
|
||||
exit 1
|
||||
exit 10
|
||||
fi
|
||||
|
||||
msg_info "Installing Docker"
|
||||
@@ -160,7 +160,7 @@ if [[ "${type:-}" == "update" ]]; then
|
||||
update
|
||||
else
|
||||
msg_error "${APP} is not installed. Nothing to update."
|
||||
exit 1
|
||||
exit 233
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
@@ -92,7 +92,7 @@ function check_or_install_docker() {
|
||||
msg_ok "Docker Compose is available"
|
||||
else
|
||||
msg_error "Docker Compose plugin is not available. Please install it."
|
||||
exit 1
|
||||
exit 10
|
||||
fi
|
||||
return
|
||||
fi
|
||||
@@ -102,7 +102,7 @@ function check_or_install_docker() {
|
||||
read -r install_docker_prompt
|
||||
if [[ ! "${install_docker_prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||
msg_error "Docker is required for ${APP}. Exiting."
|
||||
exit 1
|
||||
exit 10
|
||||
fi
|
||||
|
||||
msg_info "Installing Docker"
|
||||
@@ -163,7 +163,7 @@ if [[ "${type:-}" == "update" ]]; then
|
||||
update
|
||||
else
|
||||
msg_error "${APP} is not installed. Nothing to update."
|
||||
exit 1
|
||||
exit 233
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
@@ -54,7 +54,7 @@ elif [[ -f "/etc/debian_version" ]]; then
|
||||
PKG_MANAGER="apt-get install -y"
|
||||
else
|
||||
echo -e "${CROSS} Unsupported OS detected. Exiting."
|
||||
exit 1
|
||||
exit 238
|
||||
fi
|
||||
|
||||
header_info
|
||||
|
||||
@@ -52,7 +52,7 @@ elif [[ -f "/etc/debian_version" ]]; then
|
||||
PKG_MANAGER="apt-get install -y"
|
||||
else
|
||||
echo -e "${CROSS} Unsupported OS detected. Exiting."
|
||||
exit 1
|
||||
exit 238
|
||||
fi
|
||||
|
||||
header_info
|
||||
|
||||
@@ -93,7 +93,7 @@ EOF
|
||||
update_glances_debian() {
|
||||
if [[ ! -d /opt/glances/.venv ]]; then
|
||||
msg_error "$APP is not installed"
|
||||
exit 1
|
||||
exit 233
|
||||
fi
|
||||
msg_info "Updating $APP"
|
||||
cd /opt/glances
|
||||
@@ -160,7 +160,7 @@ EOF
|
||||
update_glances_alpine() {
|
||||
if [[ ! -d /opt/glances/.venv ]]; then
|
||||
msg_error "$APP is not installed"
|
||||
exit 1
|
||||
exit 233
|
||||
fi
|
||||
msg_info "Updating $APP"
|
||||
cd /opt/glances
|
||||
|
||||
@@ -52,13 +52,13 @@ EOF
|
||||
# ==============================================================================
|
||||
if [[ -f "/etc/alpine-release" ]]; then
|
||||
msg_error "Alpine is not supported for ${APP}. Use Debian."
|
||||
exit 1
|
||||
exit 238
|
||||
elif [[ -f "/etc/debian_version" ]]; then
|
||||
OS="Debian"
|
||||
SERVICE_PATH="/etc/systemd/system/immich-proxy.service"
|
||||
else
|
||||
echo -e "${CROSS} Unsupported OS detected. Exiting."
|
||||
exit 1
|
||||
exit 238
|
||||
fi
|
||||
|
||||
# ==============================================================================
|
||||
@@ -231,7 +231,7 @@ if [[ "${type:-}" == "update" ]]; then
|
||||
update
|
||||
else
|
||||
msg_error "${APP} is not installed. Nothing to update."
|
||||
exit 1
|
||||
exit 233
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
@@ -52,13 +52,13 @@ EOF
|
||||
# ==============================================================================
|
||||
if [[ -f "/etc/alpine-release" ]]; then
|
||||
msg_error "Alpine is not supported for ${APP}. Use Debian/Ubuntu."
|
||||
exit 1
|
||||
exit 238
|
||||
elif [[ -f "/etc/debian_version" ]]; then
|
||||
OS="Debian"
|
||||
SERVICE_PATH="/etc/systemd/system/jellystat.service"
|
||||
else
|
||||
echo -e "${CROSS} Unsupported OS detected. Exiting."
|
||||
exit 1
|
||||
exit 238
|
||||
fi
|
||||
|
||||
# ==============================================================================
|
||||
@@ -326,7 +326,7 @@ if [[ "${type:-}" == "update" ]]; then
|
||||
update
|
||||
else
|
||||
msg_error "${APP} is not installed. Nothing to update."
|
||||
exit 1
|
||||
exit 233
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
@@ -37,7 +37,7 @@ function find_compose_file() {
|
||||
COMPOSE_FILE=$(find "$INSTALL_PATH" -maxdepth 1 -type f -name '*.compose.yaml' ! -name 'compose.env' | head -n1)
|
||||
if [[ -z "${COMPOSE_FILE:-}" ]]; then
|
||||
msg_error "No valid compose file found in ${INSTALL_PATH}!"
|
||||
exit 1
|
||||
exit 233
|
||||
fi
|
||||
COMPOSE_BASENAME=$(basename "$COMPOSE_FILE")
|
||||
}
|
||||
@@ -48,7 +48,7 @@ function check_legacy_db() {
|
||||
echo -e "${YW}This configuration is no longer supported since Komodo v1.18.0.${CL}"
|
||||
echo -e "${YW}Please follow the migration guide:${CL}"
|
||||
echo -e "${BGN}https://github.com/community-scripts/ProxmoxVE/discussions/5689${CL}\n"
|
||||
exit 1
|
||||
exit 238
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -79,14 +79,14 @@ function update() {
|
||||
BACKUP_FILE="${INSTALL_PATH}/${COMPOSE_BASENAME}.bak_$(date +%Y%m%d_%H%M%S)"
|
||||
cp "$COMPOSE_FILE" "$BACKUP_FILE" || {
|
||||
msg_error "Failed to create backup of ${COMPOSE_BASENAME}!"
|
||||
exit 1
|
||||
exit 235
|
||||
}
|
||||
|
||||
GITHUB_URL="https://raw.githubusercontent.com/moghtech/komodo/main/compose/${COMPOSE_BASENAME}"
|
||||
if ! curl -fsSL "$GITHUB_URL" -o "$COMPOSE_FILE"; then
|
||||
msg_error "Failed to download ${COMPOSE_BASENAME} from GitHub!"
|
||||
mv "$BACKUP_FILE" "$COMPOSE_FILE"
|
||||
exit 1
|
||||
exit 115
|
||||
fi
|
||||
|
||||
if ! grep -qxF 'COMPOSE_KOMODO_BACKUPS_PATH=/etc/komodo/backups' "$COMPOSE_ENV"; then
|
||||
@@ -129,7 +129,7 @@ function check_or_install_docker() {
|
||||
msg_ok "Docker Compose is available"
|
||||
else
|
||||
msg_error "Docker Compose plugin is not available. Please install it."
|
||||
exit 1
|
||||
exit 10
|
||||
fi
|
||||
return
|
||||
fi
|
||||
@@ -139,7 +139,7 @@ function check_or_install_docker() {
|
||||
read -r install_docker_prompt
|
||||
if [[ ! "${install_docker_prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||
msg_error "Docker is required for ${APP}. Exiting."
|
||||
exit 1
|
||||
exit 10
|
||||
fi
|
||||
|
||||
msg_info "Installing Docker"
|
||||
@@ -239,7 +239,7 @@ if [[ "${type:-}" == "update" ]]; then
|
||||
update
|
||||
else
|
||||
msg_error "${APP} is not installed. Nothing to update."
|
||||
exit 1
|
||||
exit 233
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
@@ -58,7 +58,7 @@ pve_check() {
|
||||
if ((MINOR < 0 || MINOR > 9)); then
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported: Proxmox VE version 8.0 – 8.9"
|
||||
exit 1
|
||||
exit 105
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
@@ -69,7 +69,7 @@ pve_check() {
|
||||
if ((MINOR < 0 || MINOR > 1)); then
|
||||
msg_error "This version of Proxmox VE is not yet supported."
|
||||
msg_error "Supported: Proxmox VE version 9.0–9.1.x"
|
||||
exit 1
|
||||
exit 105
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
@@ -77,19 +77,19 @@ pve_check() {
|
||||
# All other unsupported versions
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported versions: Proxmox VE 8.0 – 8.9 or 9.0–9.1.x"
|
||||
exit 1
|
||||
exit 105
|
||||
}
|
||||
|
||||
detect_codename() {
|
||||
source /etc/os-release
|
||||
if [[ "$ID" != "debian" ]]; then
|
||||
msg_error "Unsupported base OS: $ID (only Proxmox VE / Debian supported)."
|
||||
exit 1
|
||||
exit 238
|
||||
fi
|
||||
CODENAME="${VERSION_CODENAME:-}"
|
||||
if [[ -z "$CODENAME" ]]; then
|
||||
msg_error "Could not detect Debian codename."
|
||||
exit 1
|
||||
exit 71
|
||||
fi
|
||||
echo "$CODENAME"
|
||||
}
|
||||
@@ -124,7 +124,7 @@ install() {
|
||||
PKG=$(get_latest_repo_pkg "$REPO_URL")
|
||||
if [[ -z "$PKG" ]]; then
|
||||
msg_error "Could not find netdata-repo package for Debian $CODENAME"
|
||||
exit 1
|
||||
exit 237
|
||||
fi
|
||||
curl -fsSL "${REPO_URL}${PKG}" -o "$PKG"
|
||||
$STD dpkg -i "$PKG"
|
||||
|
||||
@@ -36,7 +36,7 @@ SERVICE_PATH="/etc/systemd/system/nextcloud-exporter.service"
|
||||
# ==============================================================================
|
||||
if ! grep -qE 'ID=debian|ID=ubuntu' /etc/os-release 2>/dev/null; then
|
||||
echo -e "${CROSS} Unsupported OS detected. This script only supports Debian and Ubuntu."
|
||||
exit 1
|
||||
exit 238
|
||||
fi
|
||||
|
||||
# ==============================================================================
|
||||
@@ -170,7 +170,7 @@ if [[ "${type:-}" == "update" ]]; then
|
||||
update
|
||||
else
|
||||
msg_error "Nextcloud-Exporter is not installed. Nothing to update."
|
||||
exit 1
|
||||
exit 233
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
@@ -52,7 +52,7 @@ elif [[ -f "/etc/debian_version" ]]; then
|
||||
INSTALL_DIR="$INSTALL_DIR_DEBIAN"
|
||||
else
|
||||
echo -e "${CROSS} Unsupported OS detected. Exiting."
|
||||
exit 1
|
||||
exit 238
|
||||
fi
|
||||
|
||||
header_info
|
||||
@@ -72,7 +72,7 @@ function check_internet() {
|
||||
msg_ok "Internet connectivity OK"
|
||||
else
|
||||
msg_error "Internet connectivity or GitHub unreachable (Status $HTTP_CODE). Exiting."
|
||||
exit 1
|
||||
exit 115
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ function install_php_and_modules() {
|
||||
msg_info "Installing missing PHP packages: ${MISSING_PACKAGES[*]}"
|
||||
if ! apt-get update &>/dev/null || ! apt-get install -y "${MISSING_PACKAGES[@]}" &>/dev/null; then
|
||||
msg_error "Failed to install required PHP modules. Exiting."
|
||||
exit 1
|
||||
exit 237
|
||||
fi
|
||||
msg_ok "Installed missing PHP packages"
|
||||
else
|
||||
@@ -132,7 +132,7 @@ function install_phpmyadmin() {
|
||||
msg_info "Downloading ${TARBALL_URL}"
|
||||
if ! curl -fsSL "$TARBALL_URL" -o /tmp/phpmyadmin.tar.gz; then
|
||||
msg_error "Download failed: $TARBALL_URL"
|
||||
exit 1
|
||||
exit 115
|
||||
fi
|
||||
|
||||
mkdir -p "$INSTALL_DIR"
|
||||
@@ -188,7 +188,7 @@ EOF
|
||||
msg_ok "Started PHP-FPM service: $PHP_FPM_SERVICE"
|
||||
else
|
||||
msg_error "Failed to start PHP-FPM service: $PHP_FPM_SERVICE"
|
||||
exit 1
|
||||
exit 150
|
||||
fi
|
||||
|
||||
$STD rc-service lighttpd start
|
||||
@@ -237,7 +237,7 @@ function update_phpmyadmin() {
|
||||
|
||||
if ! curl -fsSL "$TARBALL_URL" -o /tmp/phpmyadmin.tar.gz; then
|
||||
msg_error "Download failed: $TARBALL_URL"
|
||||
exit 1
|
||||
exit 115
|
||||
fi
|
||||
|
||||
BACKUP_DIR="/tmp/phpmyadmin-backup-$(date +%Y%m%d-%H%M%S)"
|
||||
@@ -280,7 +280,7 @@ if is_phpmyadmin_installed; then
|
||||
;;
|
||||
*)
|
||||
echo -e "${YW}⚠️ Invalid input. Exiting.${CL}"
|
||||
exit 1
|
||||
exit 112
|
||||
;;
|
||||
esac
|
||||
else
|
||||
|
||||
@@ -41,7 +41,7 @@ elif grep -qE 'ID=debian|ID=ubuntu' /etc/os-release; then
|
||||
SERVICE_PATH="/etc/systemd/system/pihole-exporter.service"
|
||||
else
|
||||
echo -e "${CROSS} Unsupported OS detected. Exiting."
|
||||
exit 1
|
||||
exit 238
|
||||
fi
|
||||
|
||||
# ==============================================================================
|
||||
@@ -207,7 +207,7 @@ if [[ "${type:-}" == "update" ]]; then
|
||||
update
|
||||
else
|
||||
msg_error "Pihole-Exporter is not installed. Nothing to update."
|
||||
exit 1
|
||||
exit 233
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
@@ -32,7 +32,7 @@ AUTH_TOKEN_FILE="/etc/prometheus-paperless-ngx-exporter/paperless_auth_token_fil
|
||||
# ==============================================================================
|
||||
if ! grep -qE 'ID=debian|ID=ubuntu' /etc/os-release 2>/dev/null; then
|
||||
echo -e "${CROSS} Unsupported OS detected. This script only supports Debian and Ubuntu."
|
||||
exit 1
|
||||
exit 238
|
||||
fi
|
||||
|
||||
# ==============================================================================
|
||||
@@ -144,7 +144,7 @@ if [[ "${type:-}" == "update" ]]; then
|
||||
update
|
||||
else
|
||||
msg_error "Prometheus-Paperless-NGX-Exporter is not installed. Nothing to update."
|
||||
exit 1
|
||||
exit 233
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
@@ -41,7 +41,7 @@ elif grep -qE 'ID=debian|ID=ubuntu' /etc/os-release; then
|
||||
SERVICE_PATH="/etc/systemd/system/qbittorrent-exporter.service"
|
||||
else
|
||||
echo -e "${CROSS} Unsupported OS detected. Exiting."
|
||||
exit 1
|
||||
exit 238
|
||||
fi
|
||||
|
||||
# ==============================================================================
|
||||
@@ -200,7 +200,7 @@ if [[ "${type:-}" == "update" ]]; then
|
||||
update
|
||||
else
|
||||
msg_error "qBittorrent-Exporter is not installed. Nothing to update."
|
||||
exit 1
|
||||
exit 233
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
@@ -62,7 +62,7 @@ function check_or_install_docker() {
|
||||
msg_ok "Docker Compose is available"
|
||||
else
|
||||
msg_error "Docker Compose plugin is not available. Please install it."
|
||||
exit 1
|
||||
exit 10
|
||||
fi
|
||||
return
|
||||
fi
|
||||
@@ -72,7 +72,7 @@ function check_or_install_docker() {
|
||||
read -r install_docker_prompt
|
||||
if [[ ! "${install_docker_prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||
msg_error "Docker is required for ${APP}. Exiting."
|
||||
exit 1
|
||||
exit 10
|
||||
fi
|
||||
|
||||
msg_info "Installing Docker"
|
||||
@@ -168,14 +168,14 @@ if [[ "${type:-}" == "update" ]]; then
|
||||
update
|
||||
else
|
||||
msg_error "${APP} is not installed. Nothing to update."
|
||||
exit 1
|
||||
exit 233
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ -f /etc/alpine-release ]]; then
|
||||
msg_error "${APP} does not support Alpine Linux. Please use a Debian or Ubuntu based LXC."
|
||||
exit 1
|
||||
exit 238
|
||||
fi
|
||||
|
||||
header_info
|
||||
|
||||
@@ -62,7 +62,7 @@ function msg_error() {
|
||||
}
|
||||
if [ -z "$(ls -A /var/lib/docker/volumes/hass_config/_data/backups/)" ]; then
|
||||
msg_error "No backups found! \n"
|
||||
exit 1
|
||||
exit 235
|
||||
fi
|
||||
DIR=/var/lib/docker/volumes/hass_config/_data/restore
|
||||
if [ -d "$DIR" ]; then
|
||||
|
||||
@@ -62,7 +62,7 @@ function msg_error() {
|
||||
}
|
||||
if [ -z "$(ls -A /root/.homeassistant/backups/)" ]; then
|
||||
msg_error "No backups found! \n"
|
||||
exit 1
|
||||
exit 235
|
||||
fi
|
||||
DIR=/root/.homeassistant/restore
|
||||
if [ -d "$DIR" ]; then
|
||||
|
||||
@@ -39,7 +39,7 @@ ROOT_FS=$(df -Th "/" | awk 'NR==2 {print $2}')
|
||||
if [ "$ROOT_FS" != "ext4" ]; then
|
||||
whiptail --backtitle "Proxmox VE Helper Scripts" \
|
||||
--title "Warning" \
|
||||
--yesno "Root filesystem is not ext4 ($ROOT_FS).\nContinue anyway?" 12 80 || exit 1
|
||||
--yesno "Root filesystem is not ext4 ($ROOT_FS).\nContinue anyway?" 12 80 || exit 0
|
||||
fi
|
||||
|
||||
NODE=$(hostname)
|
||||
|
||||
@@ -57,7 +57,7 @@ done
|
||||
|
||||
if [ ${#kernels_to_remove[@]} -eq 0 ]; then
|
||||
echo -e "${RD}No valid selection made. Exiting.${CL}"
|
||||
exit 1
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Confirm removal
|
||||
@@ -66,7 +66,7 @@ printf "%s\n" "${kernels_to_remove[@]}"
|
||||
read -rp "Proceed with removal? (y/n): " confirm
|
||||
if [[ "$confirm" != "y" ]]; then
|
||||
echo -e "${RD}Aborted.${CL}"
|
||||
exit 1
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Remove kernels
|
||||
|
||||
@@ -51,7 +51,7 @@ containers=$(pct list | tail -n +2 | awk '{print $0 " " $4}')
|
||||
|
||||
if [ -z "$containers" ]; then
|
||||
whiptail --title "LXC Container Delete" --msgbox "No LXC containers available!" 10 60
|
||||
exit 1
|
||||
exit 234
|
||||
fi
|
||||
|
||||
menu_items=("ALL" "Delete ALL containers" "OFF") # Add as first option
|
||||
@@ -72,7 +72,7 @@ CHOICES=$(whiptail --title "LXC Container Delete" \
|
||||
if [ -z "$CHOICES" ]; then
|
||||
whiptail --title "LXC Container Delete" \
|
||||
--msgbox "No containers selected!" 10 60
|
||||
exit 1
|
||||
exit 0
|
||||
fi
|
||||
|
||||
read -p "Delete containers manually or automatically? (Default: manual) m/a: " DELETE_MODE
|
||||
|
||||
@@ -47,7 +47,7 @@ function msg_warn() { echo -e "${WARN} ${YWB}${1}"; }
|
||||
# Check for root privileges
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
msg_error "Error: This script must be run as root."
|
||||
exit 1
|
||||
exit 104
|
||||
fi
|
||||
|
||||
if ! command -v ethtool >/dev/null 2>&1; then
|
||||
@@ -55,7 +55,7 @@ if ! command -v ethtool >/dev/null 2>&1; then
|
||||
apt-get update &>/dev/null
|
||||
apt-get install -y ethtool &>/dev/null || {
|
||||
msg_error "Failed to install ethtool. Exiting."
|
||||
exit 1
|
||||
exit 237
|
||||
}
|
||||
msg_ok "ethtool installed successfully"
|
||||
fi
|
||||
@@ -86,7 +86,7 @@ done
|
||||
if [ ${#INTERFACES[@]} -eq 0 ]; then
|
||||
whiptail --title "Error" --msgbox "No Intel e1000e or e1000 network interfaces found!" 10 60
|
||||
msg_error "No Intel e1000e or e1000 network interfaces found! Exiting."
|
||||
exit 1
|
||||
exit 236
|
||||
fi
|
||||
|
||||
msg_ok "Found ${BL}$COUNT${GN} Intel e1000e/e1000 interfaces"
|
||||
|
||||
@@ -41,7 +41,7 @@ header_info
|
||||
virt=$(systemd-detect-virt)
|
||||
if [ "$virt" != "none" ]; then
|
||||
msg_error "This script must be run on bare metal. Detected virtual environment: $virt"
|
||||
exit 1
|
||||
exit 232
|
||||
fi
|
||||
|
||||
# Attempt to obtain the current loaded microcode revision
|
||||
|
||||
@@ -83,7 +83,7 @@ main() {
|
||||
|
||||
if command -v pveversion >/dev/null 2>&1; then
|
||||
echo -e "\n🛑 PVE Detected, Wrong Script!\n"
|
||||
exit 1
|
||||
exit 232
|
||||
fi
|
||||
|
||||
local CODENAME
|
||||
@@ -95,7 +95,7 @@ main() {
|
||||
*)
|
||||
msg_error "Unsupported Debian codename: $CODENAME"
|
||||
echo -e "Supported: bookworm (PBS 3.x) and trixie (PBS 4.x)"
|
||||
exit 1
|
||||
exit 105
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "post-pmg-inst
|
||||
|
||||
if ! grep -q "Proxmox Mail Gateway" /etc/issue 2>/dev/null; then
|
||||
msg_error "This script is only intended for Proxmox Mail Gateway"
|
||||
exit 1
|
||||
exit 232
|
||||
fi
|
||||
|
||||
repo_state() {
|
||||
|
||||
@@ -88,19 +88,19 @@ main() {
|
||||
if [[ "$PVE_MAJOR" == "8" ]]; then
|
||||
if ((PVE_MINOR < 0 || PVE_MINOR > 9)); then
|
||||
msg_error "Unsupported Proxmox 8 version"
|
||||
exit 1
|
||||
exit 105
|
||||
fi
|
||||
start_routines_8
|
||||
elif [[ "$PVE_MAJOR" == "9" ]]; then
|
||||
if ((PVE_MINOR < 0 || PVE_MINOR > 1)); then
|
||||
msg_error "Only Proxmox 9.0-9.1.x is currently supported"
|
||||
exit 1
|
||||
exit 105
|
||||
fi
|
||||
start_routines_9
|
||||
else
|
||||
msg_error "Unsupported Proxmox VE major version: $PVE_MAJOR"
|
||||
echo -e "Supported: 8.0–8.9.x and 9.0–9.1.x"
|
||||
exit 1
|
||||
exit 105
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ header_info "$APP"
|
||||
check_root() {
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
msg_error "Script must be run as root"
|
||||
exit 1
|
||||
exit 104
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ select_container() {
|
||||
|
||||
if [[ ${#lxc_list[@]} -eq 0 ]]; then
|
||||
msg_error "No containers found"
|
||||
exit 1
|
||||
exit 234
|
||||
fi
|
||||
|
||||
PS3="Enter number of container to convert: "
|
||||
@@ -101,7 +101,7 @@ backup_container() {
|
||||
if [ -z "$BACKUP_PATH" ] || ! grep -q "Backup job finished successfully" "$vzdump_output"; then
|
||||
rm "$vzdump_output"
|
||||
msg_error "Backup failed"
|
||||
exit 1
|
||||
exit 235
|
||||
fi
|
||||
rm "$vzdump_output"
|
||||
msg_ok "Backup complete: $BACKUP_PATH"
|
||||
@@ -126,7 +126,7 @@ perform_conversion() {
|
||||
msg_ok "Conversion successful"
|
||||
else
|
||||
msg_error "Conversion failed"
|
||||
exit 1
|
||||
exit 235
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
@@ -140,7 +140,7 @@ function backup_container() {
|
||||
msg_ok "Backup created"
|
||||
else
|
||||
msg_error "Backup failed for container $1"
|
||||
exit 1
|
||||
exit 235
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -183,7 +183,7 @@ containers=$(pct list | tail -n +2 | awk '{print $0 " " $4}')
|
||||
|
||||
if [ -z "$containers" ]; then
|
||||
whiptail --title "LXC Container Update" --msgbox "No LXC containers available!" 10 60
|
||||
exit 1
|
||||
exit 234
|
||||
fi
|
||||
|
||||
menu_items=()
|
||||
@@ -242,7 +242,7 @@ if [[ -n "$var_container" ]]; then
|
||||
|
||||
if [[ -z "$CHOICE" ]]; then
|
||||
msg_error "No containers matched the selection criteria: $var_container ${var_tags:-community-script|proxmox-helper-scripts}"
|
||||
exit 1
|
||||
exit 234
|
||||
fi
|
||||
msg_ok "Selected containers: $CHOICE"
|
||||
else
|
||||
@@ -253,7 +253,7 @@ else
|
||||
if [ -z "$CHOICE" ]; then
|
||||
whiptail --title "LXC Container Update" \
|
||||
--msgbox "No containers selected!" 10 60
|
||||
exit 1
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -284,7 +284,7 @@ if [ "$BACKUP_CHOICE" == "yes" ]; then
|
||||
|
||||
if [ -z "$STORAGES" ]; then
|
||||
msg_error "No storage with 'backup' support found!"
|
||||
exit 1
|
||||
exit 119
|
||||
fi
|
||||
|
||||
# Determine storage based on var_backup_storage
|
||||
@@ -296,7 +296,7 @@ if [ "$BACKUP_CHOICE" == "yes" ]; then
|
||||
else
|
||||
msg_error "Specified backup storage '$var_backup_storage' not found or doesn't support backups!"
|
||||
msg_info "Available storages: $(echo $STORAGES | tr '\n' ' ')"
|
||||
exit 1
|
||||
exit 119
|
||||
fi
|
||||
else
|
||||
MENU_ITEMS=()
|
||||
@@ -308,7 +308,7 @@ if [ "$BACKUP_CHOICE" == "yes" ]; then
|
||||
|
||||
if [ -z "$STORAGE_CHOICE" ]; then
|
||||
msg_error "No storage selected!"
|
||||
exit 1
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
@@ -436,11 +436,11 @@ for container in $CHOICE; do
|
||||
msg_ok "Restored LXC from backup"
|
||||
else
|
||||
msg_error "Restored LXC from backup failed"
|
||||
exit 1
|
||||
exit 235
|
||||
fi
|
||||
else
|
||||
msg_error "Update failed for container $container. Exiting"
|
||||
exit 1
|
||||
exit "$exit_code"
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
@@ -158,7 +158,7 @@ pve_check() {
|
||||
if ((MINOR < 0 || MINOR > 9)); then
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported: Proxmox VE version 8.0 – 8.9"
|
||||
exit 1
|
||||
exit 105
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
@@ -169,7 +169,7 @@ pve_check() {
|
||||
if ((MINOR < 0 || MINOR > 1)); then
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported: Proxmox VE version 9.0 – 9.1"
|
||||
exit 1
|
||||
exit 105
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
@@ -177,7 +177,7 @@ pve_check() {
|
||||
# All other unsupported versions
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported versions: Proxmox VE 8.0 – 8.x or 9.0 – 9.1"
|
||||
exit 1
|
||||
exit 105
|
||||
}
|
||||
|
||||
function arch_check() {
|
||||
@@ -513,7 +513,7 @@ DISK_REF_IMPORTED="$(printf '%s\n' "$IMPORT_OUT" | sed -n "s/.*successfully impo
|
||||
[[ -z "$DISK_REF_IMPORTED" ]] && {
|
||||
msg_error "Unable to determine imported disk reference."
|
||||
echo "$IMPORT_OUT"
|
||||
exit 1
|
||||
exit 226
|
||||
}
|
||||
msg_ok "Imported disk (${CL}${BL}${DISK_REF_IMPORTED}${CL})"
|
||||
|
||||
|
||||
@@ -158,7 +158,7 @@ pve_check() {
|
||||
if ((MINOR < 0 || MINOR > 9)); then
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported: Proxmox VE version 8.0 – 8.9"
|
||||
exit 1
|
||||
exit 105
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
@@ -169,7 +169,7 @@ pve_check() {
|
||||
if ((MINOR < 0 || MINOR > 1)); then
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported: Proxmox VE version 9.0 – 9.1"
|
||||
exit 1
|
||||
exit 105
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
@@ -177,7 +177,7 @@ pve_check() {
|
||||
# All other unsupported versions
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported versions: Proxmox VE 8.0 – 8.x or 9.0 – 9.1"
|
||||
exit 1
|
||||
exit 105
|
||||
}
|
||||
|
||||
function arch_check() {
|
||||
|
||||
@@ -158,7 +158,7 @@ pve_check() {
|
||||
if ((MINOR < 0 || MINOR > 9)); then
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported: Proxmox VE version 8.0 – 8.9"
|
||||
exit 1
|
||||
exit 105
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
@@ -169,7 +169,7 @@ pve_check() {
|
||||
if ((MINOR < 0 || MINOR > 1)); then
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported: Proxmox VE version 9.0 – 9.1"
|
||||
exit 1
|
||||
exit 105
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
@@ -177,7 +177,7 @@ pve_check() {
|
||||
# All other unsupported versions
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported versions: Proxmox VE 8.0 – 8.x or 9.0 – 9.1"
|
||||
exit 1
|
||||
exit 105
|
||||
}
|
||||
|
||||
function arch_check() {
|
||||
|
||||
@@ -638,7 +638,7 @@ DISK_REF_IMPORTED="$(printf '%s\n' "$IMPORT_OUT" | sed -n "s/.*successfully impo
|
||||
[[ -z "$DISK_REF_IMPORTED" ]] && {
|
||||
msg_error "Unable to determine imported disk reference."
|
||||
echo "$IMPORT_OUT"
|
||||
exit 1
|
||||
exit 226
|
||||
}
|
||||
|
||||
msg_ok "Imported disk (${CL}${BL}${DISK_REF_IMPORTED}${CL})"
|
||||
|
||||
@@ -163,7 +163,7 @@ pve_check() {
|
||||
if ((MINOR < 0 || MINOR > 9)); then
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported: Proxmox VE version 8.0 – 8.9"
|
||||
exit 1
|
||||
exit 105
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
@@ -174,7 +174,7 @@ pve_check() {
|
||||
if ((MINOR < 0 || MINOR > 1)); then
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported: Proxmox VE version 9.0 – 9.1"
|
||||
exit 1
|
||||
exit 105
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
@@ -182,7 +182,7 @@ pve_check() {
|
||||
# All other unsupported versions
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported versions: Proxmox VE 8.0 – 8.x or 9.0 – 9.1"
|
||||
exit 1
|
||||
exit 105
|
||||
}
|
||||
|
||||
function arch_check() {
|
||||
@@ -221,7 +221,7 @@ function ensure_pv() {
|
||||
if ! apt-get update -qq &>/dev/null || ! apt-get install -y pv &>/dev/null; then
|
||||
msg_error "Failed to install pv automatically."
|
||||
echo -e "\nPlease run manually on the Proxmox host:\n apt install pv\n"
|
||||
exit 1
|
||||
exit 237
|
||||
fi
|
||||
msg_ok "Installed pv"
|
||||
fi
|
||||
@@ -249,14 +249,14 @@ function download_and_validate_xz() {
|
||||
if ! curl -fSL -o "$file" "$url"; then
|
||||
msg_error "Download failed: $url"
|
||||
rm -f "$file"
|
||||
exit 1
|
||||
exit 115
|
||||
fi
|
||||
|
||||
# Validate again
|
||||
if ! xz -t "$file" &>/dev/null; then
|
||||
msg_error "Downloaded file $(basename "$file") is corrupted. Please try again later."
|
||||
rm -f "$file"
|
||||
exit 1
|
||||
exit 115
|
||||
fi
|
||||
msg_ok "Downloaded and validated $(basename "$file")"
|
||||
}
|
||||
@@ -272,7 +272,7 @@ function extract_xz_with_pv() {
|
||||
if ! xz -dc "$file" | pv -N "Extracting" >"$target"; then
|
||||
msg_error "Failed to extract $file"
|
||||
rm -f "$target"
|
||||
exit 1
|
||||
exit 115
|
||||
fi
|
||||
msg_ok "Decompressed to $target"
|
||||
}
|
||||
@@ -592,7 +592,7 @@ DISK_REF="$(printf '%s\n' "$IMPORT_OUT" | sed -n "s/.*successfully imported disk
|
||||
[[ -z "$DISK_REF" ]] && {
|
||||
msg_error "Unable to determine imported disk reference."
|
||||
echo "$IMPORT_OUT"
|
||||
exit 1
|
||||
exit 226
|
||||
}
|
||||
msg_ok "Imported disk (${CL}${BL}${DISK_REF}${CL})"
|
||||
|
||||
|
||||
@@ -159,7 +159,7 @@ pve_check() {
|
||||
if ((MINOR < 0 || MINOR > 9)); then
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported: Proxmox VE version 8.0 – 8.9"
|
||||
exit 1
|
||||
exit 105
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
@@ -170,7 +170,7 @@ pve_check() {
|
||||
if ((MINOR < 0 || MINOR > 1)); then
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported: Proxmox VE version 9.0 – 9.1"
|
||||
exit 1
|
||||
exit 105
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
@@ -178,7 +178,7 @@ pve_check() {
|
||||
# All other unsupported versions
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported versions: Proxmox VE 8.0 – 8.x or 9.0 – 9.1"
|
||||
exit 1
|
||||
exit 105
|
||||
}
|
||||
|
||||
function arch_check() {
|
||||
|
||||
@@ -158,7 +158,7 @@ pve_check() {
|
||||
if ((MINOR < 0 || MINOR > 9)); then
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported: Proxmox VE version 8.0 – 8.9"
|
||||
exit 1
|
||||
exit 105
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
@@ -169,7 +169,7 @@ pve_check() {
|
||||
if ((MINOR < 0 || MINOR > 1)); then
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported: Proxmox VE version 9.0 – 9.1"
|
||||
exit 1
|
||||
exit 105
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
@@ -177,7 +177,7 @@ pve_check() {
|
||||
# All other unsupported versions
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported versions: Proxmox VE 8.0 – 8.x or 9.0 – 9.1"
|
||||
exit 1
|
||||
exit 105
|
||||
}
|
||||
|
||||
function arch_check() {
|
||||
|
||||
@@ -226,7 +226,7 @@ pve_check() {
|
||||
if ((MINOR < 0 || MINOR > 9)); then
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported: Proxmox VE version 8.0 – 8.9"
|
||||
exit 1
|
||||
exit 105
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
@@ -237,7 +237,7 @@ pve_check() {
|
||||
if ((MINOR < 0 || MINOR > 1)); then
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported: Proxmox VE version 9.0 – 9.1"
|
||||
exit 1
|
||||
exit 105
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
@@ -245,7 +245,7 @@ pve_check() {
|
||||
# All other unsupported versions
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported versions: Proxmox VE 8.0 – 8.x or 9.0 – 9.1"
|
||||
exit 1
|
||||
exit 105
|
||||
}
|
||||
|
||||
function arch_check() {
|
||||
@@ -556,7 +556,7 @@ fi
|
||||
if [[ -z "$DISK_REF" ]]; then
|
||||
msg_error "Unable to determine imported disk reference."
|
||||
echo "$IMPORT_OUT"
|
||||
exit 1
|
||||
exit 226
|
||||
fi
|
||||
|
||||
qm set $VMID \
|
||||
@@ -635,7 +635,7 @@ if qm status "$VMID" | grep -q "running"; then
|
||||
msg_ok "Network interfaces configured in OpenWrt"
|
||||
else
|
||||
msg_error "VM is not running"
|
||||
exit 1
|
||||
exit 226
|
||||
fi
|
||||
|
||||
msg_info "Waiting for OpenWrt to shut down..."
|
||||
|
||||
@@ -210,7 +210,7 @@ pve_check() {
|
||||
if ((MINOR < 0 || MINOR > 9)); then
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported: Proxmox VE version 8.0 – 8.9"
|
||||
exit 1
|
||||
exit 105
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
@@ -221,7 +221,7 @@ pve_check() {
|
||||
if ((MINOR < 0 || MINOR > 1)); then
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported: Proxmox VE version 9.0 – 9.1"
|
||||
exit 1
|
||||
exit 105
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
@@ -229,7 +229,7 @@ pve_check() {
|
||||
# All other unsupported versions
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported versions: Proxmox VE 8.0 – 8.x or 9.0 – 9.1"
|
||||
exit 1
|
||||
exit 105
|
||||
}
|
||||
|
||||
function arch_check() {
|
||||
@@ -616,7 +616,7 @@ for ver in $RELEASE_LIST; do
|
||||
done
|
||||
if [ -z "$URL" ]; then
|
||||
msg_error "Could not find generic FreeBSD amd64 qcow2 image (non-UFS/ZFS)."
|
||||
exit 1
|
||||
exit 115
|
||||
fi
|
||||
msg_ok "Download URL: ${CL}${BL}${URL}${CL}"
|
||||
|
||||
@@ -626,7 +626,7 @@ if ! check_disk_space "$TEMP_DIR" 20; then
|
||||
msg_error "Insufficient disk space in temporary directory ($TEMP_DIR)."
|
||||
msg_error "Available: ${AVAILABLE_GB}, Required: ~20GB for FreeBSD image decompression."
|
||||
msg_error "Please free up space or ensure /tmp has sufficient storage."
|
||||
exit 1
|
||||
exit 214
|
||||
fi
|
||||
|
||||
msg_info "Downloading FreeBSD Image"
|
||||
@@ -639,7 +639,7 @@ if ! check_disk_space "$TEMP_DIR" 15; then
|
||||
AVAILABLE_GB=$(df -h "$TEMP_DIR" | awk 'NR==2 {print $4}')
|
||||
msg_error "Insufficient disk space for decompression."
|
||||
msg_error "Available: ${AVAILABLE_GB}, Required: ~15GB for decompressed image."
|
||||
exit 1
|
||||
exit 214
|
||||
fi
|
||||
|
||||
msg_info "Decompressing FreeBSD Image (this may take a few minutes)"
|
||||
@@ -648,7 +648,7 @@ if ! unxz -cv $(basename $URL) >${FILE}; then
|
||||
msg_error "Failed to decompress FreeBSD image."
|
||||
msg_error "This is usually caused by insufficient disk space."
|
||||
df -h "$TEMP_DIR"
|
||||
exit 1
|
||||
exit 115
|
||||
fi
|
||||
|
||||
# Remove the compressed file to save space
|
||||
|
||||
@@ -159,7 +159,7 @@ pve_check() {
|
||||
if ((MINOR < 0 || MINOR > 9)); then
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported: Proxmox VE version 8.0 – 8.9"
|
||||
exit 1
|
||||
exit 105
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
@@ -170,7 +170,7 @@ pve_check() {
|
||||
if ((MINOR < 0 || MINOR > 1)); then
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported: Proxmox VE version 9.0 – 9.1"
|
||||
exit 1
|
||||
exit 105
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
@@ -178,7 +178,7 @@ pve_check() {
|
||||
# All other unsupported versions
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported versions: Proxmox VE 8.0 – 8.x or 9.0 – 9.1"
|
||||
exit 1
|
||||
exit 105
|
||||
}
|
||||
|
||||
function arch_check() {
|
||||
|
||||
@@ -167,7 +167,7 @@ pve_check() {
|
||||
if ((MINOR < 0 || MINOR > 9)); then
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported: Proxmox VE version 8.0 – 8.9"
|
||||
exit 1
|
||||
exit 105
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
@@ -178,7 +178,7 @@ pve_check() {
|
||||
if ((MINOR < 0 || MINOR > 1)); then
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported: Proxmox VE version 9.0 – 9.1"
|
||||
exit 1
|
||||
exit 105
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
@@ -186,7 +186,7 @@ pve_check() {
|
||||
# All other unsupported versions
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported versions: Proxmox VE 8.0 – 8.x or 9.0 – 9.1"
|
||||
exit 1
|
||||
exit 105
|
||||
}
|
||||
|
||||
function arch_check() {
|
||||
|
||||
@@ -192,7 +192,7 @@ function pve_check() {
|
||||
if ((MINOR < 0 || MINOR > 9)); then
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported: Proxmox VE version 8.0 – 8.9"
|
||||
exit 1
|
||||
exit 105
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
@@ -202,14 +202,14 @@ function pve_check() {
|
||||
if ((MINOR < 0 || MINOR > 1)); then
|
||||
msg_error "This version of Proxmox VE is not yet supported."
|
||||
msg_error "Supported: Proxmox VE version 9.0 – 9.1"
|
||||
exit 1
|
||||
exit 105
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported versions: Proxmox VE 8.0 – 8.x or 9.0 – 9.1"
|
||||
exit 1
|
||||
exit 105
|
||||
}
|
||||
|
||||
function arch_check() {
|
||||
@@ -305,7 +305,7 @@ function advanced_settings() {
|
||||
|
||||
if [ $ISO_COUNT -eq 0 ]; then
|
||||
echo "No ISOs found."
|
||||
exit 1
|
||||
exit 115
|
||||
fi
|
||||
|
||||
# Identify the index of the last stable release
|
||||
@@ -529,7 +529,7 @@ if [ -z "${SELECTED_ISO:-}" ]; then
|
||||
|
||||
if [ -z "$SELECTED_ISO" ]; then
|
||||
msg_error "Could not find a stable ISO for fallback."
|
||||
exit 1
|
||||
exit 115
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
@@ -155,7 +155,7 @@ pve_check() {
|
||||
if ((MINOR < 0 || MINOR > 9)); then
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported: Proxmox VE version 8.0 – 8.9"
|
||||
exit 1
|
||||
exit 105
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
@@ -166,7 +166,7 @@ pve_check() {
|
||||
if ((MINOR < 0 || MINOR > 1)); then
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported: Proxmox VE version 9.0 – 9.1"
|
||||
exit 1
|
||||
exit 105
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
@@ -174,7 +174,7 @@ pve_check() {
|
||||
# All other unsupported versions
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported versions: Proxmox VE 8.0 – 8.x or 9.0 – 9.1"
|
||||
exit 1
|
||||
exit 105
|
||||
}
|
||||
|
||||
function arch_check() {
|
||||
|
||||
@@ -158,7 +158,7 @@ pve_check() {
|
||||
if ((MINOR < 0 || MINOR > 9)); then
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported: Proxmox VE version 8.0 – 8.9"
|
||||
exit 1
|
||||
exit 105
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
@@ -169,7 +169,7 @@ pve_check() {
|
||||
if ((MINOR < 0 || MINOR > 1)); then
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported: Proxmox VE version 9.0 – 9.1"
|
||||
exit 1
|
||||
exit 105
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
@@ -177,7 +177,7 @@ pve_check() {
|
||||
# All other unsupported versions
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported versions: Proxmox VE 8.0 – 8.x or 9.0 – 9.1"
|
||||
exit 1
|
||||
exit 105
|
||||
}
|
||||
|
||||
function arch_check() {
|
||||
|
||||
@@ -157,7 +157,7 @@ pve_check() {
|
||||
if ((MINOR < 0 || MINOR > 9)); then
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported: Proxmox VE version 8.0 – 8.9"
|
||||
exit 1
|
||||
exit 105
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
@@ -168,7 +168,7 @@ pve_check() {
|
||||
if ((MINOR < 0 || MINOR > 1)); then
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported: Proxmox VE version 9.0 – 9.1"
|
||||
exit 1
|
||||
exit 105
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
@@ -176,7 +176,7 @@ pve_check() {
|
||||
# All other unsupported versions
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported versions: Proxmox VE 8.0 – 8.x or 9.0 – 9.1"
|
||||
exit 1
|
||||
exit 105
|
||||
}
|
||||
|
||||
function arch_check() {
|
||||
|
||||
@@ -157,7 +157,7 @@ pve_check() {
|
||||
if ((MINOR < 0 || MINOR > 9)); then
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported: Proxmox VE version 8.0 – 8.9"
|
||||
exit 1
|
||||
exit 105
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
@@ -168,7 +168,7 @@ pve_check() {
|
||||
if ((MINOR < 0 || MINOR > 1)); then
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported: Proxmox VE version 9.0 – 9.1"
|
||||
exit 1
|
||||
exit 105
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
@@ -176,7 +176,7 @@ pve_check() {
|
||||
# All other unsupported versions
|
||||
msg_error "This version of Proxmox VE is not supported."
|
||||
msg_error "Supported versions: Proxmox VE 8.0 – 8.x or 9.0 – 9.1"
|
||||
exit 1
|
||||
exit 105
|
||||
}
|
||||
|
||||
function arch_check() {
|
||||
@@ -215,7 +215,7 @@ function ensure_pv() {
|
||||
if ! apt-get update -qq &>/dev/null || ! apt-get install -y pv &>/dev/null; then
|
||||
msg_error "Failed to install pv automatically."
|
||||
echo -e "\nPlease run manually on the Proxmox host:\n apt install pv\n"
|
||||
exit 1
|
||||
exit 237
|
||||
fi
|
||||
msg_ok "Installed pv"
|
||||
fi
|
||||
@@ -243,14 +243,14 @@ function download_and_validate_xz() {
|
||||
if ! curl -fSL -o "$file" "$url"; then
|
||||
msg_error "Download failed: $url"
|
||||
rm -f "$file"
|
||||
exit 1
|
||||
exit 115
|
||||
fi
|
||||
|
||||
# Validate again
|
||||
if ! xz -t "$file" &>/dev/null; then
|
||||
msg_error "Downloaded file $(basename "$file") is corrupted. Please try again later."
|
||||
rm -f "$file"
|
||||
exit 1
|
||||
exit 115
|
||||
fi
|
||||
msg_ok "Downloaded and validated $(basename "$file")"
|
||||
}
|
||||
@@ -266,7 +266,7 @@ function extract_xz_with_pv() {
|
||||
if ! xz -dc "$file" | pv -N "Extracting" >"$target"; then
|
||||
msg_error "Failed to extract $file"
|
||||
rm -f "$target"
|
||||
exit 1
|
||||
exit 115
|
||||
fi
|
||||
msg_ok "Decompressed to $target"
|
||||
}
|
||||
@@ -514,7 +514,7 @@ done < <(pvesm status -content images | awk 'NR>1 {printf "%s %s %s\n", $1, $2,
|
||||
|
||||
if [ ${#STORAGE_MENU[@]} -eq 0 ]; then
|
||||
msg_error "Unable to detect a valid storage location."
|
||||
exit 1
|
||||
exit 119
|
||||
elif [ $((${#STORAGE_MENU[@]} / 3)) -eq 1 ]; then
|
||||
STORAGE=${STORAGE_MENU[0]}
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user