mirror of
https://github.com/community-scripts/ProxmoxVE.git
synced 2026-02-03 20:03:25 +01:00
Compare commits
46 Commits
2026-01-19
...
2026-01-21
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4e21f411f5 | ||
|
|
fe21d3577f | ||
|
|
3725023ee3 | ||
|
|
c19817af8d | ||
|
|
5378d41acf | ||
|
|
5bb48fc843 | ||
|
|
e935289128 | ||
|
|
0db119d2c3 | ||
|
|
5c9087a91a | ||
|
|
1d7d8c27fa | ||
|
|
fae2d032ab | ||
|
|
2fab70294f | ||
|
|
477199a4c2 | ||
|
|
733425f970 | ||
|
|
7395a44277 | ||
|
|
f555f9ae0c | ||
|
|
fe2384a2fa | ||
|
|
5384adf0c3 | ||
|
|
ed18776710 | ||
|
|
13824931b0 | ||
|
|
88557d53f4 | ||
|
|
0c9653c7cb | ||
|
|
914c316f42 | ||
|
|
49d92afb98 | ||
|
|
dba473b2b3 | ||
|
|
5dd50aacd7 | ||
|
|
0dcb8b5ef7 | ||
|
|
a48435e064 | ||
|
|
cb2141ebe2 | ||
|
|
b1f21b4024 | ||
|
|
7699f4f6ad | ||
|
|
657a9629be | ||
|
|
d71f24bddb | ||
|
|
5a1c1e06f9 | ||
|
|
7146e8d5b9 | ||
|
|
a5dfa33af3 | ||
|
|
6dd5fbd7da | ||
|
|
718cda8eb1 | ||
|
|
ff5263981b | ||
|
|
785177fe29 | ||
|
|
5e7e7c884d | ||
|
|
97275d06ea | ||
|
|
0f15d81cd3 | ||
|
|
6712f6a9ca | ||
|
|
1816b0169e | ||
|
|
3f05972eb9 |
49
CHANGELOG.md
49
CHANGELOG.md
@@ -10,8 +10,57 @@
|
||||
> [!CAUTION]
|
||||
Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit the project's popularity for potentially malicious purposes.
|
||||
|
||||
## 2026-01-22
|
||||
|
||||
## 2026-01-21
|
||||
|
||||
### 🆕 New Scripts
|
||||
|
||||
- Byparr ([#11039](https://github.com/community-scripts/ProxmoxVE/pull/11039))
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- fix: Snipe-IT update missing all user uploads (#11032) [@ruanmed](https://github.com/ruanmed) ([#11033](https://github.com/community-scripts/ProxmoxVE/pull/11033))
|
||||
- yubal: fix for v0.2 [@CrazyWolf13](https://github.com/CrazyWolf13) ([#11006](https://github.com/community-scripts/ProxmoxVE/pull/11006))
|
||||
- Joplin-Server: use yarn workspaces focus for faster builds [@MickLesk](https://github.com/MickLesk) ([#11027](https://github.com/community-scripts/ProxmoxVE/pull/11027))
|
||||
|
||||
### 💾 Core
|
||||
|
||||
- #### ✨ New Features
|
||||
|
||||
- tools: add ubuntu PHP repository setup [@MickLesk](https://github.com/MickLesk) ([#11034](https://github.com/community-scripts/ProxmoxVE/pull/11034))
|
||||
|
||||
- #### 🔧 Refactor
|
||||
|
||||
- core: allow empty tags & improve template search [@MickLesk](https://github.com/MickLesk) ([#11020](https://github.com/community-scripts/ProxmoxVE/pull/11020))
|
||||
|
||||
### 🌐 Website
|
||||
|
||||
- #### 📝 Script Information
|
||||
|
||||
- Joplin Server: Set disable flag to true in joplin-server.json [@tremor021](https://github.com/tremor021) ([#11008](https://github.com/community-scripts/ProxmoxVE/pull/11008))
|
||||
|
||||
## 2026-01-20
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- dolibarr: switch mirror [@MickLesk](https://github.com/MickLesk) ([#11004](https://github.com/community-scripts/ProxmoxVE/pull/11004))
|
||||
- checkmk: reordner base function [@MickLesk](https://github.com/MickLesk) ([#10990](https://github.com/community-scripts/ProxmoxVE/pull/10990))
|
||||
- Homepage: preserve config directory during updates [@MickLesk](https://github.com/MickLesk) ([#10993](https://github.com/community-scripts/ProxmoxVE/pull/10993))
|
||||
- DiscoPanel: add go for update build process [@miausalvaje](https://github.com/miausalvaje) ([#10991](https://github.com/community-scripts/ProxmoxVE/pull/10991))
|
||||
|
||||
### 💾 Core
|
||||
|
||||
- #### ✨ New Features
|
||||
|
||||
- core: add retry logic for template lock in LXC container creation [@MickLesk](https://github.com/MickLesk) ([#11002](https://github.com/community-scripts/ProxmoxVE/pull/11002))
|
||||
- core: implement ensure_profile_loaded function [@MickLesk](https://github.com/MickLesk) ([#10999](https://github.com/community-scripts/ProxmoxVE/pull/10999))
|
||||
- core: add input validations for several functions [@MickLesk](https://github.com/MickLesk) ([#10995](https://github.com/community-scripts/ProxmoxVE/pull/10995))
|
||||
|
||||
## 2026-01-19
|
||||
|
||||
### 🆕 New Scripts
|
||||
|
||||
53
ct/byparr.sh
Normal file
53
ct/byparr.sh
Normal file
@@ -0,0 +1,53 @@
|
||||
#!/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: luismco
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://github.com/ThePhaseless/Byparr
|
||||
|
||||
APP="Byparr"
|
||||
var_tags="${var_tags:-proxy}"
|
||||
var_cpu="${var_cpu:-2}"
|
||||
var_ram="${var_ram:-2048}"
|
||||
var_disk="${var_disk:-4}"
|
||||
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/Byparr ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
|
||||
if check_for_gh_release "Byparr" "ThePhaseless/Byparr"; then
|
||||
msg_info "Stopping Service"
|
||||
systemctl stop byparr
|
||||
msg_ok "Stopped Service"
|
||||
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "Byparr" "ThePhaseless/Byparr" "tarball" "latest"
|
||||
|
||||
msg_info "Starting Service"
|
||||
systemctl start byparr
|
||||
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}:8191${CL}"
|
||||
@@ -54,9 +54,14 @@ function update_script() {
|
||||
cd /opt/discopanel/web/discopanel
|
||||
$STD npm install
|
||||
$STD npm run build
|
||||
msg_ok "Built Web Interface"
|
||||
|
||||
setup_go
|
||||
|
||||
msg_info "Building DiscoPanel"
|
||||
cd /opt/discopanel
|
||||
$STD go build -o discopanel cmd/discopanel/main.go
|
||||
msg_ok "Setup DiscoPanel"
|
||||
msg_ok "Built DiscoPanel"
|
||||
|
||||
msg_info "Restoring Data"
|
||||
mkdir -p /opt/discopanel/data
|
||||
|
||||
6
ct/headers/byparr
Normal file
6
ct/headers/byparr
Normal file
@@ -0,0 +1,6 @@
|
||||
____
|
||||
/ __ )__ ______ ____ ___________
|
||||
/ __ / / / / __ \/ __ `/ ___/ ___/
|
||||
/ /_/ / /_/ / /_/ / /_/ / / / /
|
||||
/_____/\__, / .___/\__,_/_/ /_/
|
||||
/____/_/
|
||||
@@ -45,8 +45,11 @@ function update_script() {
|
||||
msg_ok "Stopped service"
|
||||
|
||||
cp /opt/homepage/.env /opt/homepage.env
|
||||
cp -r /opt/homepage/config /opt/homepage_config_backup
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "homepage" "gethomepage/homepage" "tarball"
|
||||
mv /opt/homepage.env /opt/homepage
|
||||
rm -rf /opt/homepage/config
|
||||
mv /opt/homepage_config_backup /opt/homepage/config
|
||||
|
||||
msg_info "Updating Homepage (Patience)"
|
||||
RELEASE=$(get_latest_github_release "gethomepage/homepage")
|
||||
|
||||
@@ -44,7 +44,9 @@ function update_script() {
|
||||
sed -i "/onenote-converter/d" packages/lib/package.json
|
||||
$STD yarn config set --home enableTelemetry 0
|
||||
export BUILD_SEQUENCIAL=1
|
||||
$STD yarn install --inline-builds
|
||||
$STD yarn workspaces focus @joplin/server
|
||||
$STD yarn workspaces foreach -R --topological-dev --from @joplin/server run build
|
||||
$STD yarn workspaces foreach -R --topological-dev --from @joplin/server run tsc
|
||||
msg_ok "Updated Joplin-Server"
|
||||
|
||||
msg_info "Starting Services"
|
||||
|
||||
@@ -50,8 +50,8 @@ function update_script() {
|
||||
$STD apt update
|
||||
$STD apt -y upgrade
|
||||
cp /opt/snipe-it-backup/.env /opt/snipe-it/.env
|
||||
cp -r /opt/snipe-it-backup/public/uploads/ /opt/snipe-it/public/uploads/
|
||||
cp -r /opt/snipe-it-backup/storage/private_uploads /opt/snipe-it/storage/private_uploads
|
||||
cp -r /opt/snipe-it-backup/public/uploads/. /opt/snipe-it/public/uploads/
|
||||
cp -r /opt/snipe-it-backup/storage/private_uploads/. /opt/snipe-it/storage/private_uploads/
|
||||
cd /opt/snipe-it/
|
||||
export COMPOSER_ALLOW_SUPERUSER=1
|
||||
$STD composer install --no-dev --optimize-autoloader --no-interaction
|
||||
|
||||
35
frontend/public/json/byparr.json
Normal file
35
frontend/public/json/byparr.json
Normal file
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"name": "Byparr",
|
||||
"slug": "byparr",
|
||||
"categories": [
|
||||
14
|
||||
],
|
||||
"date_created": "2026-01-21",
|
||||
"type": "ct",
|
||||
"updateable": true,
|
||||
"privileged": false,
|
||||
"interface_port": 8191,
|
||||
"documentation": "https://github.com/ThePhaseless/Byparr/blob/master/README.md",
|
||||
"website": "https://github.com/ThePhaseless/Byparr",
|
||||
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/byparr.webp",
|
||||
"config_path": "",
|
||||
"description": "Byparr is a proxy server to bypass Cloudflare and DDoS-GUARD protection.",
|
||||
"install_methods": [
|
||||
{
|
||||
"type": "default",
|
||||
"script": "ct/byparr.sh",
|
||||
"resources": {
|
||||
"cpu": 2,
|
||||
"ram": 2048,
|
||||
"hdd": 4,
|
||||
"os": "debian",
|
||||
"version": "13"
|
||||
}
|
||||
}
|
||||
],
|
||||
"default_credentials": {
|
||||
"username": null,
|
||||
"password": null
|
||||
},
|
||||
"notes": []
|
||||
}
|
||||
@@ -1,4 +1,284 @@
|
||||
[
|
||||
{
|
||||
"name": "Stirling-Tools/Stirling-PDF",
|
||||
"version": "v2.3.0",
|
||||
"date": "2026-01-15T19:29:02Z"
|
||||
},
|
||||
{
|
||||
"name": "ollama/ollama",
|
||||
"version": "v0.14.3-rc3",
|
||||
"date": "2026-01-20T20:20:53Z"
|
||||
},
|
||||
{
|
||||
"name": "BerriAI/litellm",
|
||||
"version": "v1.81.0.rc.4",
|
||||
"date": "2026-01-21T21:43:55Z"
|
||||
},
|
||||
{
|
||||
"name": "Infisical/infisical",
|
||||
"version": "v0.156.2",
|
||||
"date": "2026-01-21T21:02:11Z"
|
||||
},
|
||||
{
|
||||
"name": "runtipi/runtipi",
|
||||
"version": "nightly",
|
||||
"date": "2026-01-20T21:10:15Z"
|
||||
},
|
||||
{
|
||||
"name": "Comfy-Org/ComfyUI",
|
||||
"version": "v0.10.0",
|
||||
"date": "2026-01-21T19:22:04Z"
|
||||
},
|
||||
{
|
||||
"name": "fccview/jotty",
|
||||
"version": "1.18.1",
|
||||
"date": "2026-01-21T19:16:44Z"
|
||||
},
|
||||
{
|
||||
"name": "firefly-iii/firefly-iii",
|
||||
"version": "v6.4.16",
|
||||
"date": "2026-01-17T07:54:15Z"
|
||||
},
|
||||
{
|
||||
"name": "metabase/metabase",
|
||||
"version": "v0.57.x",
|
||||
"date": "2026-01-21T17:54:29Z"
|
||||
},
|
||||
{
|
||||
"name": "openobserve/openobserve",
|
||||
"version": "v0.50.2",
|
||||
"date": "2026-01-21T17:02:52Z"
|
||||
},
|
||||
{
|
||||
"name": "LimeSurvey/LimeSurvey",
|
||||
"version": "7.0.0-beta1+260113",
|
||||
"date": "2026-01-21T15:14:45Z"
|
||||
},
|
||||
{
|
||||
"name": "jenkinsci/jenkins",
|
||||
"version": "jenkins-2.541.1",
|
||||
"date": "2026-01-21T15:09:10Z"
|
||||
},
|
||||
{
|
||||
"name": "dedicatedcode/reitti",
|
||||
"version": "v3.4.0",
|
||||
"date": "2026-01-21T14:29:46Z"
|
||||
},
|
||||
{
|
||||
"name": "node-red/node-red",
|
||||
"version": "4.1.3",
|
||||
"date": "2026-01-07T16:24:23Z"
|
||||
},
|
||||
{
|
||||
"name": "prometheus/prometheus",
|
||||
"version": "v3.5.1",
|
||||
"date": "2026-01-21T13:28:57Z"
|
||||
},
|
||||
{
|
||||
"name": "apache/tomcat",
|
||||
"version": "10.1.51",
|
||||
"date": "2026-01-21T13:19:21Z"
|
||||
},
|
||||
{
|
||||
"name": "semaphoreui/semaphore",
|
||||
"version": "v2.17.0-rc7",
|
||||
"date": "2026-01-21T12:12:33Z"
|
||||
},
|
||||
{
|
||||
"name": "evcc-io/evcc",
|
||||
"version": "0.300.5",
|
||||
"date": "2026-01-21T11:35:44Z"
|
||||
},
|
||||
{
|
||||
"name": "javedh-dev/tracktor",
|
||||
"version": "1.2.1",
|
||||
"date": "2026-01-21T11:12:28Z"
|
||||
},
|
||||
{
|
||||
"name": "endurain-project/endurain",
|
||||
"version": "v0.17.0",
|
||||
"date": "2026-01-21T10:55:33Z"
|
||||
},
|
||||
{
|
||||
"name": "emqx/emqx",
|
||||
"version": "e5.10.3-rc.2",
|
||||
"date": "2026-01-21T08:57:16Z"
|
||||
},
|
||||
{
|
||||
"name": "docker/compose",
|
||||
"version": "v5.0.2",
|
||||
"date": "2026-01-21T07:42:38Z"
|
||||
},
|
||||
{
|
||||
"name": "SigNoz/signoz",
|
||||
"version": "v0.108.0",
|
||||
"date": "2026-01-21T06:45:16Z"
|
||||
},
|
||||
{
|
||||
"name": "rabbitmq/rabbitmq-server",
|
||||
"version": "v4.2.2",
|
||||
"date": "2025-12-15T18:25:36Z"
|
||||
},
|
||||
{
|
||||
"name": "Jackett/Jackett",
|
||||
"version": "v0.24.898",
|
||||
"date": "2026-01-21T05:50:19Z"
|
||||
},
|
||||
{
|
||||
"name": "9001/copyparty",
|
||||
"version": "v1.20.3",
|
||||
"date": "2026-01-21T05:39:57Z"
|
||||
},
|
||||
{
|
||||
"name": "donetick/donetick",
|
||||
"version": "v0.1.70-beta.1",
|
||||
"date": "2026-01-21T05:35:05Z"
|
||||
},
|
||||
{
|
||||
"name": "esphome/esphome",
|
||||
"version": "2026.1.0",
|
||||
"date": "2026-01-21T03:43:09Z"
|
||||
},
|
||||
{
|
||||
"name": "jeedom/core",
|
||||
"version": "4.5.2",
|
||||
"date": "2026-01-21T00:27:05Z"
|
||||
},
|
||||
{
|
||||
"name": "steveiliop56/tinyauth",
|
||||
"version": "v4.1.0",
|
||||
"date": "2025-11-23T12:13:34Z"
|
||||
},
|
||||
{
|
||||
"name": "paperless-ngx/paperless-ngx",
|
||||
"version": "v2.20.5",
|
||||
"date": "2026-01-21T00:12:33Z"
|
||||
},
|
||||
{
|
||||
"name": "keycloak/keycloak",
|
||||
"version": "26.4.8",
|
||||
"date": "2026-01-15T13:52:29Z"
|
||||
},
|
||||
{
|
||||
"name": "ZoeyVid/NPMplus",
|
||||
"version": "2026-01-20-r2",
|
||||
"date": "2026-01-20T22:28:54Z"
|
||||
},
|
||||
{
|
||||
"name": "seerr-team/seerr",
|
||||
"version": "preview-availability-sync-fix",
|
||||
"date": "2026-01-20T22:11:24Z"
|
||||
},
|
||||
{
|
||||
"name": "chrisbenincasa/tunarr",
|
||||
"version": "v1.2.0-dev.1",
|
||||
"date": "2026-01-20T21:46:14Z"
|
||||
},
|
||||
{
|
||||
"name": "rcourtman/Pulse",
|
||||
"version": "v5.0.17",
|
||||
"date": "2026-01-20T19:07:30Z"
|
||||
},
|
||||
{
|
||||
"name": "netbox-community/netbox",
|
||||
"version": "v4.5.1",
|
||||
"date": "2026-01-20T19:45:05Z"
|
||||
},
|
||||
{
|
||||
"name": "nickheyer/discopanel",
|
||||
"version": "v1.0.24",
|
||||
"date": "2026-01-20T18:31:20Z"
|
||||
},
|
||||
{
|
||||
"name": "mysql/mysql-server",
|
||||
"version": "mysql-cluster-8.0.45",
|
||||
"date": "2026-01-20T18:27:03Z"
|
||||
},
|
||||
{
|
||||
"name": "element-hq/synapse",
|
||||
"version": "v1.145.0",
|
||||
"date": "2026-01-13T16:49:51Z"
|
||||
},
|
||||
{
|
||||
"name": "chrisvel/tududi",
|
||||
"version": "v0.88.4",
|
||||
"date": "2026-01-20T16:02:12Z"
|
||||
},
|
||||
{
|
||||
"name": "gtsteffaniak/filebrowser",
|
||||
"version": "v1.1.1-stable",
|
||||
"date": "2026-01-12T23:25:10Z"
|
||||
},
|
||||
{
|
||||
"name": "mattermost/mattermost",
|
||||
"version": "@mattermost/client@11.3.0",
|
||||
"date": "2026-01-20T15:26:31Z"
|
||||
},
|
||||
{
|
||||
"name": "theonedev/onedev",
|
||||
"version": "v14.0.8",
|
||||
"date": "2026-01-20T15:10:44Z"
|
||||
},
|
||||
{
|
||||
"name": "meilisearch/meilisearch",
|
||||
"version": "latest",
|
||||
"date": "2026-01-20T14:25:19Z"
|
||||
},
|
||||
{
|
||||
"name": "sysadminsmedia/homebox",
|
||||
"version": "v0.23.0-rc.1",
|
||||
"date": "2026-01-20T14:19:56Z"
|
||||
},
|
||||
{
|
||||
"name": "n8n-io/n8n",
|
||||
"version": "n8n@2.3.6",
|
||||
"date": "2026-01-16T15:00:42Z"
|
||||
},
|
||||
{
|
||||
"name": "dgtlmoon/changedetection.io",
|
||||
"version": "0.52.8",
|
||||
"date": "2026-01-20T12:36:05Z"
|
||||
},
|
||||
{
|
||||
"name": "lazy-media/reactive-resume",
|
||||
"version": "v1.2.7",
|
||||
"date": "2026-01-20T11:59:40Z"
|
||||
},
|
||||
{
|
||||
"name": "cloudflare/cloudflared",
|
||||
"version": "2026.1.1",
|
||||
"date": "2026-01-20T11:22:06Z"
|
||||
},
|
||||
{
|
||||
"name": "passbolt/passbolt_api",
|
||||
"version": "v5.9.0-test.1",
|
||||
"date": "2026-01-20T10:34:53Z"
|
||||
},
|
||||
{
|
||||
"name": "Luligu/matterbridge",
|
||||
"version": "3.5.0",
|
||||
"date": "2026-01-20T08:53:52Z"
|
||||
},
|
||||
{
|
||||
"name": "nzbgetcom/nzbget",
|
||||
"version": "v25.4",
|
||||
"date": "2025-10-09T10:27:01Z"
|
||||
},
|
||||
{
|
||||
"name": "HydroshieldMKII/Guardian",
|
||||
"version": "v1.3.4",
|
||||
"date": "2026-01-20T06:20:36Z"
|
||||
},
|
||||
{
|
||||
"name": "morpheus65535/bazarr",
|
||||
"version": "v1.5.4",
|
||||
"date": "2026-01-04T22:41:00Z"
|
||||
},
|
||||
{
|
||||
"name": "diced/zipline",
|
||||
"version": "v4.4.1",
|
||||
"date": "2026-01-20T01:29:01Z"
|
||||
},
|
||||
{
|
||||
"name": "binwiederhier/ntfy",
|
||||
"version": "v2.16.0",
|
||||
@@ -10,29 +290,9 @@
|
||||
"date": "2026-01-19T20:51:19Z"
|
||||
},
|
||||
{
|
||||
"name": "ollama/ollama",
|
||||
"version": "v0.14.3-rc2",
|
||||
"date": "2026-01-19T20:48:34Z"
|
||||
},
|
||||
{
|
||||
"name": "firefly-iii/firefly-iii",
|
||||
"version": "v6.4.16",
|
||||
"date": "2026-01-17T07:54:15Z"
|
||||
},
|
||||
{
|
||||
"name": "metabase/metabase",
|
||||
"version": "v0.58.x",
|
||||
"date": "2026-01-19T18:21:04Z"
|
||||
},
|
||||
{
|
||||
"name": "apache/tomcat",
|
||||
"version": "11.0.16",
|
||||
"date": "2026-01-19T18:15:05Z"
|
||||
},
|
||||
{
|
||||
"name": "paperless-ngx/paperless-ngx",
|
||||
"version": "v2.20.5",
|
||||
"date": "2026-01-19T17:55:57Z"
|
||||
"name": "livebook-dev/livebook",
|
||||
"version": "nightly",
|
||||
"date": "2026-01-19T18:03:38Z"
|
||||
},
|
||||
{
|
||||
"name": "ghostfolio/ghostfolio",
|
||||
@@ -44,16 +304,6 @@
|
||||
"version": "server-v3.5.2",
|
||||
"date": "2025-12-19T21:28:55Z"
|
||||
},
|
||||
{
|
||||
"name": "meilisearch/meilisearch",
|
||||
"version": "prototype-v1.33.0-hannoy-better-linear-scanning.4",
|
||||
"date": "2026-01-19T16:37:18Z"
|
||||
},
|
||||
{
|
||||
"name": "Infisical/infisical",
|
||||
"version": "v0.155.6",
|
||||
"date": "2026-01-19T16:35:03Z"
|
||||
},
|
||||
{
|
||||
"name": "bunkerity/bunkerweb",
|
||||
"version": "v1.6.7",
|
||||
@@ -69,11 +319,6 @@
|
||||
"version": "pmm-6401-v1.134.0",
|
||||
"date": "2026-01-19T13:31:08Z"
|
||||
},
|
||||
{
|
||||
"name": "keycloak/keycloak",
|
||||
"version": "26.4.8",
|
||||
"date": "2026-01-15T13:52:29Z"
|
||||
},
|
||||
{
|
||||
"name": "crowdsecurity/crowdsec",
|
||||
"version": "v1.7.4",
|
||||
@@ -94,36 +339,11 @@
|
||||
"version": "v1.9.14",
|
||||
"date": "2026-01-19T09:16:56Z"
|
||||
},
|
||||
{
|
||||
"name": "dgtlmoon/changedetection.io",
|
||||
"version": "0.52.7",
|
||||
"date": "2026-01-19T08:38:05Z"
|
||||
},
|
||||
{
|
||||
"name": "morpheus65535/bazarr",
|
||||
"version": "v1.5.4",
|
||||
"date": "2026-01-04T22:41:00Z"
|
||||
},
|
||||
{
|
||||
"name": "Jackett/Jackett",
|
||||
"version": "v0.24.887",
|
||||
"date": "2026-01-19T05:55:24Z"
|
||||
},
|
||||
{
|
||||
"name": "gethomepage/homepage",
|
||||
"version": "v1.9.0",
|
||||
"date": "2026-01-19T05:46:09Z"
|
||||
},
|
||||
{
|
||||
"name": "nickheyer/discopanel",
|
||||
"version": "v1.0.23",
|
||||
"date": "2026-01-19T05:14:43Z"
|
||||
},
|
||||
{
|
||||
"name": "9001/copyparty",
|
||||
"version": "v1.20.2",
|
||||
"date": "2026-01-19T02:20:10Z"
|
||||
},
|
||||
{
|
||||
"name": "jellyfin/jellyfin",
|
||||
"version": "v10.11.6",
|
||||
@@ -134,16 +354,6 @@
|
||||
"version": "2.1.0rc1",
|
||||
"date": "2026-01-19T00:48:21Z"
|
||||
},
|
||||
{
|
||||
"name": "steveiliop56/tinyauth",
|
||||
"version": "v4.1.0",
|
||||
"date": "2025-11-23T12:13:34Z"
|
||||
},
|
||||
{
|
||||
"name": "jeedom/core",
|
||||
"version": "4.5.2",
|
||||
"date": "2026-01-19T00:27:05Z"
|
||||
},
|
||||
{
|
||||
"name": "Kareadita/Kavita",
|
||||
"version": "v0.8.9.1",
|
||||
@@ -164,16 +374,6 @@
|
||||
"version": "v2.5.0",
|
||||
"date": "2026-01-18T22:16:38Z"
|
||||
},
|
||||
{
|
||||
"name": "seerr-team/seerr",
|
||||
"version": "preview-remonitor-sonarr-episodes",
|
||||
"date": "2026-01-18T20:33:38Z"
|
||||
},
|
||||
{
|
||||
"name": "fccview/jotty",
|
||||
"version": "1.18.0",
|
||||
"date": "2026-01-18T19:00:48Z"
|
||||
},
|
||||
{
|
||||
"name": "Brandawg93/PeaNUT",
|
||||
"version": "v5.21.2",
|
||||
@@ -194,11 +394,6 @@
|
||||
"version": "2.4",
|
||||
"date": "2026-01-18T12:12:02Z"
|
||||
},
|
||||
{
|
||||
"name": "BerriAI/litellm",
|
||||
"version": "v1.81.0-nightly",
|
||||
"date": "2026-01-18T04:06:15Z"
|
||||
},
|
||||
{
|
||||
"name": "hyperion-project/hyperion.ng",
|
||||
"version": "2.1.1",
|
||||
@@ -209,26 +404,11 @@
|
||||
"version": "v7.14.2",
|
||||
"date": "2026-01-18T00:26:09Z"
|
||||
},
|
||||
{
|
||||
"name": "chrisbenincasa/tunarr",
|
||||
"version": "v1.1.1",
|
||||
"date": "2026-01-17T22:35:09Z"
|
||||
},
|
||||
{
|
||||
"name": "ZoeyVid/NPMplus",
|
||||
"version": "2026-01-17-r3",
|
||||
"date": "2026-01-17T21:45:17Z"
|
||||
},
|
||||
{
|
||||
"name": "outline/outline",
|
||||
"version": "v1.3.0",
|
||||
"date": "2026-01-17T16:28:04Z"
|
||||
},
|
||||
{
|
||||
"name": "evcc-io/evcc",
|
||||
"version": "0.300.4",
|
||||
"date": "2026-01-17T14:11:01Z"
|
||||
},
|
||||
{
|
||||
"name": "LogicLabs-OU/OpenArchiver",
|
||||
"version": "v0.4.1",
|
||||
@@ -244,11 +424,6 @@
|
||||
"version": "v6.13.6",
|
||||
"date": "2025-11-04T13:35:35Z"
|
||||
},
|
||||
{
|
||||
"name": "esphome/esphome",
|
||||
"version": "2025.12.7",
|
||||
"date": "2026-01-17T03:49:29Z"
|
||||
},
|
||||
{
|
||||
"name": "coder/code-server",
|
||||
"version": "v4.108.1",
|
||||
@@ -269,26 +444,6 @@
|
||||
"version": "v1.50.1",
|
||||
"date": "2026-01-16T19:27:38Z"
|
||||
},
|
||||
{
|
||||
"name": "livebook-dev/livebook",
|
||||
"version": "v0.18.3",
|
||||
"date": "2026-01-14T21:50:55Z"
|
||||
},
|
||||
{
|
||||
"name": "cloudflare/cloudflared",
|
||||
"version": "2026.1.0",
|
||||
"date": "2026-01-16T17:48:15Z"
|
||||
},
|
||||
{
|
||||
"name": "n8n-io/n8n",
|
||||
"version": "n8n@2.3.6",
|
||||
"date": "2026-01-16T15:00:42Z"
|
||||
},
|
||||
{
|
||||
"name": "emqx/emqx",
|
||||
"version": "6.0.2",
|
||||
"date": "2026-01-16T13:52:11Z"
|
||||
},
|
||||
{
|
||||
"name": "silverbulletmd/silverbullet",
|
||||
"version": "2.4.1",
|
||||
@@ -319,31 +474,11 @@
|
||||
"version": "v0.13.6",
|
||||
"date": "2026-01-15T23:34:51Z"
|
||||
},
|
||||
{
|
||||
"name": "semaphoreui/semaphore",
|
||||
"version": "v2.17.0-rc3",
|
||||
"date": "2026-01-15T21:30:26Z"
|
||||
},
|
||||
{
|
||||
"name": "azukaar/Cosmos-Server",
|
||||
"version": "v0.20.0",
|
||||
"date": "2026-01-15T20:59:44Z"
|
||||
},
|
||||
{
|
||||
"name": "runtipi/runtipi",
|
||||
"version": "nightly",
|
||||
"date": "2026-01-15T20:03:50Z"
|
||||
},
|
||||
{
|
||||
"name": "Stirling-Tools/Stirling-PDF",
|
||||
"version": "v2.3.0",
|
||||
"date": "2026-01-15T19:29:02Z"
|
||||
},
|
||||
{
|
||||
"name": "Comfy-Org/ComfyUI",
|
||||
"version": "v0.9.2",
|
||||
"date": "2026-01-15T17:55:40Z"
|
||||
},
|
||||
{
|
||||
"name": "zwave-js/zwave-js-ui",
|
||||
"version": "v11.10.1",
|
||||
@@ -359,26 +494,11 @@
|
||||
"version": "0.24.3",
|
||||
"date": "2026-01-15T14:40:15Z"
|
||||
},
|
||||
{
|
||||
"name": "openobserve/openobserve",
|
||||
"version": "v0.50.0-rc3",
|
||||
"date": "2026-01-15T13:57:37Z"
|
||||
},
|
||||
{
|
||||
"name": "readeck/readeck",
|
||||
"version": "0.21.6",
|
||||
"date": "2026-01-15T11:18:58Z"
|
||||
},
|
||||
{
|
||||
"name": "mattermost/mattermost",
|
||||
"version": "v10.11.10",
|
||||
"date": "2026-01-15T10:36:07Z"
|
||||
},
|
||||
{
|
||||
"name": "SigNoz/signoz",
|
||||
"version": "v0.107.0",
|
||||
"date": "2026-01-15T06:50:08Z"
|
||||
},
|
||||
{
|
||||
"name": "zitadel/zitadel",
|
||||
"version": "v4.9.1",
|
||||
@@ -429,11 +549,6 @@
|
||||
"version": "v3.3.1-rc2",
|
||||
"date": "2026-01-14T12:29:28Z"
|
||||
},
|
||||
{
|
||||
"name": "dedicatedcode/reitti",
|
||||
"version": "v3.3.0",
|
||||
"date": "2026-01-14T11:06:59Z"
|
||||
},
|
||||
{
|
||||
"name": "cloudreve/cloudreve",
|
||||
"version": "4.11.1",
|
||||
@@ -474,31 +589,6 @@
|
||||
"version": "v0.5.5",
|
||||
"date": "2026-01-13T17:03:32Z"
|
||||
},
|
||||
{
|
||||
"name": "element-hq/synapse",
|
||||
"version": "v1.145.0",
|
||||
"date": "2026-01-13T16:49:51Z"
|
||||
},
|
||||
{
|
||||
"name": "LimeSurvey/LimeSurvey",
|
||||
"version": "6.16.3+251215",
|
||||
"date": "2026-01-13T10:36:10Z"
|
||||
},
|
||||
{
|
||||
"name": "endurain-project/endurain",
|
||||
"version": "v0.16.6",
|
||||
"date": "2026-01-13T10:28:14Z"
|
||||
},
|
||||
{
|
||||
"name": "jenkinsci/jenkins",
|
||||
"version": "jenkins-2.546",
|
||||
"date": "2026-01-13T10:08:09Z"
|
||||
},
|
||||
{
|
||||
"name": "Luligu/matterbridge",
|
||||
"version": "3.4.7",
|
||||
"date": "2026-01-13T07:28:02Z"
|
||||
},
|
||||
{
|
||||
"name": "henrygd/beszel",
|
||||
"version": "v0.18.2",
|
||||
@@ -514,11 +604,6 @@
|
||||
"version": "26.1.1",
|
||||
"date": "2026-01-12T23:26:02Z"
|
||||
},
|
||||
{
|
||||
"name": "gtsteffaniak/filebrowser",
|
||||
"version": "v1.1.1-stable",
|
||||
"date": "2026-01-12T23:25:10Z"
|
||||
},
|
||||
{
|
||||
"name": "influxdata/influxdb",
|
||||
"version": "v2.8.0",
|
||||
@@ -534,11 +619,6 @@
|
||||
"version": "v1.7.10",
|
||||
"date": "2026-01-12T20:50:50Z"
|
||||
},
|
||||
{
|
||||
"name": "rcourtman/Pulse",
|
||||
"version": "v5.0.16",
|
||||
"date": "2026-01-12T20:18:34Z"
|
||||
},
|
||||
{
|
||||
"name": "release-argus/Argus",
|
||||
"version": "0.29.2",
|
||||
@@ -624,11 +704,6 @@
|
||||
"version": "v0.14.1",
|
||||
"date": "2024-08-29T22:32:51Z"
|
||||
},
|
||||
{
|
||||
"name": "theonedev/onedev",
|
||||
"version": "v14.0.7",
|
||||
"date": "2026-01-10T10:31:47Z"
|
||||
},
|
||||
{
|
||||
"name": "Kozea/Radicale",
|
||||
"version": "v3.6.0",
|
||||
@@ -709,21 +784,11 @@
|
||||
"version": "5.2.7",
|
||||
"date": "2026-01-07T23:48:00Z"
|
||||
},
|
||||
{
|
||||
"name": "prometheus/prometheus",
|
||||
"version": "v0.309.1",
|
||||
"date": "2026-01-07T19:20:52Z"
|
||||
},
|
||||
{
|
||||
"name": "leiweibau/Pi.Alert",
|
||||
"version": "v2026-01-07",
|
||||
"date": "2026-01-07T18:50:28Z"
|
||||
},
|
||||
{
|
||||
"name": "node-red/node-red",
|
||||
"version": "4.1.3",
|
||||
"date": "2026-01-07T16:24:23Z"
|
||||
},
|
||||
{
|
||||
"name": "MDeLuise/plant-it",
|
||||
"version": "1.0.1",
|
||||
@@ -759,11 +824,6 @@
|
||||
"version": "2.46.0",
|
||||
"date": "2026-01-07T00:19:31Z"
|
||||
},
|
||||
{
|
||||
"name": "netbox-community/netbox",
|
||||
"version": "v4.5.0",
|
||||
"date": "2026-01-06T21:14:27Z"
|
||||
},
|
||||
{
|
||||
"name": "caddyserver/caddy",
|
||||
"version": "v2.10.2",
|
||||
@@ -822,7 +882,7 @@
|
||||
{
|
||||
"name": "mealie-recipes/mealie",
|
||||
"version": "v3.9.2",
|
||||
"date": "2026-01-02T19:40:09Z"
|
||||
"date": "2026-01-02T19:40:19Z"
|
||||
},
|
||||
{
|
||||
"name": "gotify/server",
|
||||
@@ -849,11 +909,6 @@
|
||||
"version": "v25.12.1",
|
||||
"date": "2025-12-30T17:25:57Z"
|
||||
},
|
||||
{
|
||||
"name": "javedh-dev/tracktor",
|
||||
"version": "1.1.0",
|
||||
"date": "2025-12-30T04:42:18Z"
|
||||
},
|
||||
{
|
||||
"name": "ArchiveBox/ArchiveBox",
|
||||
"version": "v0.8.6rc1",
|
||||
@@ -874,16 +929,6 @@
|
||||
"version": "v4.7.0",
|
||||
"date": "2025-12-27T20:37:54Z"
|
||||
},
|
||||
{
|
||||
"name": "sysadminsmedia/homebox",
|
||||
"version": "v0.22.3",
|
||||
"date": "2025-12-26T22:31:20Z"
|
||||
},
|
||||
{
|
||||
"name": "HydroshieldMKII/Guardian",
|
||||
"version": "v1.3.3",
|
||||
"date": "2025-12-25T20:19:52Z"
|
||||
},
|
||||
{
|
||||
"name": "matze/wastebin",
|
||||
"version": "3.4.0",
|
||||
@@ -919,11 +964,6 @@
|
||||
"version": "v5.7",
|
||||
"date": "2025-12-23T14:53:51Z"
|
||||
},
|
||||
{
|
||||
"name": "nzbgetcom/nzbget",
|
||||
"version": "v25.4",
|
||||
"date": "2025-10-09T10:27:01Z"
|
||||
},
|
||||
{
|
||||
"name": "itsmng/itsm-ng",
|
||||
"version": "v1.6.11",
|
||||
@@ -944,16 +984,6 @@
|
||||
"version": "v4.0.16.2944",
|
||||
"date": "2025-11-05T01:56:48Z"
|
||||
},
|
||||
{
|
||||
"name": "chrisvel/tududi",
|
||||
"version": "v0.88.2",
|
||||
"date": "2025-12-22T14:36:59Z"
|
||||
},
|
||||
{
|
||||
"name": "passbolt/passbolt_api",
|
||||
"version": "v5.8.0",
|
||||
"date": "2025-12-22T10:12:48Z"
|
||||
},
|
||||
{
|
||||
"name": "benjaminjonard/koillection",
|
||||
"version": "1.7.1",
|
||||
@@ -1009,11 +1039,6 @@
|
||||
"version": "v1.25.3",
|
||||
"date": "2025-12-18T18:11:48Z"
|
||||
},
|
||||
{
|
||||
"name": "docker/compose",
|
||||
"version": "v5.0.1",
|
||||
"date": "2025-12-18T14:22:38Z"
|
||||
},
|
||||
{
|
||||
"name": "juanfont/headscale",
|
||||
"version": "v0.27.1",
|
||||
@@ -1034,11 +1059,6 @@
|
||||
"version": "v4.1.0",
|
||||
"date": "2025-12-15T18:53:25Z"
|
||||
},
|
||||
{
|
||||
"name": "rabbitmq/rabbitmq-server",
|
||||
"version": "v4.2.2",
|
||||
"date": "2025-12-15T18:25:36Z"
|
||||
},
|
||||
{
|
||||
"name": "docmost/docmost",
|
||||
"version": "v0.24.1",
|
||||
@@ -1059,11 +1079,6 @@
|
||||
"version": "v1.13.2",
|
||||
"date": "2025-12-13T22:59:03Z"
|
||||
},
|
||||
{
|
||||
"name": "diced/zipline",
|
||||
"version": "v4.4.0",
|
||||
"date": "2025-12-13T22:49:07Z"
|
||||
},
|
||||
{
|
||||
"name": "WGDashboard/WGDashboard",
|
||||
"version": "v4.3.1",
|
||||
@@ -1424,31 +1439,16 @@
|
||||
"version": "v2.2.2",
|
||||
"date": "2025-10-06T21:31:07Z"
|
||||
},
|
||||
{
|
||||
"name": "mysql/mysql-server",
|
||||
"version": "mysql-cluster-7.6.36",
|
||||
"date": "2025-10-06T15:19:49Z"
|
||||
},
|
||||
{
|
||||
"name": "jordan-dalby/ByteStash",
|
||||
"version": "v1.5.9",
|
||||
"date": "2025-10-06T08:34:01Z"
|
||||
},
|
||||
{
|
||||
"name": "donetick/donetick",
|
||||
"version": "v0.1.64",
|
||||
"date": "2025-10-03T05:18:24Z"
|
||||
},
|
||||
{
|
||||
"name": "thomiceli/opengist",
|
||||
"version": "v1.11.1",
|
||||
"date": "2025-09-30T00:24:16Z"
|
||||
},
|
||||
{
|
||||
"name": "lazy-media/Reactive-Resume",
|
||||
"version": "v1.2.6",
|
||||
"date": "2025-09-28T18:09:21Z"
|
||||
},
|
||||
{
|
||||
"name": "Pf2eToolsOrg/Pf2eTools",
|
||||
"version": "v0.10.1",
|
||||
|
||||
50
install/byparr-install.sh
Normal file
50
install/byparr-install.sh
Normal file
@@ -0,0 +1,50 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: luismco
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://github.com/ThePhaseless/Byparr
|
||||
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
color
|
||||
verb_ip6
|
||||
catch_errors
|
||||
setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
|
||||
msg_info "Installing Dependencies"
|
||||
$STD apt -y install \
|
||||
xauth \
|
||||
xvfb \
|
||||
scrot \
|
||||
chromium \
|
||||
chromium-driver \
|
||||
ca-certificates
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
fetch_and_deploy_gh_release "Byparr" "ThePhaseless/Byparr" "tarball" "latest"
|
||||
setup_uv
|
||||
|
||||
msg_info "Creating Service"
|
||||
cat <<EOF >/etc/systemd/system/byparr.service
|
||||
[Unit]
|
||||
Description=Byparr
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
WorkingDirectory=/opt/Byparr
|
||||
ExecStart=/usr/local/bin/uv run python3 main.py
|
||||
Restart=on-failure
|
||||
RestartSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
systemctl enable -q --now byparr
|
||||
msg_ok "Created Service"
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
@@ -21,9 +21,6 @@ rm -rf /opt/checkmk.deb
|
||||
echo "${RELEASE}" >"/opt/checkmk_version.txt"
|
||||
msg_ok "Installed Checkmk"
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
|
||||
msg_info "Creating Service"
|
||||
SITE_NAME="monitoring"
|
||||
$STD omd create "$SITE_NAME"
|
||||
@@ -42,3 +39,5 @@ $STD omd start "$SITE_NAME"
|
||||
msg_ok "Created Service"
|
||||
|
||||
cleanup_lxc
|
||||
motd_ssh
|
||||
customize
|
||||
|
||||
@@ -34,7 +34,7 @@ msg_info "Setup Dolibarr"
|
||||
BASE="https://sourceforge.net/projects/dolibarr/files/Dolibarr%20installer%20for%20Debian-Ubuntu%20(DoliDeb)/"
|
||||
RELEASE=$(curl -fsSL "$BASE" | grep -oP '(?<=/Dolibarr%20installer%20for%20Debian-Ubuntu%20%28DoliDeb%29/)\d+(\.\d+)+(?=/)' | sort -V | tail -n1)
|
||||
FILE=$(curl -fsSL "${BASE}${RELEASE}/" | grep -oP 'dolibarr_[^"]+_all.deb' | head -n1)
|
||||
curl -fsSL "https://netcologne.dl.sourceforge.net/project/dolibarr/Dolibarr%20installer%20for%20Debian-Ubuntu%20(DoliDeb)/${RELEASE}/${FILE}?viasf=1" -o ""$FILE""
|
||||
curl -fsSL "https://altushost-swe.dl.sourceforge.net/project/dolibarr/Dolibarr%20installer%20for%20Debian-Ubuntu%20(DoliDeb)/${RELEASE}/${FILE}?viasf=1" -o ""$FILE""
|
||||
echo "dolibarr dolibarr/reconfigure-webserver multiselect apache2" | debconf-set-selections
|
||||
$STD apt-get install ./$FILE -y
|
||||
$STD apt install -f
|
||||
|
||||
@@ -36,8 +36,9 @@ cd /opt/joplin-server
|
||||
sed -i "/onenote-converter/d" packages/lib/package.json
|
||||
$STD yarn config set --home enableTelemetry 0
|
||||
export BUILD_SEQUENCIAL=1
|
||||
$STD yarn install --inline-builds
|
||||
|
||||
$STD yarn workspaces focus @joplin/server
|
||||
$STD yarn workspaces foreach -R --topological-dev --from @joplin/server run build
|
||||
$STD yarn workspaces foreach -R --topological-dev --from @joplin/server run tsc
|
||||
cat <<EOF >/opt/joplin-server/.env
|
||||
PM2_HOME=/opt/pm2
|
||||
NODE_ENV=production
|
||||
|
||||
@@ -59,7 +59,7 @@ msg_ok "Installed Python Dependencies"
|
||||
msg_info "Creating Service"
|
||||
cat <<EOF >/opt/yubal.env
|
||||
YUBAL_HOST=0.0.0.0
|
||||
YUBAL_PORT=8001
|
||||
YUBAL_PORT=8000
|
||||
YUBAL_DATA=/opt/yubal_data
|
||||
YUBAL_CONFIG=/opt/yubal_config
|
||||
YUBAL_ROOT=/opt/yubal
|
||||
@@ -76,7 +76,7 @@ User=root
|
||||
WorkingDirectory=/opt/yubal
|
||||
EnvironmentFile=/opt/yubal.env
|
||||
Environment="PATH=/opt/yubal/.venv/bin:/usr/local/bin:/usr/bin:/bin"
|
||||
ExecStart=/opt/yubal/.venv/bin/python -m yubal
|
||||
ExecStart=/opt/yubal/.venv/bin/python -m yubal_api
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
|
||||
647
misc/build.func
647
misc/build.func
@@ -357,6 +357,268 @@ validate_hostname() {
|
||||
return 0
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# validate_mac_address()
|
||||
#
|
||||
# - Validates MAC address format (XX:XX:XX:XX:XX:XX)
|
||||
# - Empty value is allowed (auto-generated)
|
||||
# - Returns 0 if valid, 1 if invalid
|
||||
# ------------------------------------------------------------------------------
|
||||
validate_mac_address() {
|
||||
local mac="$1"
|
||||
[[ -z "$mac" ]] && return 0
|
||||
if [[ ! "$mac" =~ ^([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}$ ]]; then
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# validate_vlan_tag()
|
||||
#
|
||||
# - Validates VLAN tag (1-4094)
|
||||
# - Empty value is allowed (no VLAN)
|
||||
# - Returns 0 if valid, 1 if invalid
|
||||
# ------------------------------------------------------------------------------
|
||||
validate_vlan_tag() {
|
||||
local vlan="$1"
|
||||
[[ -z "$vlan" ]] && return 0
|
||||
if ! [[ "$vlan" =~ ^[0-9]+$ ]] || ((vlan < 1 || vlan > 4094)); then
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# validate_mtu()
|
||||
#
|
||||
# - Validates MTU size (576-65535, common values: 1500, 9000)
|
||||
# - Empty value is allowed (default 1500)
|
||||
# - Returns 0 if valid, 1 if invalid
|
||||
# ------------------------------------------------------------------------------
|
||||
validate_mtu() {
|
||||
local mtu="$1"
|
||||
[[ -z "$mtu" ]] && return 0
|
||||
if ! [[ "$mtu" =~ ^[0-9]+$ ]] || ((mtu < 576 || mtu > 65535)); then
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# validate_ipv6_address()
|
||||
#
|
||||
# - Validates IPv6 address with optional CIDR notation
|
||||
# - Supports compressed (::) and full notation
|
||||
# - Empty value is allowed
|
||||
# - Returns 0 if valid, 1 if invalid
|
||||
# ------------------------------------------------------------------------------
|
||||
validate_ipv6_address() {
|
||||
local ipv6="$1"
|
||||
[[ -z "$ipv6" ]] && return 0
|
||||
|
||||
# Extract address and CIDR
|
||||
local addr="${ipv6%%/*}"
|
||||
local cidr="${ipv6##*/}"
|
||||
|
||||
# Validate CIDR if present (1-128)
|
||||
if [[ "$ipv6" == */* ]]; then
|
||||
if ! [[ "$cidr" =~ ^[0-9]+$ ]] || ((cidr < 1 || cidr > 128)); then
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Basic IPv6 validation - check for valid characters and structure
|
||||
# Must contain only hex digits and colons
|
||||
if [[ ! "$addr" =~ ^[0-9a-fA-F:]+$ ]]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Must contain at least one colon
|
||||
if [[ ! "$addr" == *:* ]]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check for valid double-colon usage (only one :: allowed)
|
||||
if [[ "$addr" == *::*::* ]]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check that no segment exceeds 4 hex chars
|
||||
local IFS=':'
|
||||
local -a segments
|
||||
read -ra segments <<< "$addr"
|
||||
for seg in "${segments[@]}"; do
|
||||
if [[ ${#seg} -gt 4 ]]; then
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# validate_bridge()
|
||||
#
|
||||
# - Validates that network bridge exists and is active
|
||||
# - Returns 0 if valid, 1 if invalid
|
||||
# ------------------------------------------------------------------------------
|
||||
validate_bridge() {
|
||||
local bridge="$1"
|
||||
[[ -z "$bridge" ]] && return 1
|
||||
|
||||
# Check if bridge interface exists
|
||||
if ! ip link show "$bridge" &>/dev/null; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# validate_gateway_in_subnet()
|
||||
#
|
||||
# - Validates that gateway IP is in the same subnet as static IP
|
||||
# - Arguments: static_ip (with CIDR), gateway_ip
|
||||
# - Returns 0 if valid, 1 if invalid
|
||||
# ------------------------------------------------------------------------------
|
||||
validate_gateway_in_subnet() {
|
||||
local static_ip="$1"
|
||||
local gateway="$2"
|
||||
|
||||
[[ -z "$static_ip" || -z "$gateway" ]] && return 0
|
||||
|
||||
# Extract IP and CIDR
|
||||
local ip="${static_ip%%/*}"
|
||||
local cidr="${static_ip##*/}"
|
||||
|
||||
# Convert CIDR to netmask bits
|
||||
local mask=$((0xFFFFFFFF << (32 - cidr) & 0xFFFFFFFF))
|
||||
|
||||
# Convert IPs to integers
|
||||
local IFS='.'
|
||||
read -r i1 i2 i3 i4 <<< "$ip"
|
||||
read -r g1 g2 g3 g4 <<< "$gateway"
|
||||
|
||||
local ip_int=$(( (i1 << 24) + (i2 << 16) + (i3 << 8) + i4 ))
|
||||
local gw_int=$(( (g1 << 24) + (g2 << 16) + (g3 << 8) + g4 ))
|
||||
|
||||
# Check if both are in same network
|
||||
if (( (ip_int & mask) != (gw_int & mask) )); then
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# validate_ip_address()
|
||||
#
|
||||
# - Validates IPv4 address with CIDR notation
|
||||
# - Checks each octet is 0-255
|
||||
# - Checks CIDR is 1-32
|
||||
# - Returns 0 if valid, 1 if invalid
|
||||
# ------------------------------------------------------------------------------
|
||||
validate_ip_address() {
|
||||
local ip="$1"
|
||||
[[ -z "$ip" ]] && return 1
|
||||
|
||||
# Check format with CIDR
|
||||
if [[ ! "$ip" =~ ^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})/([0-9]{1,2})$ ]]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
local o1="${BASH_REMATCH[1]}"
|
||||
local o2="${BASH_REMATCH[2]}"
|
||||
local o3="${BASH_REMATCH[3]}"
|
||||
local o4="${BASH_REMATCH[4]}"
|
||||
local cidr="${BASH_REMATCH[5]}"
|
||||
|
||||
# Validate octets (0-255)
|
||||
for octet in "$o1" "$o2" "$o3" "$o4"; do
|
||||
if ((octet > 255)); then
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
|
||||
# Validate CIDR (1-32)
|
||||
if ((cidr < 1 || cidr > 32)); then
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# validate_gateway_ip()
|
||||
#
|
||||
# - Validates gateway IPv4 address (without CIDR)
|
||||
# - Checks each octet is 0-255
|
||||
# - Returns 0 if valid, 1 if invalid
|
||||
# ------------------------------------------------------------------------------
|
||||
validate_gateway_ip() {
|
||||
local ip="$1"
|
||||
[[ -z "$ip" ]] && return 0
|
||||
|
||||
# Check format without CIDR
|
||||
if [[ ! "$ip" =~ ^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$ ]]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
local o1="${BASH_REMATCH[1]}"
|
||||
local o2="${BASH_REMATCH[2]}"
|
||||
local o3="${BASH_REMATCH[3]}"
|
||||
local o4="${BASH_REMATCH[4]}"
|
||||
|
||||
# Validate octets (0-255)
|
||||
for octet in "$o1" "$o2" "$o3" "$o4"; do
|
||||
if ((octet > 255)); then
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# validate_timezone()
|
||||
#
|
||||
# - Validates timezone string against system zoneinfo
|
||||
# - Empty value or "host" is allowed
|
||||
# - Returns 0 if valid, 1 if invalid
|
||||
# ------------------------------------------------------------------------------
|
||||
validate_timezone() {
|
||||
local tz="$1"
|
||||
[[ -z "$tz" || "$tz" == "host" ]] && return 0
|
||||
|
||||
# Check if timezone file exists
|
||||
if [[ ! -f "/usr/share/zoneinfo/$tz" ]]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# validate_tags()
|
||||
#
|
||||
# - Validates Proxmox tags format
|
||||
# - Only alphanumeric, hyphens, underscores, and semicolons allowed
|
||||
# - Empty value is allowed
|
||||
# - Returns 0 if valid, 1 if invalid
|
||||
# ------------------------------------------------------------------------------
|
||||
validate_tags() {
|
||||
local tags="$1"
|
||||
[[ -z "$tags" ]] && return 0
|
||||
|
||||
# Tags can only contain alphanumeric, -, _, and ; (separator)
|
||||
if [[ ! "$tags" =~ ^[a-zA-Z0-9_\;-]+$ ]]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# find_host_ssh_keys()
|
||||
#
|
||||
@@ -772,6 +1034,119 @@ load_vars_file() {
|
||||
# Trim trailing whitespace
|
||||
var_val="${var_val%"${var_val##*[![:space:]]}"}"
|
||||
|
||||
# Validate values before setting (skip empty values - they use defaults)
|
||||
if [[ -n "$var_val" ]]; then
|
||||
case "$var_key" in
|
||||
var_mac)
|
||||
if ! validate_mac_address "$var_val"; then
|
||||
msg_warn "Invalid MAC address '$var_val' in $file, ignoring"
|
||||
continue
|
||||
fi
|
||||
;;
|
||||
var_vlan)
|
||||
if ! validate_vlan_tag "$var_val"; then
|
||||
msg_warn "Invalid VLAN tag '$var_val' in $file (must be 1-4094), ignoring"
|
||||
continue
|
||||
fi
|
||||
;;
|
||||
var_mtu)
|
||||
if ! validate_mtu "$var_val"; then
|
||||
msg_warn "Invalid MTU '$var_val' in $file (must be 576-65535), ignoring"
|
||||
continue
|
||||
fi
|
||||
;;
|
||||
var_tags)
|
||||
if ! validate_tags "$var_val"; then
|
||||
msg_warn "Invalid tags '$var_val' in $file (alphanumeric, -, _, ; only), ignoring"
|
||||
continue
|
||||
fi
|
||||
;;
|
||||
var_timezone)
|
||||
if ! validate_timezone "$var_val"; then
|
||||
msg_warn "Invalid timezone '$var_val' in $file, ignoring"
|
||||
continue
|
||||
fi
|
||||
;;
|
||||
var_brg)
|
||||
if ! validate_bridge "$var_val"; then
|
||||
msg_warn "Bridge '$var_val' not found in $file, ignoring"
|
||||
continue
|
||||
fi
|
||||
;;
|
||||
var_gateway)
|
||||
if ! validate_gateway_ip "$var_val"; then
|
||||
msg_warn "Invalid gateway IP '$var_val' in $file, ignoring"
|
||||
continue
|
||||
fi
|
||||
;;
|
||||
var_hostname)
|
||||
if ! validate_hostname "$var_val"; then
|
||||
msg_warn "Invalid hostname '$var_val' in $file, ignoring"
|
||||
continue
|
||||
fi
|
||||
;;
|
||||
var_cpu)
|
||||
if ! [[ "$var_val" =~ ^[0-9]+$ ]] || ((var_val < 1 || var_val > 128)); then
|
||||
msg_warn "Invalid CPU count '$var_val' in $file (must be 1-128), ignoring"
|
||||
continue
|
||||
fi
|
||||
;;
|
||||
var_ram)
|
||||
if ! [[ "$var_val" =~ ^[0-9]+$ ]] || ((var_val < 256)); then
|
||||
msg_warn "Invalid RAM '$var_val' in $file (must be >= 256 MiB), ignoring"
|
||||
continue
|
||||
fi
|
||||
;;
|
||||
var_disk)
|
||||
if ! [[ "$var_val" =~ ^[0-9]+$ ]] || ((var_val < 1)); then
|
||||
msg_warn "Invalid disk size '$var_val' in $file (must be >= 1 GB), ignoring"
|
||||
continue
|
||||
fi
|
||||
;;
|
||||
var_unprivileged)
|
||||
if [[ "$var_val" != "0" && "$var_val" != "1" ]]; then
|
||||
msg_warn "Invalid unprivileged value '$var_val' in $file (must be 0 or 1), ignoring"
|
||||
continue
|
||||
fi
|
||||
;;
|
||||
var_nesting)
|
||||
if [[ "$var_val" != "0" && "$var_val" != "1" ]]; then
|
||||
msg_warn "Invalid nesting value '$var_val' in $file (must be 0 or 1), ignoring"
|
||||
continue
|
||||
fi
|
||||
;;
|
||||
var_keyctl)
|
||||
if [[ "$var_val" != "0" && "$var_val" != "1" ]]; then
|
||||
msg_warn "Invalid keyctl value '$var_val' in $file (must be 0 or 1), ignoring"
|
||||
continue
|
||||
fi
|
||||
;;
|
||||
var_net)
|
||||
# var_net can be: dhcp, static IP/CIDR, or IP range
|
||||
if [[ "$var_val" != "dhcp" ]]; then
|
||||
if is_ip_range "$var_val"; then
|
||||
: # IP range is valid, will be resolved at runtime
|
||||
elif ! validate_ip_address "$var_val"; then
|
||||
msg_warn "Invalid network '$var_val' in $file (must be dhcp or IP/CIDR), ignoring"
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
var_fuse|var_tun|var_gpu|var_ssh|var_verbose|var_protection)
|
||||
if [[ "$var_val" != "yes" && "$var_val" != "no" ]]; then
|
||||
msg_warn "Invalid boolean '$var_val' for $var_key in $file (must be yes/no), ignoring"
|
||||
continue
|
||||
fi
|
||||
;;
|
||||
var_ipv6_method)
|
||||
if [[ "$var_val" != "auto" && "$var_val" != "dhcp" && "$var_val" != "static" && "$var_val" != "none" ]]; then
|
||||
msg_warn "Invalid IPv6 method '$var_val' in $file (must be auto/dhcp/static/none), ignoring"
|
||||
continue
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Set variable: force mode overrides existing, otherwise only set if empty
|
||||
if [[ "$force" == "yes" ]]; then
|
||||
export "${var_key}=${var_val}"
|
||||
@@ -1612,8 +1987,14 @@ advanced_settings() {
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
8)
|
||||
if [[ ${#BRIDGE_MENU_OPTIONS[@]} -eq 0 ]]; then
|
||||
_bridge="vmbr0"
|
||||
((STEP++))
|
||||
# Validate default bridge exists
|
||||
if validate_bridge "vmbr0"; then
|
||||
_bridge="vmbr0"
|
||||
((STEP++))
|
||||
else
|
||||
whiptail --msgbox "Default bridge 'vmbr0' not found!\n\nPlease configure a network bridge in Proxmox first." 10 58
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \
|
||||
--title "NETWORK BRIDGE" \
|
||||
@@ -1621,8 +2002,13 @@ advanced_settings() {
|
||||
--menu "\nSelect network bridge:" 16 58 6 \
|
||||
"${BRIDGE_MENU_OPTIONS[@]}" \
|
||||
3>&1 1>&2 2>&3); then
|
||||
_bridge="${result:-vmbr0}"
|
||||
((STEP++))
|
||||
local bridge_test="${result:-vmbr0}"
|
||||
if validate_bridge "$bridge_test"; then
|
||||
_bridge="$bridge_test"
|
||||
((STEP++))
|
||||
else
|
||||
whiptail --msgbox "Bridge '$bridge_test' is not available or not active." 8 58
|
||||
fi
|
||||
else
|
||||
((STEP--))
|
||||
fi
|
||||
@@ -1650,7 +2036,7 @@ advanced_settings() {
|
||||
--ok-button "Next" --cancel-button "Back" \
|
||||
--inputbox "\nEnter Static IPv4 CIDR Address\n(e.g. 192.168.1.100/24)" 12 58 "" \
|
||||
3>&1 1>&2 2>&3); then
|
||||
if [[ "$static_ip" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}/([0-9]|[1-2][0-9]|3[0-2])$ ]]; then
|
||||
if validate_ip_address "$static_ip"; then
|
||||
# Get gateway
|
||||
local gateway_ip
|
||||
if gateway_ip=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \
|
||||
@@ -1658,16 +2044,21 @@ advanced_settings() {
|
||||
--ok-button "Next" --cancel-button "Back" \
|
||||
--inputbox "\nEnter Gateway IP address" 10 58 "" \
|
||||
3>&1 1>&2 2>&3); then
|
||||
if [[ "$gateway_ip" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
|
||||
_net="$static_ip"
|
||||
_gate=",gw=$gateway_ip"
|
||||
((STEP++))
|
||||
if validate_gateway_ip "$gateway_ip"; then
|
||||
# Validate gateway is in same subnet
|
||||
if validate_gateway_in_subnet "$static_ip" "$gateway_ip"; then
|
||||
_net="$static_ip"
|
||||
_gate=",gw=$gateway_ip"
|
||||
((STEP++))
|
||||
else
|
||||
whiptail --msgbox "Gateway is not in the same subnet as the static IP.\n\nStatic IP: $static_ip\nGateway: $gateway_ip" 10 58
|
||||
fi
|
||||
else
|
||||
whiptail --msgbox "Invalid Gateway IP format." 8 58
|
||||
whiptail --msgbox "Invalid Gateway IP format.\n\nEach octet must be 0-255.\nExample: 192.168.1.1" 10 58
|
||||
fi
|
||||
fi
|
||||
else
|
||||
whiptail --msgbox "Invalid IPv4 CIDR format.\nExample: 192.168.1.100/24" 8 58
|
||||
whiptail --msgbox "Invalid IPv4 CIDR format.\n\nEach octet must be 0-255.\nCIDR must be 1-32.\nExample: 192.168.1.100/24" 12 58
|
||||
fi
|
||||
fi
|
||||
elif [[ "$result" == "range" ]]; then
|
||||
@@ -1691,12 +2082,17 @@ advanced_settings() {
|
||||
--ok-button "Next" --cancel-button "Back" \
|
||||
--inputbox "\nFound free IP: $NET_RESOLVED\n\nEnter Gateway IP address" 12 58 "" \
|
||||
3>&1 1>&2 2>&3); then
|
||||
if [[ "$gateway_ip" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
|
||||
_net="$NET_RESOLVED"
|
||||
_gate=",gw=$gateway_ip"
|
||||
((STEP++))
|
||||
if validate_gateway_ip "$gateway_ip"; then
|
||||
# Validate gateway is in same subnet
|
||||
if validate_gateway_in_subnet "$NET_RESOLVED" "$gateway_ip"; then
|
||||
_net="$NET_RESOLVED"
|
||||
_gate=",gw=$gateway_ip"
|
||||
((STEP++))
|
||||
else
|
||||
whiptail --msgbox "Gateway is not in the same subnet as the IP.\n\nIP: $NET_RESOLVED\nGateway: $gateway_ip" 10 58
|
||||
fi
|
||||
else
|
||||
whiptail --msgbox "Invalid Gateway IP format." 8 58
|
||||
whiptail --msgbox "Invalid Gateway IP format.\n\nEach octet must be 0-255.\nExample: 192.168.1.1" 10 58
|
||||
fi
|
||||
fi
|
||||
else
|
||||
@@ -1739,16 +2135,33 @@ advanced_settings() {
|
||||
--title "STATIC IPv6 ADDRESS" \
|
||||
--inputbox "\nEnter IPv6 CIDR address\n(e.g. 2001:db8::1/64)" 12 58 "" \
|
||||
3>&1 1>&2 2>&3); then
|
||||
if [[ "$ipv6_addr" =~ ^([0-9a-fA-F:]+:+)+[0-9a-fA-F]+(/[0-9]{1,3})$ ]]; then
|
||||
if validate_ipv6_address "$ipv6_addr"; then
|
||||
_ipv6_addr="$ipv6_addr"
|
||||
# Optional gateway
|
||||
_ipv6_gate=$(whiptail --backtitle "Proxmox VE Helper Scripts" \
|
||||
--title "IPv6 GATEWAY" \
|
||||
--inputbox "\nEnter IPv6 gateway (optional, leave blank for none)" 10 58 "" \
|
||||
3>&1 1>&2 2>&3) || true
|
||||
((STEP++))
|
||||
# Optional gateway - loop until valid or empty
|
||||
local ipv6_gw_valid=false
|
||||
while [[ "$ipv6_gw_valid" == "false" ]]; do
|
||||
local ipv6_gw
|
||||
ipv6_gw=$(whiptail --backtitle "Proxmox VE Helper Scripts" \
|
||||
--title "IPv6 GATEWAY" \
|
||||
--inputbox "\nEnter IPv6 gateway (optional, leave blank for none)" 10 58 "" \
|
||||
3>&1 1>&2 2>&3) || true
|
||||
# Validate gateway if provided
|
||||
if [[ -n "$ipv6_gw" ]]; then
|
||||
if validate_ipv6_address "$ipv6_gw"; then
|
||||
_ipv6_gate="$ipv6_gw"
|
||||
ipv6_gw_valid=true
|
||||
((STEP++))
|
||||
else
|
||||
whiptail --msgbox "Invalid IPv6 gateway format.\n\nExample: 2001:db8::1" 8 58
|
||||
fi
|
||||
else
|
||||
_ipv6_gate=""
|
||||
ipv6_gw_valid=true
|
||||
((STEP++))
|
||||
fi
|
||||
done
|
||||
else
|
||||
whiptail --msgbox "Invalid IPv6 CIDR format." 8 58
|
||||
whiptail --msgbox "Invalid IPv6 CIDR format.\n\nExample: 2001:db8::1/64\nCIDR must be 1-128." 10 58
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
@@ -1781,10 +2194,14 @@ advanced_settings() {
|
||||
if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \
|
||||
--title "MTU SIZE" \
|
||||
--ok-button "Next" --cancel-button "Back" \
|
||||
--inputbox "\nSet Interface MTU Size\n(leave blank for default 1500)" 12 58 "" \
|
||||
--inputbox "\nSet Interface MTU Size\n(leave blank for default 1500, common values: 1500, 9000)" 12 62 "" \
|
||||
3>&1 1>&2 2>&3); then
|
||||
_mtu="$result"
|
||||
((STEP++))
|
||||
if validate_mtu "$result"; then
|
||||
_mtu="$result"
|
||||
((STEP++))
|
||||
else
|
||||
whiptail --msgbox "Invalid MTU size.\n\nMTU must be between 576 and 65535.\nCommon values: 1500 (default), 9000 (jumbo frames)" 10 58
|
||||
fi
|
||||
else
|
||||
((STEP--))
|
||||
fi
|
||||
@@ -1829,10 +2246,14 @@ advanced_settings() {
|
||||
if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \
|
||||
--title "MAC ADDRESS" \
|
||||
--ok-button "Next" --cancel-button "Back" \
|
||||
--inputbox "\nSet MAC Address\n(leave blank for auto-generated)" 12 58 "" \
|
||||
--inputbox "\nSet MAC Address\n(leave blank for auto-generated, format: XX:XX:XX:XX:XX:XX)" 12 62 "" \
|
||||
3>&1 1>&2 2>&3); then
|
||||
_mac="$result"
|
||||
((STEP++))
|
||||
if validate_mac_address "$result"; then
|
||||
_mac="$result"
|
||||
((STEP++))
|
||||
else
|
||||
whiptail --msgbox "Invalid MAC address format.\n\nRequired format: XX:XX:XX:XX:XX:XX\nExample: 02:00:00:00:00:01" 10 58
|
||||
fi
|
||||
else
|
||||
((STEP--))
|
||||
fi
|
||||
@@ -1845,10 +2266,14 @@ advanced_settings() {
|
||||
if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \
|
||||
--title "VLAN TAG" \
|
||||
--ok-button "Next" --cancel-button "Back" \
|
||||
--inputbox "\nSet VLAN Tag\n(leave blank for no VLAN)" 12 58 "" \
|
||||
--inputbox "\nSet VLAN Tag (1-4094)\n(leave blank for no VLAN)" 12 58 "" \
|
||||
3>&1 1>&2 2>&3); then
|
||||
_vlan="$result"
|
||||
((STEP++))
|
||||
if validate_vlan_tag "$result"; then
|
||||
_vlan="$result"
|
||||
((STEP++))
|
||||
else
|
||||
whiptail --msgbox "Invalid VLAN tag.\n\nVLAN must be a number between 1 and 4094." 8 58
|
||||
fi
|
||||
else
|
||||
((STEP--))
|
||||
fi
|
||||
@@ -1861,11 +2286,16 @@ advanced_settings() {
|
||||
if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \
|
||||
--title "CONTAINER TAGS" \
|
||||
--ok-button "Next" --cancel-button "Back" \
|
||||
--inputbox "\nSet Custom Tags (semicolon-separated)\n(remove all for no tags)" 12 58 "$_tags" \
|
||||
--inputbox "\nSet Custom Tags (semicolon-separated)\n(alphanumeric, hyphens, underscores only)" 12 58 "$_tags" \
|
||||
3>&1 1>&2 2>&3); then
|
||||
_tags="${result:-;}"
|
||||
_tags=$(echo "$_tags" | tr -d '[:space:]')
|
||||
((STEP++))
|
||||
local tags_test="${result:-}"
|
||||
tags_test=$(echo "$tags_test" | tr -d '[:space:]')
|
||||
if validate_tags "$tags_test"; then
|
||||
_tags="$tags_test"
|
||||
((STEP++))
|
||||
else
|
||||
whiptail --msgbox "Invalid tag format.\n\nTags can only contain:\n- Letters (a-z, A-Z)\n- Numbers (0-9)\n- Hyphens (-)\n- Underscores (_)\n- Semicolons (;) as separator" 14 58
|
||||
fi
|
||||
else
|
||||
((STEP--))
|
||||
fi
|
||||
@@ -2044,9 +2474,14 @@ advanced_settings() {
|
||||
--ok-button "Next" --cancel-button "Back" \
|
||||
--inputbox "\nSet container timezone.\n\nExamples: Europe/Berlin, America/New_York, Asia/Tokyo\n\nHost timezone: ${_host_timezone:-unknown}\n\nLeave empty to inherit from host." 16 62 "$_ct_timezone" \
|
||||
3>&1 1>&2 2>&3); then
|
||||
_ct_timezone="$result"
|
||||
[[ "${_ct_timezone:-}" == Etc/* ]] && _ct_timezone="host" # pct doesn't accept Etc/* zones
|
||||
((STEP++))
|
||||
local tz_test="$result"
|
||||
[[ "${tz_test:-}" == Etc/* ]] && tz_test="host" # pct doesn't accept Etc/* zones
|
||||
if validate_timezone "$tz_test"; then
|
||||
_ct_timezone="$tz_test"
|
||||
((STEP++))
|
||||
else
|
||||
whiptail --msgbox "Invalid timezone: '$result'\n\nTimezone must exist in /usr/share/zoneinfo/\n\nExamples:\n- Europe/Berlin\n- America/New_York\n- Asia/Tokyo\n- UTC" 14 58
|
||||
fi
|
||||
else
|
||||
((STEP--))
|
||||
fi
|
||||
@@ -2843,6 +3278,7 @@ start() {
|
||||
elif [ ! -z ${PHS_SILENT+x} ] && [[ "${PHS_SILENT}" == "1" ]]; then
|
||||
VERBOSE="no"
|
||||
set_std_mode
|
||||
ensure_profile_loaded
|
||||
update_script
|
||||
cleanup_lxc
|
||||
else
|
||||
@@ -2868,6 +3304,7 @@ start() {
|
||||
exit
|
||||
;;
|
||||
esac
|
||||
ensure_profile_loaded
|
||||
update_script
|
||||
cleanup_lxc
|
||||
fi
|
||||
@@ -3005,8 +3442,13 @@ build_container() {
|
||||
export DEV_MODE_DRYRUN="${DEV_MODE_DRYRUN:-false}"
|
||||
|
||||
# Build PCT_OPTIONS as multi-line string
|
||||
PCT_OPTIONS_STRING=" -hostname $HN
|
||||
PCT_OPTIONS_STRING=" -hostname $HN"
|
||||
|
||||
# Only add -tags if TAGS is not empty
|
||||
if [ -n "$TAGS" ]; then
|
||||
PCT_OPTIONS_STRING="$PCT_OPTIONS_STRING
|
||||
-tags $TAGS"
|
||||
fi
|
||||
|
||||
# Only add -features if FEATURES is not empty
|
||||
if [ -n "$FEATURES" ]; then
|
||||
@@ -4036,37 +4478,42 @@ create_lxc_container() {
|
||||
|
||||
msg_info "Searching for template '$TEMPLATE_SEARCH'"
|
||||
|
||||
# Initialize variables
|
||||
ONLINE_TEMPLATE=""
|
||||
ONLINE_TEMPLATES=()
|
||||
|
||||
# Step 1: Check local templates first (instant)
|
||||
mapfile -t LOCAL_TEMPLATES < <(
|
||||
pveam list "$TEMPLATE_STORAGE" 2>/dev/null |
|
||||
awk -v search="${TEMPLATE_SEARCH}" -v pattern="${TEMPLATE_PATTERN}" '$1 ~ search && $1 ~ pattern {print $1}' |
|
||||
sed 's|.*/||' | sort -t - -k 2 -V
|
||||
)
|
||||
|
||||
pveam update >/dev/null 2>&1 || msg_warn "Could not update template catalog (pveam update failed)."
|
||||
|
||||
msg_ok "Template search completed"
|
||||
|
||||
set +u
|
||||
mapfile -t ONLINE_TEMPLATES < <(pveam available -section system 2>/dev/null | grep -E '\.(tar\.zst|tar\.xz|tar\.gz)$' | awk '{print $2}' | grep -E "^${TEMPLATE_SEARCH}.*${TEMPLATE_PATTERN}" | sort -t - -k 2 -V 2>/dev/null || true)
|
||||
set -u
|
||||
|
||||
ONLINE_TEMPLATE=""
|
||||
[[ ${#ONLINE_TEMPLATES[@]} -gt 0 ]] && ONLINE_TEMPLATE="${ONLINE_TEMPLATES[-1]}"
|
||||
|
||||
if [[ ${#ONLINE_TEMPLATES[@]} -gt 0 ]]; then
|
||||
count=0
|
||||
for idx in "${!ONLINE_TEMPLATES[@]}"; do
|
||||
((count++))
|
||||
[[ $count -ge 3 ]] && break
|
||||
done
|
||||
fi
|
||||
|
||||
# Step 2: If local template found, use it immediately (skip pveam update)
|
||||
if [[ ${#LOCAL_TEMPLATES[@]} -gt 0 ]]; then
|
||||
TEMPLATE="${LOCAL_TEMPLATES[-1]}"
|
||||
TEMPLATE_SOURCE="local"
|
||||
msg_ok "Template search completed"
|
||||
else
|
||||
# Step 3: No local template - need to check online (this may be slow)
|
||||
msg_info "No local template found, checking online catalog..."
|
||||
|
||||
# Update catalog with timeout to prevent long hangs
|
||||
if command -v timeout &>/dev/null; then
|
||||
if ! timeout 30 pveam update >/dev/null 2>&1; then
|
||||
msg_warn "Template catalog update timed out (possible network/DNS issue). Run 'pveam update' manually to diagnose."
|
||||
fi
|
||||
else
|
||||
pveam update >/dev/null 2>&1 || msg_warn "Could not update template catalog (pveam update failed)"
|
||||
fi
|
||||
|
||||
ONLINE_TEMPLATES=()
|
||||
mapfile -t ONLINE_TEMPLATES < <(pveam available -section system 2>/dev/null | grep -E '\.(tar\.zst|tar\.xz|tar\.gz)$' | awk '{print $2}' | grep -E "^${TEMPLATE_SEARCH}.*${TEMPLATE_PATTERN}" | sort -t - -k 2 -V 2>/dev/null || true)
|
||||
[[ ${#ONLINE_TEMPLATES[@]} -gt 0 ]] && ONLINE_TEMPLATE="${ONLINE_TEMPLATES[-1]}"
|
||||
|
||||
TEMPLATE="$ONLINE_TEMPLATE"
|
||||
TEMPLATE_SOURCE="online"
|
||||
msg_ok "Template search completed"
|
||||
fi
|
||||
|
||||
# If still no template, try to find alternatives
|
||||
@@ -4075,6 +4522,7 @@ create_lxc_container() {
|
||||
echo "[DEBUG] No template found for ${PCT_OSTYPE} ${PCT_OSVERSION}, searching for alternatives..."
|
||||
|
||||
# Get all available versions for this OS type
|
||||
AVAILABLE_VERSIONS=()
|
||||
mapfile -t AVAILABLE_VERSIONS < <(
|
||||
pveam available -section system 2>/dev/null |
|
||||
grep -E '\.(tar\.zst|tar\.xz|tar\.gz)$' |
|
||||
@@ -4097,6 +4545,7 @@ create_lxc_container() {
|
||||
PCT_OSVERSION="${AVAILABLE_VERSIONS[$((choice - 1))]}"
|
||||
TEMPLATE_SEARCH="${PCT_OSTYPE}-${PCT_OSVERSION}"
|
||||
|
||||
ONLINE_TEMPLATES=()
|
||||
mapfile -t ONLINE_TEMPLATES < <(
|
||||
pveam available -section system 2>/dev/null |
|
||||
grep -E '\.(tar\.zst|tar\.xz|tar\.gz)$' |
|
||||
@@ -4306,50 +4755,88 @@ create_lxc_container() {
|
||||
-rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}"
|
||||
fi
|
||||
|
||||
# Lock by template file (avoid concurrent downloads/creates)
|
||||
# Lock by template file (avoid concurrent template downloads/validation)
|
||||
lockfile="/tmp/template.${TEMPLATE}.lock"
|
||||
|
||||
# Cleanup stale lock files (older than 1 hour - likely from crashed processes)
|
||||
if [[ -f "$lockfile" ]]; then
|
||||
local lock_age=$(($(date +%s) - $(stat -c %Y "$lockfile" 2>/dev/null || echo 0)))
|
||||
if [[ $lock_age -gt 3600 ]]; then
|
||||
msg_warn "Removing stale template lock file (age: ${lock_age}s)"
|
||||
rm -f "$lockfile"
|
||||
fi
|
||||
fi
|
||||
|
||||
exec 9>"$lockfile" || {
|
||||
msg_error "Failed to create lock file '$lockfile'."
|
||||
exit 200
|
||||
}
|
||||
flock -w 60 9 || {
|
||||
msg_error "Timeout while waiting for template lock."
|
||||
exit 211
|
||||
}
|
||||
|
||||
# Retry logic for template lock (another container creation may be running)
|
||||
local lock_attempts=0
|
||||
local max_lock_attempts=10
|
||||
local lock_wait_time=30
|
||||
|
||||
while ! flock -w "$lock_wait_time" 9; do
|
||||
lock_attempts=$((lock_attempts + 1))
|
||||
if [[ $lock_attempts -ge $max_lock_attempts ]]; then
|
||||
msg_error "Timeout while waiting for template lock after ${max_lock_attempts} attempts."
|
||||
msg_custom "💡" "${YW}" "Another container creation may be stuck. Check running processes or remove: $lockfile"
|
||||
exit 211
|
||||
fi
|
||||
msg_custom "⏳" "${YW}" "Another container is being created with this template. Waiting... (attempt ${lock_attempts}/${max_lock_attempts})"
|
||||
done
|
||||
|
||||
LOGFILE="/tmp/pct_create_${CTID}_$(date +%Y%m%d_%H%M%S)_${SESSION_ID}.log"
|
||||
|
||||
# Validate template before pct create (while holding lock)
|
||||
if [[ ! -s "$TEMPLATE_PATH" || "$(stat -c%s "$TEMPLATE_PATH" 2>/dev/null || echo 0)" -lt 1000000 ]]; then
|
||||
msg_info "Template file missing or too small – downloading"
|
||||
rm -f "$TEMPLATE_PATH"
|
||||
pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null 2>&1
|
||||
msg_ok "Template downloaded"
|
||||
elif ! tar -tf "$TEMPLATE_PATH" &>/dev/null; then
|
||||
if [[ -n "$ONLINE_TEMPLATE" ]]; then
|
||||
msg_info "Template appears corrupted – re-downloading"
|
||||
rm -f "$TEMPLATE_PATH"
|
||||
pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null 2>&1
|
||||
msg_ok "Template re-downloaded"
|
||||
else
|
||||
msg_warn "Template appears corrupted, but no online version exists. Skipping re-download."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Release lock after template validation - pct create has its own internal locking
|
||||
exec 9>&-
|
||||
|
||||
msg_debug "pct create command: pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} $PCT_OPTIONS"
|
||||
msg_debug "Logfile: $LOGFILE"
|
||||
|
||||
# First attempt (PCT_OPTIONS is a multi-line string, use it directly)
|
||||
if ! pct create "$CTID" "${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE}" $PCT_OPTIONS >"$LOGFILE" 2>&1; then
|
||||
msg_debug "Container creation failed on ${TEMPLATE_STORAGE}. Validating template..."
|
||||
msg_debug "Container creation failed on ${TEMPLATE_STORAGE}. Checking error..."
|
||||
|
||||
# Validate template file
|
||||
if [[ ! -s "$TEMPLATE_PATH" || "$(stat -c%s "$TEMPLATE_PATH")" -lt 1000000 ]]; then
|
||||
msg_warn "Template file too small or missing – re-downloading."
|
||||
# Check if template issue - retry with fresh download
|
||||
if grep -qiE 'unable to open|corrupt|invalid' "$LOGFILE"; then
|
||||
msg_info "Template may be corrupted – re-downloading"
|
||||
rm -f "$TEMPLATE_PATH"
|
||||
pveam download "$TEMPLATE_STORAGE" "$TEMPLATE"
|
||||
elif ! tar -tf "$TEMPLATE_PATH" &>/dev/null; then
|
||||
if [[ -n "$ONLINE_TEMPLATE" ]]; then
|
||||
msg_warn "Template appears corrupted – re-downloading."
|
||||
rm -f "$TEMPLATE_PATH"
|
||||
pveam download "$TEMPLATE_STORAGE" "$TEMPLATE"
|
||||
else
|
||||
msg_warn "Template appears corrupted, but no online version exists. Skipping re-download."
|
||||
fi
|
||||
pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null 2>&1
|
||||
msg_ok "Template re-downloaded"
|
||||
fi
|
||||
|
||||
# Retry after repair
|
||||
if ! pct create "$CTID" "${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE}" $PCT_OPTIONS >>"$LOGFILE" 2>&1; then
|
||||
# Fallback to local storage if not already on local
|
||||
if [[ "$TEMPLATE_STORAGE" != "local" ]]; then
|
||||
msg_info "Retrying container creation with fallback to local storage..."
|
||||
msg_info "Retrying container creation with fallback to local storage"
|
||||
LOCAL_TEMPLATE_PATH="/var/lib/vz/template/cache/$TEMPLATE"
|
||||
if [[ ! -f "$LOCAL_TEMPLATE_PATH" ]]; then
|
||||
msg_info "Downloading template to local..."
|
||||
msg_ok "Trying local storage fallback"
|
||||
msg_info "Downloading template to local"
|
||||
pveam download local "$TEMPLATE" >/dev/null 2>&1
|
||||
msg_ok "Template downloaded to local"
|
||||
else
|
||||
msg_ok "Trying local storage fallback"
|
||||
fi
|
||||
if ! pct create "$CTID" "local:vztmpl/${TEMPLATE}" $PCT_OPTIONS >>"$LOGFILE" 2>&1; then
|
||||
# Local fallback also failed - check for LXC stack version issue
|
||||
|
||||
@@ -38,8 +38,6 @@ load_functions() {
|
||||
icons
|
||||
default_vars
|
||||
set_std_mode
|
||||
# Note: get_lxc_ip() is NOT called here automatically
|
||||
# Call it explicitly when you need LOCAL_IP variable
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
@@ -129,6 +127,34 @@ icons() {
|
||||
HOURGLASS="${TAB}⏳${TAB}"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# ensure_profile_loaded()
|
||||
#
|
||||
# - Sources /etc/profile.d/*.sh scripts if not already loaded
|
||||
# - Fixes PATH issues when running via pct enter/exec (non-login shells)
|
||||
# - Safe to call multiple times (uses guard variable)
|
||||
# - Should be called in update_script() or any script running inside LXC
|
||||
# ------------------------------------------------------------------------------
|
||||
ensure_profile_loaded() {
|
||||
# Skip if already loaded or running on Proxmox host
|
||||
[[ -n "${_PROFILE_LOADED:-}" ]] && return
|
||||
command -v pveversion &>/dev/null && return
|
||||
|
||||
# Source all profile.d scripts to ensure PATH is complete
|
||||
if [[ -d /etc/profile.d ]]; then
|
||||
for script in /etc/profile.d/*.sh; do
|
||||
[[ -r "$script" ]] && source "$script"
|
||||
done
|
||||
fi
|
||||
|
||||
# Also ensure /usr/local/bin is in PATH (common install location)
|
||||
if [[ ":$PATH:" != *":/usr/local/bin:"* ]]; then
|
||||
export PATH="/usr/local/bin:$PATH"
|
||||
fi
|
||||
|
||||
export _PROFILE_LOADED=1
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# default_vars()
|
||||
#
|
||||
|
||||
@@ -4387,11 +4387,19 @@ EOF
|
||||
return 1
|
||||
}
|
||||
|
||||
manage_tool_repository "php" "$PHP_VERSION" "" "https://packages.sury.org/debsuryorg-archive-keyring.deb" || {
|
||||
msg_error "Failed to setup PHP repository"
|
||||
return 1
|
||||
}
|
||||
|
||||
# Use different repository based on OS
|
||||
if [[ "$DISTRO_ID" == "ubuntu" ]]; then
|
||||
# Ubuntu: Use ondrej/php PPA
|
||||
msg_info "Adding ondrej/php PPA for Ubuntu"
|
||||
$STD apt install -y software-properties-common
|
||||
$STD add-apt-repository -y ppa:ondrej/php
|
||||
else
|
||||
# Debian: Use Sury repository
|
||||
manage_tool_repository "php" "$PHP_VERSION" "" "https://packages.sury.org/debsuryorg-archive-keyring.deb" || {
|
||||
msg_error "Failed to setup PHP repository"
|
||||
return 1
|
||||
}
|
||||
fi
|
||||
ensure_apt_working || return 1
|
||||
$STD apt update
|
||||
|
||||
|
||||
Reference in New Issue
Block a user