Compare commits

...

14 Commits

Author SHA1 Message Date
copilot-swe-agent[bot]
f3f36f2253 Switch disk allocations: OpenWebUI to 50GB, Ollama to 40GB
Co-authored-by: MickLesk <47820557+MickLesk@users.noreply.github.com>
2026-02-14 20:26:57 +00:00
copilot-swe-agent[bot]
2f13b4dbc8 Increase disk space for OpenWebUI (25->40GB) and Ollama (35->50GB)
Co-authored-by: MickLesk <47820557+MickLesk@users.noreply.github.com>
2026-02-14 20:23:50 +00:00
copilot-swe-agent[bot]
8ead654ebb Initial plan 2026-02-14 20:22:06 +00:00
community-scripts-pr-app[bot]
da915b87f6 chore: update github-versions.json (#11917)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-14 18:07:36 +00:00
community-scripts-pr-app[bot]
b46dddbd7d Update CHANGELOG.md (#11916)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-14 15:43:15 +00:00
community-scripts-pr-app[bot]
b3e3ed5fb3 Update CHANGELOG.md (#11915)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-14 15:42:52 +00:00
failure101
7b767ff58b Feature/lxc update patchmon aware (#11905)
* update-lxcs.sh ist now patchmon-agent aware: if patchmon agent is detected inside LXC,
then it is called after updating the container

it is called with the argument "report" to relay the current update situation back to the patchmon system

* Added status message if patchmon agent is found

* whitespace added

* Update tools/pve/update-lxcs.sh

Co-authored-by: Tobias <96661824+CrazyWolf13@users.noreply.github.com>

* Update tools/pve/update-lxcs.sh

Co-authored-by: Tobias <96661824+CrazyWolf13@users.noreply.github.com>

* removed os differentiation, removed use of explicit shell during call of patchmon-agent

* removed os differentiation
removed use of explicit shell during call of patchmon-agent
fixed whitespace

* Delete .git-setup-info

not needed

---------

Co-authored-by: Tobias <96661824+CrazyWolf13@users.noreply.github.com>
2026-02-14 16:42:29 +01:00
community-scripts-pr-app[bot]
79baf4360e Update CHANGELOG.md (#11914)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-14 15:37:34 +00:00
Tobias
773f3f67b8 core: overwriteable app version (#11753)
* refactor: homepage

* add: overwriteable app version var

* fix wrong commit

* fix: wrong commit

* fix: wrong commit

* Remove APPLICATION_VERSION export

* Change APPLICATION_VERSION to var_appversion
2026-02-14 16:37:13 +01:00
CanbiZ (MickLesk)
9a95d81f17 Strip ANSI and control chars in json_escape & logs
Enhance json_escape to remove ANSI escape sequences (color codes) and other non-printable control characters before escaping backslashes, quotes, newlines, tabs and carriage returns. Also update get_error_text to strip ANSI sequences from tailed logfile output. These changes ensure safe JSON embedding of strings and prevent control characters / terminal color codes from leaking into logs or JSON payloads.
2026-02-14 16:13:05 +01:00
community-scripts-pr-app[bot]
ed9a6d9d4b Update CHANGELOG.md (#11911)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-14 14:29:19 +00:00
community-scripts-pr-app[bot]
c6005af29d Update CHANGELOG.md (#11910)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-14 14:28:56 +00:00
CanbiZ (MickLesk)
911f533e6a fix(cluster): validate container IDs cluster-wide across all nodes (#11906)
- Query /cluster/resources via pvesh to check all VMs/CTs on ALL nodes
- Check /etc/pve/nodes/*/qemu-server and /etc/pve/nodes/*/lxc dirs
- Handles pmxcfs sync delays that caused sporadic ID conflicts
- Remove duplicate validate_container_id/get_valid_container_id definitions
- Add max_attempts safeguard to prevent infinite loops
2026-02-14 15:28:47 +01:00
CanbiZ (MickLesk)
cecadf5681 core: improve error reporting with structured error strings and better categorization + output formatting (#11907)
* fix(telemetry): improve error reporting with structured error strings and better categorization

- Add build_error_string() that creates structured format:
  'exit_code=N | description\n---\n<last 20 log lines>'
- Fix categorize_error() to map ALL known exit codes:
  - Added: shell(1,2), proxmox(200-231), service(150-154),
    database(170-193), runtime(243-249), signal(139,141,143)
  - Split timeout from network (28 was in both)
  - Added DPKG(255) to dependency category
- Update all API functions to use build_error_string():
  post_update_to_api, post_update_to_api_extended,
  post_tool_to_api, post_addon_to_api
- Add ensure_log_on_host() calls to on_exit, on_interrupt,
  on_terminate handlers to prevent race condition where
  telemetry reports before container log is pulled to host

* fix(ui): improve error output formatting and remove redundant log paths

- error_handler: Use msg_info/msg_ok/msg_warn for container cleanup
  instead of raw echo with manual ANSI codes
- error_handler: Add  icon before 'Remove broken container?' prompt
- error_handler: Indent log output with TAB for visual consistency
- build.func: Use msg_custom for installation log path display
- build.func: Use msg_info → msg_ok for container removal flow
- build.func: Use msg_warn for 'kept for debugging' message
- core.func/vm-core.func: Remove redundant container-internal log
  path display (📋 View full log) since combined log on host is
  the canonical location shown after failure
2026-02-14 15:28:30 +01:00
13 changed files with 219 additions and 137 deletions

View File

@@ -403,12 +403,24 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
## 2026-02-14
### 🚀 Updated Scripts
- #### ✨ New Features
- core: overwriteable app version [@CrazyWolf13](https://github.com/CrazyWolf13) ([#11753](https://github.com/community-scripts/ProxmoxVE/pull/11753))
### 💾 Core
- #### ✨ New Features
- core: validate container IDs cluster-wide across all nodes [@MickLesk](https://github.com/MickLesk) ([#11906](https://github.com/community-scripts/ProxmoxVE/pull/11906))
- core: improve error reporting with structured error strings and better categorization + output formatting [@MickLesk](https://github.com/MickLesk) ([#11907](https://github.com/community-scripts/ProxmoxVE/pull/11907))
- core: unified logging system with combined logs [@MickLesk](https://github.com/MickLesk) ([#11761](https://github.com/community-scripts/ProxmoxVE/pull/11761))
### 🧰 Tools
- lxc-updater: add patchmon aware [@failure101](https://github.com/failure101) ([#11905](https://github.com/community-scripts/ProxmoxVE/pull/11905))
### ❔ Uncategorized
- Disable UniFi script - APT packages no longer available [@Copilot](https://github.com/Copilot) ([#11898](https://github.com/community-scripts/ProxmoxVE/pull/11898))

View File

@@ -9,7 +9,7 @@ APP="Ollama"
var_tags="${var_tags:-ai}"
var_cpu="${var_cpu:-4}"
var_ram="${var_ram:-4096}"
var_disk="${var_disk:-35}"
var_disk="${var_disk:-40}"
var_os="${var_os:-ubuntu}"
var_version="${var_version:-24.04}"
var_gpu="${var_gpu:-yes}"

View File

@@ -9,7 +9,7 @@ APP="Open WebUI"
var_tags="${var_tags:-ai;interface}"
var_cpu="${var_cpu:-4}"
var_ram="${var_ram:-8192}"
var_disk="${var_disk:-25}"
var_disk="${var_disk:-50}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"

View File

@@ -1,5 +1,5 @@
{
"generated": "2026-02-14T12:08:41Z",
"generated": "2026-02-14T18:07:29Z",
"versions": [
{
"slug": "2fauth",
@@ -116,9 +116,9 @@
{
"slug": "bentopdf",
"repo": "alam00000/bentopdf",
"version": "v2.2.0",
"version": "v2.2.1",
"pinned": false,
"date": "2026-02-09T07:07:40Z"
"date": "2026-02-14T16:33:47Z"
},
{
"slug": "beszel",
@@ -354,9 +354,9 @@
{
"slug": "firefly",
"repo": "firefly-iii/firefly-iii",
"version": "v6.4.19",
"version": "v6.4.20",
"pinned": false,
"date": "2026-02-14T11:55:40Z"
"date": "2026-02-14T12:39:02Z"
},
{
"slug": "fladder",
@@ -578,9 +578,9 @@
{
"slug": "jackett",
"repo": "Jackett/Jackett",
"version": "v0.24.1109",
"version": "v0.24.1113",
"pinned": false,
"date": "2026-02-14T05:54:26Z"
"date": "2026-02-14T17:46:58Z"
},
{
"slug": "jellystat",
@@ -1411,9 +1411,9 @@
{
"slug": "tandoor",
"repo": "TandoorRecipes/recipes",
"version": "2.5.1",
"version": "2.5.3",
"pinned": false,
"date": "2026-02-13T15:57:27Z"
"date": "2026-02-14T12:42:14Z"
},
{
"slug": "tasmoadmin",

View File

@@ -21,7 +21,7 @@
"resources": {
"cpu": 4,
"ram": 4096,
"hdd": 35,
"hdd": 40,
"os": "Ubuntu",
"version": "24.04"
}

View File

@@ -21,7 +21,7 @@
"resources": {
"cpu": 4,
"ram": 8192,
"hdd": 25,
"hdd": 50,
"os": "debian",
"version": "13"
}

View File

@@ -237,16 +237,21 @@ explain_exit_code() {
# json_escape()
#
# - Escapes a string for safe JSON embedding
# - Strips ANSI escape sequences and non-printable control characters
# - Handles backslashes, quotes, newlines, tabs, and carriage returns
# ------------------------------------------------------------------------------
json_escape() {
local s="$1"
# Strip ANSI escape sequences (color codes etc.)
s=$(printf '%s' "$s" | sed 's/\x1b\[[0-9;]*[a-zA-Z]//g')
s=${s//\\/\\\\}
s=${s//"/\\"/}
s=${s//$'\n'/\\n}
s=${s//$'\r'/}
s=${s//$'\t'/\\t}
echo "$s"
# Remove any remaining control characters (0x00-0x1F except those already handled)
s=$(printf '%s' "$s" | tr -d '\000-\010\013\014\016-\037')
printf '%s' "$s"
}
# ------------------------------------------------------------------------------
@@ -283,7 +288,33 @@ get_error_text() {
fi
if [[ -n "$logfile" && -s "$logfile" ]]; then
tail -n 20 "$logfile" 2>/dev/null | sed 's/\r$//'
tail -n 20 "$logfile" 2>/dev/null | sed 's/\r$//' | sed 's/\x1b\[[0-9;]*[a-zA-Z]//g'
fi
}
# ------------------------------------------------------------------------------
# build_error_string()
#
# - Builds a structured error string for telemetry reporting
# - Format: "exit_code=<N> | <explanation>\n---\n<last 20 log lines>"
# - If no log lines available, returns just the explanation
# - Arguments:
# * $1: exit_code (numeric)
# * $2: log_text (optional, output from get_error_text)
# - Returns structured error string via stdout
# ------------------------------------------------------------------------------
build_error_string() {
local exit_code="${1:-1}"
local log_text="${2:-}"
local explanation
explanation=$(explain_exit_code "$exit_code")
if [[ -n "$log_text" ]]; then
# Structured format: header + separator + log lines
printf 'exit_code=%s | %s\n---\n%s' "$exit_code" "$explanation" "$log_text"
else
# No log available - just the explanation with exit code
printf 'exit_code=%s | %s' "$exit_code" "$explanation"
fi
}
@@ -665,13 +696,12 @@ post_update_to_api() {
else
exit_code=1
fi
# Get log lines and build structured error string
local error_text=""
error_text=$(get_error_text)
if [[ -n "$error_text" ]]; then
error=$(json_escape "$error_text")
else
error=$(json_escape "$(explain_exit_code "$exit_code")")
fi
local full_error
full_error=$(build_error_string "$exit_code" "$error_text")
error=$(json_escape "$full_error")
short_error=$(json_escape "$(explain_exit_code "$exit_code")")
error_category=$(categorize_error "$exit_code")
[[ -z "$error" ]] && error="Unknown error"
@@ -814,31 +844,52 @@ EOF
categorize_error() {
local code="$1"
case "$code" in
# Network errors
6 | 7 | 22 | 28 | 35) echo "network" ;;
# Network errors (curl/wget)
6 | 7 | 22 | 35) echo "network" ;;
# Storage errors
214 | 217 | 219) echo "storage" ;;
# Timeout errors
28 | 124 | 211) echo "timeout" ;;
# Dependency/Package errors
100 | 101 | 102 | 127 | 160 | 161 | 162) echo "dependency" ;;
# Storage errors (Proxmox storage)
214 | 217 | 219 | 224) echo "storage" ;;
# Dependency/Package errors (APT, DPKG, pip, commands)
100 | 101 | 102 | 127 | 160 | 161 | 162 | 255) echo "dependency" ;;
# Permission errors
126 | 152) echo "permission" ;;
# Timeout errors
124 | 28 | 211) echo "timeout" ;;
# Configuration errors (Proxmox config, invalid args)
128 | 203 | 204 | 205 | 206 | 207 | 208) echo "config" ;;
# Configuration errors
203 | 204 | 205 | 206 | 207 | 208) echo "config" ;;
# Proxmox container/template errors
200 | 209 | 210 | 212 | 213 | 215 | 216 | 218 | 220 | 221 | 222 | 223 | 225 | 231) echo "proxmox" ;;
# Service/Systemd errors
150 | 151 | 153 | 154) echo "service" ;;
# Database errors (PostgreSQL, MySQL, MongoDB)
170 | 171 | 172 | 173 | 180 | 181 | 182 | 183 | 190 | 191 | 192 | 193) echo "database" ;;
# Node.js / JavaScript runtime errors
243 | 245 | 246 | 247 | 248 | 249) echo "runtime" ;;
# Python environment errors
# (already covered: 160-162 under dependency)
# Aborted by user
130) echo "aborted" ;;
# Resource errors (OOM, etc)
137 | 134) echo "resource" ;;
# Resource errors (OOM, SIGKILL, SIGABRT)
134 | 137) echo "resource" ;;
# Default
# Signal/Process errors (SIGTERM, SIGPIPE, SIGSEGV)
139 | 141 | 143) echo "signal" ;;
# Shell errors (general error, syntax error)
1 | 2) echo "shell" ;;
# Default - truly unknown
*) echo "unknown" ;;
esac
}
@@ -901,11 +952,9 @@ post_tool_to_api() {
[[ ! "$exit_code" =~ ^[0-9]+$ ]] && exit_code=1
local error_text=""
error_text=$(get_error_text)
if [[ -n "$error_text" ]]; then
error=$(json_escape "$error_text")
else
error=$(json_escape "$(explain_exit_code "$exit_code")")
fi
local full_error
full_error=$(build_error_string "$exit_code" "$error_text")
error=$(json_escape "$full_error")
error_category=$(categorize_error "$exit_code")
fi
@@ -968,11 +1017,9 @@ post_addon_to_api() {
[[ ! "$exit_code" =~ ^[0-9]+$ ]] && exit_code=1
local error_text=""
error_text=$(get_error_text)
if [[ -n "$error_text" ]]; then
error=$(json_escape "$error_text")
else
error=$(json_escape "$(explain_exit_code "$exit_code")")
fi
local full_error
full_error=$(build_error_string "$exit_code" "$error_text")
error=$(json_escape "$full_error")
error_category=$(categorize_error "$exit_code")
fi
@@ -1067,11 +1114,9 @@ post_update_to_api_extended() {
fi
local error_text=""
error_text=$(get_error_text)
if [[ -n "$error_text" ]]; then
error=$(json_escape "$error_text")
else
error=$(json_escape "$(explain_exit_code "$exit_code")")
fi
local full_error
full_error=$(build_error_string "$exit_code" "$error_text")
error=$(json_escape "$full_error")
error_category=$(categorize_error "$exit_code")
[[ -z "$error" ]] && error="Unknown error"
fi

View File

@@ -277,8 +277,9 @@ install_ssh_keys_into_ct() {
# ------------------------------------------------------------------------------
# validate_container_id()
#
# - Validates if a container ID is available for use
# - Checks if ID is already used by VM or LXC container
# - Validates if a container ID is available for use (CLUSTER-WIDE)
# - Checks cluster resources via pvesh for VMs/CTs on ALL nodes
# - Falls back to local config file check if pvesh unavailable
# - Checks if ID is used in LVM logical volumes
# - Returns 0 if ID is available, 1 if already in use
# ------------------------------------------------------------------------------
@@ -290,11 +291,35 @@ validate_container_id() {
return 1
fi
# Check if config file exists for VM or LXC
# CLUSTER-WIDE CHECK: Query all VMs/CTs across all nodes
# This catches IDs used on other nodes in the cluster
# NOTE: Works on single-node too - Proxmox always has internal cluster structure
# Falls back gracefully if pvesh unavailable or returns empty
if command -v pvesh &>/dev/null; then
local cluster_ids
cluster_ids=$(pvesh get /cluster/resources --type vm --output-format json 2>/dev/null |
grep -oP '"vmid":\s*\K[0-9]+' 2>/dev/null || true)
if [[ -n "$cluster_ids" ]] && echo "$cluster_ids" | grep -qw "$ctid"; then
return 1
fi
fi
# LOCAL FALLBACK: Check if config file exists for VM or LXC
# This handles edge cases where pvesh might not return all info
if [[ -f "/etc/pve/qemu-server/${ctid}.conf" ]] || [[ -f "/etc/pve/lxc/${ctid}.conf" ]]; then
return 1
fi
# Check ALL nodes in cluster for config files (handles pmxcfs sync delays)
# NOTE: On single-node, /etc/pve/nodes/ contains just the one node - still works
if [[ -d "/etc/pve/nodes" ]]; then
for node_dir in /etc/pve/nodes/*/; do
if [[ -f "${node_dir}qemu-server/${ctid}.conf" ]] || [[ -f "${node_dir}lxc/${ctid}.conf" ]]; then
return 1
fi
done
fi
# Check if ID is used in LVM logical volumes
if lvs --noheadings -o lv_name 2>/dev/null | grep -qE "(^|[-_])${ctid}($|[-_])"; then
return 1
@@ -306,63 +331,30 @@ validate_container_id() {
# ------------------------------------------------------------------------------
# get_valid_container_id()
#
# - Returns a valid, unused container ID
# - Returns a valid, unused container ID (CLUSTER-AWARE)
# - Uses pvesh /cluster/nextid as starting point (already cluster-aware)
# - If provided ID is valid, returns it
# - Otherwise increments from suggested ID until a free one is found
# - Otherwise increments until a free one is found across entire cluster
# - Calls validate_container_id() to check availability
# ------------------------------------------------------------------------------
get_valid_container_id() {
local suggested_id="${1:-$(pvesh get /cluster/nextid)}"
while ! validate_container_id "$suggested_id"; do
suggested_id=$((suggested_id + 1))
done
echo "$suggested_id"
}
# ------------------------------------------------------------------------------
# validate_container_id()
#
# - Validates if a container ID is available for use
# - Checks if ID is already used by VM or LXC container
# - Checks if ID is used in LVM logical volumes
# - Returns 0 if ID is available, 1 if already in use
# ------------------------------------------------------------------------------
validate_container_id() {
local ctid="$1"
# Check if ID is numeric
if ! [[ "$ctid" =~ ^[0-9]+$ ]]; then
return 1
fi
# Check if config file exists for VM or LXC
if [[ -f "/etc/pve/qemu-server/${ctid}.conf" ]] || [[ -f "/etc/pve/lxc/${ctid}.conf" ]]; then
return 1
fi
# Check if ID is used in LVM logical volumes
if lvs --noheadings -o lv_name 2>/dev/null | grep -qE "(^|[-_])${ctid}($|[-_])"; then
return 1
fi
return 0
}
# ------------------------------------------------------------------------------
# get_valid_container_id()
#
# - Returns a valid, unused container ID
# - If provided ID is valid, returns it
# - Otherwise increments from suggested ID until a free one is found
# - Calls validate_container_id() to check availability
# ------------------------------------------------------------------------------
get_valid_container_id() {
local suggested_id="${1:-$(pvesh get /cluster/nextid)}"
local suggested_id="${1:-$(pvesh get /cluster/nextid 2>/dev/null || echo 100)}"
# Ensure we have a valid starting ID
if ! [[ "$suggested_id" =~ ^[0-9]+$ ]]; then
suggested_id=$(pvesh get /cluster/nextid 2>/dev/null || echo 100)
fi
local max_attempts=1000
local attempts=0
while ! validate_container_id "$suggested_id"; do
suggested_id=$((suggested_id + 1))
attempts=$((attempts + 1))
if [[ $attempts -ge $max_attempts ]]; then
msg_error "Could not find available container ID after $max_attempts attempts"
exit 1
fi
done
echo "$suggested_id"
@@ -4133,8 +4125,7 @@ EOF'
# Show combined log location
if [[ -n "$CTID" && -n "${SESSION_ID:-}" ]]; then
echo ""
echo -e "${GN}${CL} Installation log: ${BL}${combined_log}${CL}"
msg_custom "📋" "${YW}" "Installation log: ${combined_log}"
fi
# Dev mode: Keep container or open breakpoint shell
@@ -4157,19 +4148,21 @@ EOF'
exit $install_exit_code
fi
# Prompt user for cleanup with 60s timeout (plain echo - no msg_info to avoid spinner)
# Prompt user for cleanup with 60s timeout
echo ""
echo -en "${YW}Remove broken container ${CTID}? (Y/n) [auto-remove in 60s]: ${CL}"
echo -en "${TAB}${TAB}${YW}Remove broken container ${CTID}? (Y/n) [auto-remove in 60s]: ${CL}"
if read -t 60 -r response; then
if [[ -z "$response" || "$response" =~ ^[Yy]$ ]]; then
# Remove container
echo -e "\n${TAB}${HOLD}${YW}Removing container ${CTID}${CL}"
echo ""
msg_info "Removing container ${CTID}"
pct stop "$CTID" &>/dev/null || true
pct destroy "$CTID" &>/dev/null || true
echo -e "${BFR}${CM}${GN}Container ${CTID} removed${CL}"
msg_ok "Container ${CTID} removed"
elif [[ "$response" =~ ^[Nn]$ ]]; then
echo -e "\n${TAB}${YW}Container ${CTID} kept for debugging${CL}"
echo ""
msg_warn "Container ${CTID} kept for debugging"
# Dev mode: Setup MOTD/SSH for debugging access to broken container
if [[ "${DEV_MODE_MOTD:-false}" == "true" ]]; then
@@ -4185,11 +4178,11 @@ EOF'
fi
else
# Timeout - auto-remove
echo -e "\n${YW}No response - auto-removing container${CL}"
echo -e "${TAB}${HOLD}${YW}Removing container ${CTID}${CL}"
echo ""
msg_info "No response - removing container ${CTID}"
pct stop "$CTID" &>/dev/null || true
pct destroy "$CTID" &>/dev/null || true
echo -e "${BFR}${CM}${GN}Container ${CTID} removed${CL}"
msg_ok "Container ${CTID} removed"
fi
# Force one final status update attempt after cleanup

View File

@@ -522,15 +522,9 @@ silent() {
msg_custom "→" "${YWB}" "${cmd}"
if [[ -s "$logfile" ]]; then
local log_lines=$(wc -l <"$logfile")
echo "--- Last 10 lines of silent log ---"
echo -e "\n${TAB}--- Last 10 lines of log ---"
tail -n 10 "$logfile"
echo "-----------------------------------"
# Show how to view full log if there are more lines
if [[ $log_lines -gt 10 ]]; then
msg_custom "📋" "${YW}" "View full log (${log_lines} lines): ${logfile}"
fi
echo -e "${TAB}-----------------------------------\n"
fi
exit "$rc"

View File

@@ -175,9 +175,9 @@ error_handler() {
fi
if [[ -n "$active_log" && -s "$active_log" ]]; then
echo "--- Last 20 lines of silent log ---"
echo -e "\n${TAB}--- Last 20 lines of log ---"
tail -n 20 "$active_log"
echo "-----------------------------------"
echo -e "${TAB}-----------------------------------\n"
# Detect context: Container (INSTALL_LOG set + /root exists) vs Host (BUILD_LOG)
if [[ -n "${INSTALL_LOG:-}" && -d /root ]]; then
@@ -204,23 +204,50 @@ error_handler() {
fi
echo ""
echo -en "${YW}Remove broken container ${CTID}? (Y/n) [auto-remove in 60s]: ${CL}"
if declare -f msg_custom >/dev/null 2>&1; then
echo -en "${TAB}${TAB}${YW}Remove broken container ${CTID}? (Y/n) [auto-remove in 60s]: ${CL}"
else
echo -en "${YW}Remove broken container ${CTID}? (Y/n) [auto-remove in 60s]: ${CL}"
fi
if read -t 60 -r response; then
if [[ -z "$response" || "$response" =~ ^[Yy]$ ]]; then
echo -e "\n${YW}Removing container ${CTID}${CL}"
echo ""
if declare -f msg_info >/dev/null 2>&1; then
msg_info "Removing container ${CTID}"
else
echo -e "${YW}Removing container ${CTID}${CL}"
fi
pct stop "$CTID" &>/dev/null || true
pct destroy "$CTID" &>/dev/null || true
echo -e "${GN}${CL} Container ${CTID} removed"
if declare -f msg_ok >/dev/null 2>&1; then
msg_ok "Container ${CTID} removed"
else
echo -e "${GN}${CL} Container ${CTID} removed"
fi
elif [[ "$response" =~ ^[Nn]$ ]]; then
echo -e "\n${YW}Container ${CTID} kept for debugging${CL}"
echo ""
if declare -f msg_warn >/dev/null 2>&1; then
msg_warn "Container ${CTID} kept for debugging"
else
echo -e "${YW}Container ${CTID} kept for debugging${CL}"
fi
fi
else
# Timeout - auto-remove
echo -e "\n${YW}No response - auto-removing container${CL}"
echo ""
if declare -f msg_info >/dev/null 2>&1; then
msg_info "No response - removing container ${CTID}"
else
echo -e "${YW}No response - removing container ${CTID}${CL}"
fi
pct stop "$CTID" &>/dev/null || true
pct destroy "$CTID" &>/dev/null || true
echo -e "${GN}${CL} Container ${CTID} removed"
if declare -f msg_ok >/dev/null 2>&1; then
msg_ok "Container ${CTID} removed"
else
echo -e "${GN}${CL} Container ${CTID} removed"
fi
fi
# Force one final status update attempt after cleanup
@@ -254,6 +281,10 @@ on_exit() {
# post_to_api was called ("installing" sent) but post_update_to_api was never called
if [[ "${POST_TO_API_DONE:-}" == "true" && "${POST_UPDATE_DONE:-}" != "true" ]]; then
if declare -f post_update_to_api >/dev/null 2>&1; then
# Ensure log is accessible on host before reporting
if declare -f ensure_log_on_host >/dev/null 2>&1; then
ensure_log_on_host
fi
if [[ $exit_code -ne 0 ]]; then
post_update_to_api "failed" "$exit_code"
else
@@ -273,6 +304,10 @@ on_exit() {
# - Exits with code 130 (128 + SIGINT=2)
# ------------------------------------------------------------------------------
on_interrupt() {
# Ensure log is accessible on host before reporting
if declare -f ensure_log_on_host >/dev/null 2>&1; then
ensure_log_on_host
fi
# Report interruption to telemetry API (prevents stuck "installing" records)
if declare -f post_update_to_api >/dev/null 2>&1; then
post_update_to_api "failed" "130"
@@ -294,6 +329,10 @@ on_interrupt() {
# - Triggered by external process termination
# ------------------------------------------------------------------------------
on_terminate() {
# Ensure log is accessible on host before reporting
if declare -f ensure_log_on_host >/dev/null 2>&1; then
ensure_log_on_host
fi
# Report termination to telemetry API (prevents stuck "installing" records)
if declare -f post_update_to_api >/dev/null 2>&1; then
post_update_to_api "failed" "143"

View File

@@ -1913,7 +1913,7 @@ function fetch_and_deploy_codeberg_release() {
local app="$1"
local repo="$2"
local mode="${3:-tarball}" # tarball | binary | prebuild | singlefile | tag
local version="${4:-latest}"
local version="${var_appversion:-${4:-latest}}"
local target="${5:-/opt/$app}"
local asset_pattern="${6:-}"
@@ -2443,7 +2443,7 @@ function fetch_and_deploy_gh_release() {
local app="$1"
local repo="$2"
local mode="${3:-tarball}" # tarball | binary | prebuild | singlefile
local version="${4:-latest}"
local version="${var_appversion:-${4:-latest}}"
local target="${5:-/opt/$app}"
local asset_pattern="${6:-}"

View File

@@ -207,15 +207,9 @@ silent() {
msg_custom "→" "${YWB}" "${cmd}"
if [[ -s "$logfile" ]]; then
local log_lines=$(wc -l <"$logfile")
echo "--- Last 10 lines of log ---"
echo -e "\n${TAB}--- Last 10 lines of log ---"
tail -n 10 "$logfile"
echo "----------------------------"
# Show how to view full log if there are more lines
if [[ $log_lines -gt 10 ]]; then
msg_custom "📋" "${YW}" "View full log (${log_lines} lines): ${logfile}"
fi
echo -e "${TAB}----------------------------\n"
fi
exit "$rc"

View File

@@ -110,6 +110,11 @@ for container in $(pct list | awk '{if(NR>1) print $1}'); do
container_hostname=$(pct exec "$container" hostname)
containers_needing_reboot+=("$container ($container_hostname)")
fi
# check if patchmon agent is present in container and run a report if found
if pct exec "$container" -- [ -e "/usr/local/bin/patchmon-agent" ]; then
echo -e "${BL}[Info]${GN} patchmon-agent found in ${BL} $container ${CL}, triggering report. \n"
pct exec "$container" -- "/usr/local/bin/patchmon-agent" "report"
fi
fi
done
wait