1
0
forked from Proxmox/ProxmoxVE

Compare commits

..

1 Commits

Author SHA1 Message Date
d6dafbe7c5 Update .app files 2025-04-08 15:04:07 +00:00
91 changed files with 1506 additions and 1361 deletions

View File

@ -16,10 +16,6 @@ All LXC instances created using this repository come pre-installed with Midnight
## 2025-04-08 ## 2025-04-08
### 🆕 New Scripts
- Alpine-PostgreSQL [@MickLesk](https://github.com/MickLesk) ([#3751](https://github.com/community-scripts/ProxmoxVE/pull/3751))
### 🚀 Updated Scripts ### 🚀 Updated Scripts
- #### 🐞 Bug Fixes - #### 🐞 Bug Fixes

View File

@ -27,24 +27,20 @@ function update_script() {
msg_error "No ${APP} Installation Found!" msg_error "No ${APP} Installation Found!"
exit exit
fi fi
if ! [[ $(dpkg -s python3-xmlsec 2>/dev/null) ]]; then
$STD apt-get update
$STD apt-get install -y python3-xmlsec
fi
if cd /opt/tandoor && git pull | grep -q 'Already up to date'; then if cd /opt/tandoor && git pull | grep -q 'Already up to date'; then
msg_ok "There is currently no update available." msg_ok "There is currently no update available."
else else
msg_info "Updating ${APP} (Patience)" msg_info "Updating ${APP} (Patience)"
export $(cat /opt/tandoor/.env | grep "^[^#]" | xargs) export $(cat /opt/tandoor/.env | grep "^[^#]" | xargs)
cd /opt/tandoor/ || exit cd /opt/tandoor/
$STD pip3 install -r requirements.txt $STD pip3 install -r requirements.txt
$STD /usr/bin/python3 /opt/tandoor/manage.py migrate $STD /usr/bin/python3 /opt/tandoor/manage.py migrate
$STD /usr/bin/python3 /opt/tandoor/manage.py collectstatic --no-input $STD /usr/bin/python3 /opt/tandoor/manage.py collectstatic --no-input
$STD /usr/bin/python3 /opt/tandoor/manage.py collectstatic_js_reverse $STD /usr/bin/python3 /opt/tandoor/manage.py collectstatic_js_reverse
cd /opt/tandoor/vue || exit cd /opt/tandoor/vue
$STD yarn install $STD yarn install
$STD yarn build $STD yarn build
cd /opt/tandoor || exit cd /opt/tandoor
$STD python3 version.py $STD python3 version.py
systemctl restart gunicorn_tandoor systemctl restart gunicorn_tandoor
msg_ok "Updated ${APP}" msg_ok "Updated ${APP}"

View File

@ -1,9 +1,11 @@
{ {
"name": "Proxmox VE LXC IP-Tag", "name": "Proxmox VE LXC IP-Tag",
"slug": "add-lxc-iptag", "slug": "add-lxc-iptag",
"categories": [1], "categories": [
1
],
"date_created": "2024-12-16", "date_created": "2024-12-16",
"type": "pve", "type": "misc",
"updateable": false, "updateable": false,
"privileged": false, "privileged": false,
"interface_port": null, "interface_port": null,
@ -14,7 +16,7 @@
"install_methods": [ "install_methods": [
{ {
"type": "default", "type": "default",
"script": "tools/pve/add-lxc-iptag.sh", "script": "misc/add-lxc-iptag.sh",
"resources": { "resources": {
"cpu": null, "cpu": null,
"ram": null, "ram": null,

View File

@ -1,9 +1,11 @@
{ {
"name": "NetBird", "name": "NetBird",
"slug": "add-netbird-lxc", "slug": "add-netbird-lxc",
"categories": [1], "categories": [
1
],
"date_created": "2024-05-19", "date_created": "2024-05-19",
"type": "addon", "type": "misc",
"updateable": false, "updateable": false,
"privileged": false, "privileged": false,
"interface_port": null, "interface_port": null,
@ -14,7 +16,7 @@
"install_methods": [ "install_methods": [
{ {
"type": "default", "type": "default",
"script": "tools/addon/add-netbird-lxc.sh", "script": "misc/add-netbird-lxc.sh",
"resources": { "resources": {
"cpu": null, "cpu": null,
"ram": null, "ram": null,

View File

@ -1,9 +1,11 @@
{ {
"name": "Tailscale", "name": "Tailscale",
"slug": "add-tailscale-lxc", "slug": "add-tailscale-lxc",
"categories": [1], "categories": [
1
],
"date_created": "2024-05-02", "date_created": "2024-05-02",
"type": "addon", "type": "misc",
"updateable": false, "updateable": false,
"privileged": false, "privileged": false,
"interface_port": null, "interface_port": null,
@ -14,7 +16,7 @@
"install_methods": [ "install_methods": [
{ {
"type": "default", "type": "default",
"script": "tools/addon/add-tailscale-lxc.sh", "script": "misc/add-tailscale-lxc.sh",
"resources": { "resources": {
"cpu": null, "cpu": null,
"ram": null, "ram": null,

View File

@ -1,9 +1,11 @@
{ {
"name": "All Templates", "name": "All Templates",
"slug": "all-templates", "slug": "all-templates",
"categories": [1], "categories": [
1
],
"date_created": "2024-05-02", "date_created": "2024-05-02",
"type": "addon", "type": "misc",
"updateable": false, "updateable": false,
"privileged": false, "privileged": false,
"interface_port": null, "interface_port": null,
@ -14,7 +16,7 @@
"install_methods": [ "install_methods": [
{ {
"type": "default", "type": "default",
"script": "tools/addon/all-templates.sh", "script": "misc/all-templates.sh",
"resources": { "resources": {
"cpu": null, "cpu": null,
"ram": null, "ram": null,

View File

@ -1,9 +1,11 @@
{ {
"name": "Proxmox VE LXC Cleaner", "name": "Proxmox VE LXC Cleaner",
"slug": "clean-lxcs", "slug": "clean-lxcs",
"categories": [1], "categories": [
1
],
"date_created": "2024-04-29", "date_created": "2024-04-29",
"type": "addon", "type": "misc",
"updateable": false, "updateable": false,
"privileged": false, "privileged": false,
"interface_port": null, "interface_port": null,
@ -14,7 +16,7 @@
"install_methods": [ "install_methods": [
{ {
"type": "default", "type": "default",
"script": "tools/pve/clean-lxcs.sh", "script": "misc/clean-lxcs.sh",
"resources": { "resources": {
"cpu": null, "cpu": null,
"ram": null, "ram": null,

View File

@ -1,9 +1,11 @@
{ {
"name": "Proxmox Clean Orphaned LVM", "name": "Proxmox Clean Orphaned LVM",
"slug": "clean-orphaned-lvm", "slug": "clean-orphaned-lvm",
"categories": [1], "categories": [
1
],
"date_created": "2025-01-29", "date_created": "2025-01-29",
"type": "pve", "type": "misc",
"updateable": false, "updateable": false,
"privileged": false, "privileged": false,
"interface_port": null, "interface_port": null,
@ -14,7 +16,7 @@
"install_methods": [ "install_methods": [
{ {
"type": "default", "type": "default",
"script": "tools/pve/clean-orphaned-lvm.sh", "script": "misc/clean-orphaned-lvm.sh",
"resources": { "resources": {
"cpu": null, "cpu": null,
"ram": null, "ram": null,

View File

@ -1,9 +1,13 @@
{ {
"name": "VS Code Server", "name": "VS Code Server",
"slug": "code-server", "slug": "code-server",
"categories": [1, 20, 11], "categories": [
1,
20,
11
],
"date_created": "2024-05-02", "date_created": "2024-05-02",
"type": "addon", "type": "misc",
"updateable": false, "updateable": false,
"privileged": false, "privileged": false,
"interface_port": 8680, "interface_port": 8680,
@ -14,7 +18,7 @@
"install_methods": [ "install_methods": [
{ {
"type": "default", "type": "default",
"script": "tools/addon/code-server.sh", "script": "misc/code-server.sh",
"resources": { "resources": {
"cpu": null, "cpu": null,
"ram": null, "ram": null,

View File

@ -1,9 +1,11 @@
{ {
"name": "Proxmox VE Cron LXC Updater", "name": "Proxmox VE Cron LXC Updater",
"slug": "cron-update-lxcs", "slug": "cron-update-lxcs",
"categories": [1], "categories": [
1
],
"date_created": "2024-04-29", "date_created": "2024-04-29",
"type": "pve", "type": "misc",
"updateable": false, "updateable": false,
"privileged": false, "privileged": false,
"interface_port": null, "interface_port": null,
@ -14,7 +16,7 @@
"install_methods": [ "install_methods": [
{ {
"type": "default", "type": "default",
"script": "tools/pve/cron-update-lxcs.sh", "script": "misc/cron-update-lxcs.sh",
"resources": { "resources": {
"cpu": null, "cpu": null,
"ram": null, "ram": null,
@ -34,8 +36,9 @@
"type": "info" "type": "info"
}, },
{ {
"text": "To exclude LXCs from updating, edit the crontab using `crontab -e` and add CTID as shown in the example below:\n\n\n\n`0 0 * * 0 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin /bin/bash -c '$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/pve/update-lxcs-cron.sh)' -s 103 111 >>/var/log/update-lxcs-cron.log 2>/dev/null`", "text": "To exclude LXCs from updating, edit the crontab using `crontab -e` and add CTID as shown in the example below:\n\n\n\n`0 0 * * 0 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin /bin/bash -c '$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/update-lxcs-cron.sh)' -s 103 111 >>/var/log/update-lxcs-cron.log 2>/dev/null`",
"type": "info" "type": "info"
} }
] ]
} }

View File

@ -1,9 +1,11 @@
{ {
"name": "CrowdSec", "name": "CrowdSec",
"slug": "crowdsec", "slug": "crowdsec",
"categories": [6], "categories": [
6
],
"date_created": "2024-05-02", "date_created": "2024-05-02",
"type": "addon", "type": "misc",
"updateable": false, "updateable": false,
"privileged": false, "privileged": false,
"interface_port": null, "interface_port": null,
@ -14,7 +16,7 @@
"install_methods": [ "install_methods": [
{ {
"type": "default", "type": "default",
"script": "tools/addon/crowdsec.sh", "script": "misc/crowdsec.sh",
"resources": { "resources": {
"cpu": null, "cpu": null,
"ram": null, "ram": null,

View File

@ -1,9 +1,11 @@
{ {
"name": "File Browser", "name": "File Browser",
"slug": "filebrowser", "slug": "filebrowser",
"categories": [1], "categories": [
1
],
"date_created": "2024-05-02", "date_created": "2024-05-02",
"type": "addon", "type": "misc",
"updateable": false, "updateable": false,
"privileged": false, "privileged": false,
"interface_port": 8080, "interface_port": 8080,
@ -14,7 +16,7 @@
"install_methods": [ "install_methods": [
{ {
"type": "default", "type": "default",
"script": "tools/addon/filebrowser.sh", "script": "misc/filebrowser.sh",
"resources": { "resources": {
"cpu": null, "cpu": null,
"ram": null, "ram": null,
@ -25,7 +27,7 @@
}, },
{ {
"type": "alpine", "type": "alpine",
"script": "tools/addon/filebrowser.sh", "script": "misc/filebrowser.sh",
"resources": { "resources": {
"cpu": null, "cpu": null,
"ram": null, "ram": null,

View File

@ -1,9 +1,11 @@
{ {
"name": "Proxmox VE LXC Filesystem Trim", "name": "Proxmox VE LXC Filesystem Trim",
"slug": "fstrim", "slug": "fstrim",
"categories": [1], "categories": [
1
],
"date_created": "2024-04-29", "date_created": "2024-04-29",
"type": "pve", "type": "misc",
"updateable": false, "updateable": false,
"privileged": false, "privileged": false,
"interface_port": null, "interface_port": null,
@ -14,7 +16,7 @@
"install_methods": [ "install_methods": [
{ {
"type": "default", "type": "default",
"script": "tools/pve/fstrim.sh", "script": "misc/fstrim.sh",
"resources": { "resources": {
"cpu": null, "cpu": null,
"ram": null, "ram": null,

View File

@ -1,9 +1,11 @@
{ {
"name": "Glances", "name": "Glances",
"slug": "glances", "slug": "glances",
"categories": [9], "categories": [
9
],
"date_created": "2024-05-02", "date_created": "2024-05-02",
"type": "addon", "type": "misc",
"updateable": false, "updateable": false,
"privileged": false, "privileged": false,
"interface_port": 61208, "interface_port": 61208,
@ -14,7 +16,7 @@
"install_methods": [ "install_methods": [
{ {
"type": "default", "type": "default",
"script": "tools/addon/glances.sh", "script": "misc/glances.sh",
"resources": { "resources": {
"cpu": null, "cpu": null,
"ram": null, "ram": null,

View File

@ -1,9 +1,11 @@
{ {
"name": "Proxmox VE Host Backup", "name": "Proxmox VE Host Backup",
"slug": "host-backup", "slug": "host-backup",
"categories": [1], "categories": [
1
],
"date_created": "2024-04-29", "date_created": "2024-04-29",
"type": "pve", "type": "misc",
"updateable": false, "updateable": false,
"privileged": false, "privileged": false,
"interface_port": null, "interface_port": null,
@ -14,7 +16,7 @@
"install_methods": [ "install_methods": [
{ {
"type": "default", "type": "default",
"script": "tools/pve/host-backup.sh", "script": "misc/host-backup.sh",
"resources": { "resources": {
"cpu": null, "cpu": null,
"ram": null, "ram": null,

View File

@ -1,9 +1,11 @@
{ {
"name": "Proxmox VE Kernel Clean", "name": "Proxmox VE Kernel Clean",
"slug": "kernel-clean", "slug": "kernel-clean",
"categories": [1], "categories": [
1
],
"date_created": "2024-04-29", "date_created": "2024-04-29",
"type": "pve", "type": "misc",
"updateable": false, "updateable": false,
"privileged": false, "privileged": false,
"interface_port": null, "interface_port": null,
@ -14,7 +16,7 @@
"install_methods": [ "install_methods": [
{ {
"type": "default", "type": "default",
"script": "tools/pve/kernel-clean.sh", "script": "misc/kernel-clean.sh",
"resources": { "resources": {
"cpu": null, "cpu": null,
"ram": null, "ram": null,

View File

@ -1,9 +1,11 @@
{ {
"name": "Proxmox VE Kernel Pin", "name": "Proxmox VE Kernel Pin",
"slug": "kernel-pin", "slug": "kernel-pin",
"categories": [1], "categories": [
1
],
"date_created": "2024-05-08", "date_created": "2024-05-08",
"type": "pve", "type": "misc",
"updateable": false, "updateable": false,
"privileged": false, "privileged": false,
"interface_port": null, "interface_port": null,
@ -14,7 +16,7 @@
"install_methods": [ "install_methods": [
{ {
"type": "default", "type": "default",
"script": "tools/pve/kernel-pin.sh", "script": "misc/kernel-pin.sh",
"resources": { "resources": {
"cpu": null, "cpu": null,
"ram": null, "ram": null,

View File

@ -1,9 +1,11 @@
{ {
"name": "Container LXC Deletion", "name": "Container LXC Deletion",
"slug": "lxc-delete", "slug": "lxc-delete",
"categories": [1], "categories": [
1
],
"date_created": "2025-01-21", "date_created": "2025-01-21",
"type": "pve", "type": "misc",
"updateable": false, "updateable": false,
"privileged": false, "privileged": false,
"interface_port": null, "interface_port": null,
@ -14,7 +16,7 @@
"install_methods": [ "install_methods": [
{ {
"type": "default", "type": "default",
"script": "tools/pve/lxc-delete.sh", "script": "misc/lxc-delete.sh",
"resources": { "resources": {
"cpu": null, "cpu": null,
"ram": null, "ram": null,

View File

@ -1,9 +1,11 @@
{ {
"name": "Proxmox VE Processor Microcode", "name": "Proxmox VE Processor Microcode",
"slug": "microcode", "slug": "microcode",
"categories": [1], "categories": [
1
],
"date_created": "2024-04-29", "date_created": "2024-04-29",
"type": "pve", "type": "misc",
"updateable": false, "updateable": false,
"privileged": false, "privileged": false,
"interface_port": null, "interface_port": null,
@ -14,7 +16,7 @@
"install_methods": [ "install_methods": [
{ {
"type": "default", "type": "default",
"script": "tools/pve/microcode.sh", "script": "misc/microcode.sh",
"resources": { "resources": {
"cpu": null, "cpu": null,
"ram": null, "ram": null,

View File

@ -1,9 +1,11 @@
{ {
"name": "Proxmox VE Monitor-All", "name": "Proxmox VE Monitor-All",
"slug": "monitor-all", "slug": "monitor-all",
"categories": [1], "categories": [
1
],
"date_created": "2024-04-29", "date_created": "2024-04-29",
"type": "pve", "type": "misc",
"updateable": false, "updateable": false,
"privileged": false, "privileged": false,
"interface_port": null, "interface_port": null,
@ -14,7 +16,7 @@
"install_methods": [ "install_methods": [
{ {
"type": "default", "type": "default",
"script": "tools/pve/monitor-all.sh", "script": "misc/monitor-all.sh",
"resources": { "resources": {
"cpu": null, "cpu": null,
"ram": null, "ram": null,

View File

@ -1,9 +1,11 @@
{ {
"name": "Proxmox VE Netdata", "name": "Proxmox VE Netdata",
"slug": "netdata", "slug": "netdata",
"categories": [1], "categories": [
1
],
"date_created": "2024-04-29", "date_created": "2024-04-29",
"type": "addon", "type": "misc",
"updateable": false, "updateable": false,
"privileged": false, "privileged": false,
"interface_port": null, "interface_port": null,
@ -14,7 +16,7 @@
"install_methods": [ "install_methods": [
{ {
"type": "default", "type": "default",
"script": "tools/addon/netdata.sh", "script": "misc/netdata.sh",
"resources": { "resources": {
"cpu": null, "cpu": null,
"ram": null, "ram": null,

View File

@ -1,9 +1,11 @@
{ {
"name": "OliveTin", "name": "OliveTin",
"slug": "olivetin", "slug": "olivetin",
"categories": [10], "categories": [
10
],
"date_created": "2024-05-02", "date_created": "2024-05-02",
"type": "addon", "type": "misc",
"updateable": false, "updateable": false,
"privileged": false, "privileged": false,
"interface_port": 1337, "interface_port": 1337,
@ -14,7 +16,7 @@
"install_methods": [ "install_methods": [
{ {
"type": "default", "type": "default",
"script": "tools/addon/olivetin.sh", "script": "misc/olivetin.sh",
"resources": { "resources": {
"cpu": null, "cpu": null,
"ram": null, "ram": null,

View File

@ -1,9 +1,11 @@
{ {
"name": "Proxmox Backup Server Processor Microcode", "name": "Proxmox Backup Server Processor Microcode",
"slug": "pbs-microcode", "slug": "pbs-microcode",
"categories": [1], "categories": [
1
],
"date_created": "2025-02-07", "date_created": "2025-02-07",
"type": "pve", "type": "misc",
"updateable": false, "updateable": false,
"privileged": false, "privileged": false,
"interface_port": null, "interface_port": null,
@ -14,7 +16,7 @@
"install_methods": [ "install_methods": [
{ {
"type": "default", "type": "default",
"script": "tools/pve/pbs_microcode.sh", "script": "misc/pbs_microcode.sh",
"resources": { "resources": {
"cpu": null, "cpu": null,
"ram": null, "ram": null,

View File

@ -1,9 +1,11 @@
{ {
"name": "Proxmox Backup Server Post Install", "name": "Proxmox Backup Server Post Install",
"slug": "post-pbs-install", "slug": "post-pbs-install",
"categories": [1], "categories": [
1
],
"date_created": "2024-04-29", "date_created": "2024-04-29",
"type": "pve", "type": "misc",
"updateable": false, "updateable": false,
"privileged": false, "privileged": false,
"interface_port": null, "interface_port": null,
@ -14,7 +16,7 @@
"install_methods": [ "install_methods": [
{ {
"type": "default", "type": "default",
"script": "tools/pve/post-pbs-install.sh", "script": "misc/post-pbs-install.sh",
"resources": { "resources": {
"cpu": null, "cpu": null,
"ram": null, "ram": null,

View File

@ -1,9 +1,11 @@
{ {
"name": "Proxmox Mail Gateway Post Install", "name": "Proxmox Mail Gateway Post Install",
"slug": "post-pmg-install", "slug": "post-pmg-install",
"categories": [1], "categories": [
1
],
"date_created": "2025-01-20", "date_created": "2025-01-20",
"type": "pve", "type": "misc",
"updateable": false, "updateable": false,
"privileged": false, "privileged": false,
"interface_port": null, "interface_port": null,
@ -14,7 +16,7 @@
"install_methods": [ "install_methods": [
{ {
"type": "default", "type": "default",
"script": "tools/pve/post-pmg-install.sh", "script": "misc/post-pmg-install.sh",
"resources": { "resources": {
"cpu": null, "cpu": null,
"ram": null, "ram": null,

View File

@ -1,9 +1,11 @@
{ {
"name": "Proxmox VE Post Install", "name": "Proxmox VE Post Install",
"slug": "post-pve-install", "slug": "post-pve-install",
"categories": [1], "categories": [
1
],
"date_created": "2024-04-28", "date_created": "2024-04-28",
"type": "pve", "type": "misc",
"updateable": false, "updateable": false,
"privileged": false, "privileged": false,
"interface_port": null, "interface_port": null,
@ -14,7 +16,7 @@
"install_methods": [ "install_methods": [
{ {
"type": "default", "type": "default",
"script": "tools/pve/post-pve-install.sh", "script": "misc/post-pve-install.sh",
"resources": { "resources": {
"cpu": null, "cpu": null,
"ram": null, "ram": null,

View File

@ -1,9 +1,11 @@
{ {
"name": "Proxmox VE CPU Scaling Governor", "name": "Proxmox VE CPU Scaling Governor",
"slug": "scaling-governor", "slug": "scaling-governor",
"categories": [1], "categories": [
1
],
"date_created": "2024-04-29", "date_created": "2024-04-29",
"type": "pve", "type": "misc",
"updateable": false, "updateable": false,
"privileged": false, "privileged": false,
"interface_port": null, "interface_port": null,
@ -14,7 +16,7 @@
"install_methods": [ "install_methods": [
{ {
"type": "default", "type": "default",
"script": "tools/pve/scaling-governor.sh", "script": "misc/scaling-governor.sh",
"resources": { "resources": {
"cpu": null, "cpu": null,
"ram": null, "ram": null,

View File

@ -1,9 +1,11 @@
{ {
"name": "Proxmox VE LXC Updater", "name": "Proxmox VE LXC Updater",
"slug": "update-lxcs", "slug": "update-lxcs",
"categories": [1], "categories": [
1
],
"date_created": "2024-04-29", "date_created": "2024-04-29",
"type": "pve", "type": "misc",
"updateable": false, "updateable": false,
"privileged": false, "privileged": false,
"interface_port": null, "interface_port": null,
@ -14,7 +16,7 @@
"install_methods": [ "install_methods": [
{ {
"type": "default", "type": "default",
"script": "tools/pve/update-lxcs.sh", "script": "misc/update-lxcs.sh",
"resources": { "resources": {
"cpu": null, "cpu": null,
"ram": null, "ram": null,

View File

@ -1,9 +1,11 @@
{ {
"name": "Proxmox Update Repositories", "name": "Proxmox Update Repositories",
"slug": "update-repo", "slug": "update-repo",
"categories": [1], "categories": [
1
],
"date_created": "2024-11-04", "date_created": "2024-11-04",
"type": "pve", "type": "misc",
"updateable": false, "updateable": false,
"privileged": false, "privileged": false,
"interface_port": null, "interface_port": null,
@ -14,7 +16,7 @@
"install_methods": [ "install_methods": [
{ {
"type": "default", "type": "default",
"script": "tools/pve/update-repo.sh", "script": "misc/update-repo.sh",
"resources": { "resources": {
"cpu": null, "cpu": null,
"ram": null, "ram": null,

View File

@ -1,9 +1,11 @@
{ {
"name": "Webmin System Administration", "name": "Webmin System Administration",
"slug": "webmin", "slug": "webmin",
"categories": [1], "categories": [
1
],
"date_created": "2024-05-02", "date_created": "2024-05-02",
"type": "addon", "type": "misc",
"updateable": false, "updateable": false,
"privileged": false, "privileged": false,
"interface_port": 10000, "interface_port": 10000,
@ -14,7 +16,7 @@
"install_methods": [ "install_methods": [
{ {
"type": "default", "type": "default",
"script": "tools/addon/webmin.sh", "script": "misc/webmin.sh",
"resources": { "resources": {
"cpu": null, "cpu": null,
"ram": null, "ram": null,

View File

@ -1,12 +1,12 @@
"use client"; "use client";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import { Category } from "@/lib/types";
import { ChevronLeft, ChevronRight } from "lucide-react";
import { useRouter } from "next/navigation";
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { useRouter } from "next/navigation";
import { Card, CardContent } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { ChevronLeft, ChevronRight } from "lucide-react";
import { Category } from "@/lib/types";
const defaultLogo = "/default-logo.png"; // Fallback logo path const defaultLogo = "/default-logo.png"; // Fallback logo path
const MAX_DESCRIPTION_LENGTH = 100; // Set max length for description const MAX_DESCRIPTION_LENGTH = 100; // Set max length for description
@ -17,11 +17,11 @@ const formattedBadge = (type: string) => {
case "vm": case "vm":
return <Badge className="text-blue-500/75 border-blue-500/75 badge">VM</Badge>; return <Badge className="text-blue-500/75 border-blue-500/75 badge">VM</Badge>;
case "ct": case "ct":
return <Badge className="text-yellow-500/75 border-yellow-500/75 badge">LXC</Badge>; return (
case "pve": <Badge className="text-yellow-500/75 border-yellow-500/75 badge">LXC</Badge>
return <Badge className="text-orange-500/75 border-orange-500/75 badge">PVE</Badge>; );
case "addon": case "misc":
return <Badge className="text-green-500/75 border-green-500/75 badge">ADDON</Badge>; return <Badge className="text-green-500/75 border-green-500/75 badge">MISC</Badge>;
} }
return null; return null;
}; };
@ -100,7 +100,9 @@ const CategoryView = () => {
}; };
const truncateDescription = (text: string) => { const truncateDescription = (text: string) => {
return text.length > MAX_DESCRIPTION_LENGTH ? `${text.slice(0, MAX_DESCRIPTION_LENGTH)}...` : text; return text.length > MAX_DESCRIPTION_LENGTH
? `${text.slice(0, MAX_DESCRIPTION_LENGTH)}...`
: text;
}; };
const renderResources = (script: any) => { const renderResources = (script: any) => {
@ -109,24 +111,9 @@ const CategoryView = () => {
const hdd = script.install_methods[0]?.resources.hdd; const hdd = script.install_methods[0]?.resources.hdd;
const resourceParts = []; const resourceParts = [];
if (cpu) if (cpu) resourceParts.push(<span key="cpu"><b>CPU:</b> {cpu}vCPU</span>);
resourceParts.push( if (ram) resourceParts.push(<span key="ram"><b>RAM:</b> {ram}MB</span>);
<span key="cpu"> if (hdd) resourceParts.push(<span key="hdd"><b>HDD:</b> {hdd}GB</span>);
<b>CPU:</b> {cpu}vCPU
</span>,
);
if (ram)
resourceParts.push(
<span key="ram">
<b>RAM:</b> {ram}MB
</span>,
);
if (hdd)
resourceParts.push(
<span key="hdd">
<b>HDD:</b> {hdd}GB
</span>,
);
return resourceParts.length > 0 ? ( return resourceParts.length > 0 ? (
<div className="text-sm text-gray-400"> <div className="text-sm text-gray-400">

View File

@ -1,6 +1,12 @@
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { OperatingSystems } from "@/config/siteConfig"; import { OperatingSystems } from "@/config/siteConfig";
import { PlusCircle, Trash2 } from "lucide-react"; import { PlusCircle, Trash2 } from "lucide-react";
import { memo, useCallback, useRef } from "react"; import { memo, useCallback, useRef } from "react";
@ -14,29 +20,21 @@ type InstallMethodProps = {
setZodErrors: (zodErrors: z.ZodError | null) => void; setZodErrors: (zodErrors: z.ZodError | null) => void;
}; };
function InstallMethod({ script, setScript, setIsValid, setZodErrors }: InstallMethodProps) { function InstallMethod({
script,
setScript,
setIsValid,
setZodErrors,
}: InstallMethodProps) {
const cpuRefs = useRef<(HTMLInputElement | null)[]>([]); const cpuRefs = useRef<(HTMLInputElement | null)[]>([]);
const ramRefs = useRef<(HTMLInputElement | null)[]>([]); const ramRefs = useRef<(HTMLInputElement | null)[]>([]);
const hddRefs = useRef<(HTMLInputElement | null)[]>([]); const hddRefs = useRef<(HTMLInputElement | null)[]>([]);
const addInstallMethod = useCallback(() => { const addInstallMethod = useCallback(() => {
setScript((prev) => { setScript((prev) => {
const { type, slug } = prev;
const newMethodType = "default";
let scriptPath = "";
if (type === "pve") {
scriptPath = `tools/pve/${slug}.sh`;
} else if (type === "addon") {
scriptPath = `tools/addon/${slug}.sh`;
} else {
scriptPath = `${type}/${slug}.sh`;
}
const method = InstallMethodSchema.parse({ const method = InstallMethodSchema.parse({
type: newMethodType, type: "default",
script: scriptPath, script: `${prev.type}/${prev.slug}.sh`,
resources: { resources: {
cpu: null, cpu: null,
ram: null, ram: null,
@ -45,7 +43,6 @@ function InstallMethod({ script, setScript, setIsValid, setZodErrors }: InstallM
version: null, version: null,
}, },
}); });
return { return {
...prev, ...prev,
install_methods: [...prev.install_methods, method], install_methods: [...prev.install_methods, method],
@ -66,7 +63,9 @@ function InstallMethod({ script, setScript, setIsValid, setZodErrors }: InstallM
if (key === "type") { if (key === "type") {
updatedMethod.script = updatedMethod.script =
value === "alpine" ? `${prev.type}/alpine-${prev.slug}.sh` : `${prev.type}/${prev.slug}.sh`; value === "alpine"
? `${prev.type}/alpine-${prev.slug}.sh`
: `${prev.type}/${prev.slug}.sh`;
// Set OS to Alpine and reset version if type is alpine // Set OS to Alpine and reset version if type is alpine
if (value === "alpine") { if (value === "alpine") {
@ -113,7 +112,10 @@ function InstallMethod({ script, setScript, setIsValid, setZodErrors }: InstallM
<h3 className="text-xl font-semibold">Install Methods</h3> <h3 className="text-xl font-semibold">Install Methods</h3>
{script.install_methods.map((method, index) => ( {script.install_methods.map((method, index) => (
<div key={index} className="space-y-2 border p-4 rounded"> <div key={index} className="space-y-2 border p-4 rounded">
<Select value={method.type} onValueChange={(value) => updateInstallMethod(index, "type", value)}> <Select
value={method.type}
onValueChange={(value) => updateInstallMethod(index, "type", value)}
>
<SelectTrigger> <SelectTrigger>
<SelectValue placeholder="Type" /> <SelectValue placeholder="Type" />
</SelectTrigger> </SelectTrigger>
@ -203,7 +205,9 @@ function InstallMethod({ script, setScript, setIsValid, setZodErrors }: InstallM
<SelectValue placeholder="Version" /> <SelectValue placeholder="Version" />
</SelectTrigger> </SelectTrigger>
<SelectContent> <SelectContent>
{OperatingSystems.find((os) => os.name === method.resources.os)?.versions.map((version) => ( {OperatingSystems.find(
(os) => os.name === method.resources.os,
)?.versions.map((version) => (
<SelectItem key={version.slug} value={version.name}> <SelectItem key={version.slug} value={version.name}>
{version.name} {version.name}
</SelectItem> </SelectItem>
@ -211,12 +215,22 @@ function InstallMethod({ script, setScript, setIsValid, setZodErrors }: InstallM
</SelectContent> </SelectContent>
</Select> </Select>
</div> </div>
<Button variant="destructive" size="sm" type="button" onClick={() => removeInstallMethod(index)}> <Button
variant="destructive"
size="sm"
type="button"
onClick={() => removeInstallMethod(index)}
>
<Trash2 className="mr-2 h-4 w-4" /> Remove Install Method <Trash2 className="mr-2 h-4 w-4" /> Remove Install Method
</Button> </Button>
</div> </div>
))} ))}
<Button type="button" size="sm" disabled={script.install_methods.length >= 2} onClick={addInstallMethod}> <Button
type="button"
size="sm"
disabled={script.install_methods.length >= 2}
onClick={addInstallMethod}
>
<PlusCircle className="mr-2 h-4 w-4" /> Add Install Method <PlusCircle className="mr-2 h-4 w-4" /> Add Install Method
</Button> </Button>
</> </>

View File

@ -24,8 +24,8 @@ export const ScriptSchema = z.object({
slug: z.string().min(1, "Slug is required"), slug: z.string().min(1, "Slug is required"),
categories: z.array(z.number()), categories: z.array(z.number()),
date_created: z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Date must be in YYYY-MM-DD format").min(1, "Date is required"), date_created: z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Date must be in YYYY-MM-DD format").min(1, "Date is required"),
type: z.enum(["vm", "ct", "pve", "addon", "turnkey"], { type: z.enum(["vm", "ct", "misc", "turnkey"], {
errorMap: () => ({ message: "Type must be either 'vm', 'ct', 'pve', 'addon' or 'turnkey'" }) errorMap: () => ({ message: "Type must be either 'vm', 'ct', 'misc' or 'turnkey'" })
}), }),
updateable: z.boolean(), updateable: z.boolean(),
privileged: z.boolean(), privileged: z.boolean(),

View File

@ -5,8 +5,18 @@ import { Button } from "@/components/ui/button";
import { Calendar } from "@/components/ui/calendar"; import { Calendar } from "@/components/ui/calendar";
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label"; import { Label } from "@/components/ui/label";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"; import {
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { Switch } from "@/components/ui/switch"; import { Switch } from "@/components/ui/switch";
import { Textarea } from "@/components/ui/textarea"; import { Textarea } from "@/components/ui/textarea";
import { fetchCategories } from "@/lib/data"; import { fetchCategories } from "@/lib/data";
@ -56,29 +66,19 @@ export default function JSONGenerator() {
.catch((error) => console.error("Error fetching categories:", error)); .catch((error) => console.error("Error fetching categories:", error));
}, []); }, []);
const updateScript = useCallback((key: keyof Script, value: Script[keyof Script]) => { const updateScript = useCallback(
(key: keyof Script, value: Script[keyof Script]) => {
setScript((prev) => { setScript((prev) => {
const updated = { ...prev, [key]: value }; const updated = { ...prev, [key]: value };
if (updated.slug && updated.type) { if (key === "type" || key === "slug") {
updated.install_methods = updated.install_methods.map((method) => { updated.install_methods = updated.install_methods.map((method) => ({
let scriptPath = "";
if (updated.type === "pve") {
scriptPath = `tools/pve/${updated.slug}.sh`;
} else if (updated.type === "addon") {
scriptPath = `tools/addon/${updated.slug}.sh`;
} else if (method.type === "alpine") {
scriptPath = `${updated.type}/alpine-${updated.slug}.sh`;
} else {
scriptPath = `${updated.type}/${updated.slug}.sh`;
}
return {
...method, ...method,
script: scriptPath, script:
}; method.type === "alpine"
}); ? `${updated.type}/alpine-${updated.slug}.sh`
: `${updated.type}/${updated.slug}.sh`,
}));
} }
const result = ScriptSchema.safeParse(updated); const result = ScriptSchema.safeParse(updated);
@ -86,7 +86,9 @@ export default function JSONGenerator() {
setZodErrors(result.success ? null : result.error); setZodErrors(result.success ? null : result.error);
return updated; return updated;
}); });
}, []); },
[],
);
const handleCopy = useCallback(() => { const handleCopy = useCallback(() => {
navigator.clipboard.writeText(JSON.stringify(script, null, 2)); navigator.clipboard.writeText(JSON.stringify(script, null, 2));
@ -118,13 +120,16 @@ export default function JSONGenerator() {
); );
const formattedDate = useMemo( const formattedDate = useMemo(
() => (script.date_created ? format(script.date_created, "PPP") : undefined), () =>
script.date_created ? format(script.date_created, "PPP") : undefined,
[script.date_created], [script.date_created],
); );
const validationAlert = useMemo( const validationAlert = useMemo(
() => ( () => (
<Alert className={cn("text-black", isValid ? "bg-green-100" : "bg-red-100")}> <Alert
className={cn("text-black", isValid ? "bg-green-100" : "bg-red-100")}
>
<AlertTitle>{isValid ? "Valid JSON" : "Invalid JSON"}</AlertTitle> <AlertTitle>{isValid ? "Valid JSON" : "Invalid JSON"}</AlertTitle>
<AlertDescription> <AlertDescription>
{isValid {isValid
@ -155,13 +160,21 @@ export default function JSONGenerator() {
<Label> <Label>
Name <span className="text-red-500">*</span> Name <span className="text-red-500">*</span>
</Label> </Label>
<Input placeholder="Example" value={script.name} onChange={(e) => updateScript("name", e.target.value)} /> <Input
placeholder="Example"
value={script.name}
onChange={(e) => updateScript("name", e.target.value)}
/>
</div> </div>
<div> <div>
<Label> <Label>
Slug <span className="text-red-500">*</span> Slug <span className="text-red-500">*</span>
</Label> </Label>
<Input placeholder="example" value={script.slug} onChange={(e) => updateScript("slug", e.target.value)} /> <Input
placeholder="example"
value={script.slug}
onChange={(e) => updateScript("slug", e.target.value)}
/>
</div> </div>
</div> </div>
<div> <div>
@ -184,7 +197,11 @@ export default function JSONGenerator() {
onChange={(e) => updateScript("description", e.target.value)} onChange={(e) => updateScript("description", e.target.value)}
/> />
</div> </div>
<Categories script={script} setScript={setScript} categories={categories} /> <Categories
script={script}
setScript={setScript}
categories={categories}
/>
<div className="flex gap-2"> <div className="flex gap-2">
<div className="flex flex-col gap-2 w-full"> <div className="flex flex-col gap-2 w-full">
<Label>Date Created</Label> <Label>Date Created</Label>
@ -192,7 +209,10 @@ export default function JSONGenerator() {
<PopoverTrigger asChild className="flex-1"> <PopoverTrigger asChild className="flex-1">
<Button <Button
variant={"outline"} variant={"outline"}
className={cn("pl-3 text-left font-normal w-full", !script.date_created && "text-muted-foreground")} className={cn(
"pl-3 text-left font-normal w-full",
!script.date_created && "text-muted-foreground",
)}
> >
{formattedDate || <span>Pick a date</span>} {formattedDate || <span>Pick a date</span>}
<CalendarIcon className="ml-auto h-4 w-4 opacity-50" /> <CalendarIcon className="ml-auto h-4 w-4 opacity-50" />
@ -210,26 +230,38 @@ export default function JSONGenerator() {
</div> </div>
<div className="flex flex-col gap-2 w-full"> <div className="flex flex-col gap-2 w-full">
<Label>Type</Label> <Label>Type</Label>
<Select value={script.type} onValueChange={(value) => updateScript("type", value)}> <Select
value={script.type}
onValueChange={(value) => updateScript("type", value)}
>
<SelectTrigger className="flex-1"> <SelectTrigger className="flex-1">
<SelectValue placeholder="Type" /> <SelectValue placeholder="Type" />
</SelectTrigger> </SelectTrigger>
<SelectContent> <SelectContent>
<SelectItem value="ct">LXC Container</SelectItem> <SelectItem value="ct">LXC Container</SelectItem>
<SelectItem value="vm">Virtual Machine</SelectItem> <SelectItem value="vm">Virtual Machine</SelectItem>
<SelectItem value="pve">PVE-Tool</SelectItem> <SelectItem value="misc">Miscellaneous</SelectItem>
<SelectItem value="addon">Add-On</SelectItem>
</SelectContent> </SelectContent>
</Select> </Select>
</div> </div>
</div> </div>
<div className="w-full flex gap-5"> <div className="w-full flex gap-5">
<div className="flex items-center space-x-2"> <div className="flex items-center space-x-2">
<Switch checked={script.updateable} onCheckedChange={(checked) => updateScript("updateable", checked)} /> <Switch
checked={script.updateable}
onCheckedChange={(checked) =>
updateScript("updateable", checked)
}
/>
<label>Updateable</label> <label>Updateable</label>
</div> </div>
<div className="flex items-center space-x-2"> <div className="flex items-center space-x-2">
<Switch checked={script.privileged} onCheckedChange={(checked) => updateScript("privileged", checked)} /> <Switch
checked={script.privileged}
onCheckedChange={(checked) =>
updateScript("privileged", checked)
}
/>
<label>Privileged</label> <label>Privileged</label>
</div> </div>
</div> </div>
@ -237,7 +269,12 @@ export default function JSONGenerator() {
placeholder="Interface Port" placeholder="Interface Port"
type="number" type="number"
value={script.interface_port || ""} value={script.interface_port || ""}
onChange={(e) => updateScript("interface_port", e.target.value ? Number(e.target.value) : null)} onChange={(e) =>
updateScript(
"interface_port",
e.target.value ? Number(e.target.value) : null,
)
}
/> />
<div className="flex gap-2"> <div className="flex gap-2">
<Input <Input
@ -248,10 +285,17 @@ export default function JSONGenerator() {
<Input <Input
placeholder="Documentation URL" placeholder="Documentation URL"
value={script.documentation || ""} value={script.documentation || ""}
onChange={(e) => updateScript("documentation", e.target.value || null)} onChange={(e) =>
updateScript("documentation", e.target.value || null)
}
/> />
</div> </div>
<InstallMethod script={script} setScript={setScript} setIsValid={setIsValid} setZodErrors={setZodErrors} /> <InstallMethod
script={script}
setScript={setScript}
setIsValid={setIsValid}
setZodErrors={setZodErrors}
/>
<h3 className="text-xl font-semibold">Default Credentials</h3> <h3 className="text-xl font-semibold">Default Credentials</h3>
<Input <Input
placeholder="Username" placeholder="Username"
@ -273,17 +317,30 @@ export default function JSONGenerator() {
}) })
} }
/> />
<Note script={script} setScript={setScript} setIsValid={setIsValid} setZodErrors={setZodErrors} /> <Note
script={script}
setScript={setScript}
setIsValid={setIsValid}
setZodErrors={setZodErrors}
/>
</form> </form>
</div> </div>
<div className="w-1/2 p-4 bg-background overflow-y-auto"> <div className="w-1/2 p-4 bg-background overflow-y-auto">
{validationAlert} {validationAlert}
<div className="relative"> <div className="relative">
<div className="absolute right-2 top-2 flex gap-1"> <div className="absolute right-2 top-2 flex gap-1">
<Button size="icon" variant="outline" onClick={handleCopy}> <Button
size="icon"
variant="outline"
onClick={handleCopy}
>
{isCopied ? <Check className="h-4 w-4" /> : <Clipboard className="h-4 w-4" />} {isCopied ? <Check className="h-4 w-4" /> : <Clipboard className="h-4 w-4" />}
</Button> </Button>
<Button size="icon" variant="outline" onClick={handleDownload}> <Button
size="icon"
variant="outline"
onClick={handleDownload}
>
<Download className="h-4 w-4" /> <Download className="h-4 w-4" />
</Button> </Button>
</div> </div>

View File

@ -1,5 +1,12 @@
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"; import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { basePath, mostPopularScripts } from "@/config/siteConfig"; import { basePath, mostPopularScripts } from "@/config/siteConfig";
import { extractDate } from "@/lib/time"; import { extractDate } from "@/lib/time";
import { Category, Script } from "@/lib/types"; import { Category, Script } from "@/lib/types";
@ -16,8 +23,7 @@ export const getDisplayValueFromType = (type: string) => {
return "LXC"; return "LXC";
case "vm": case "vm":
return "VM"; return "VM";
case "pve": case "misc":
case "addon":
return ""; return "";
default: default:
return ""; return "";
@ -41,7 +47,8 @@ export function LatestScripts({ items }: { items: Category[] }) {
}); });
return Array.from(uniqueScriptsMap.values()).sort( return Array.from(uniqueScriptsMap.values()).sort(
(a, b) => new Date(b.date_created).getTime() - new Date(a.date_created).getTime(), (a, b) =>
new Date(b.date_created).getTime() - new Date(a.date_created).getTime(),
); );
}, [items]); }, [items]);
@ -67,12 +74,18 @@ export function LatestScripts({ items }: { items: Category[] }) {
<h2 className="text-lg font-semibold">Newest Scripts</h2> <h2 className="text-lg font-semibold">Newest Scripts</h2>
<div className="flex items-center justify-end gap-1"> <div className="flex items-center justify-end gap-1">
{page > 1 && ( {page > 1 && (
<div className="cursor-pointer select-none p-2 text-sm font-semibold" onClick={goToPreviousPage}> <div
className="cursor-pointer select-none p-2 text-sm font-semibold"
onClick={goToPreviousPage}
>
Previous Previous
</div> </div>
)} )}
{endIndex < latestScripts.length && ( {endIndex < latestScripts.length && (
<div onClick={goToNextPage} className="cursor-pointer select-none p-2 text-sm font-semibold"> <div
onClick={goToNextPage}
className="cursor-pointer select-none p-2 text-sm font-semibold"
>
{page === 1 ? "More.." : "Next"} {page === 1 ? "More.." : "Next"}
</div> </div>
)} )}
@ -81,7 +94,10 @@ export function LatestScripts({ items }: { items: Category[] }) {
)} )}
<div className="min-w flex w-full flex-row flex-wrap gap-4"> <div className="min-w flex w-full flex-row flex-wrap gap-4">
{latestScripts.slice(startIndex, endIndex).map((script) => ( {latestScripts.slice(startIndex, endIndex).map((script) => (
<Card key={script.slug} className="min-w-[250px] flex-1 flex-grow bg-accent/30"> <Card
key={script.slug}
className="min-w-[250px] flex-1 flex-grow bg-accent/30"
>
<CardHeader> <CardHeader>
<CardTitle className="flex items-center gap-3"> <CardTitle className="flex items-center gap-3">
<div className="flex h-16 w-16 min-w-16 items-center justify-center rounded-lg bg-accent p-1"> <div className="flex h-16 w-16 min-w-16 items-center justify-center rounded-lg bg-accent p-1">
@ -91,7 +107,10 @@ export function LatestScripts({ items }: { items: Category[] }) {
height={64} height={64}
width={64} width={64}
alt="" alt=""
onError={(e) => ((e.currentTarget as HTMLImageElement).src = `/${basePath}/logo.png`)} onError={(e) =>
((e.currentTarget as HTMLImageElement).src =
`/${basePath}/logo.png`)
}
className="h-11 w-11 object-contain" className="h-11 w-11 object-contain"
/> />
</div> </div>
@ -107,7 +126,9 @@ export function LatestScripts({ items }: { items: Category[] }) {
</CardTitle> </CardTitle>
</CardHeader> </CardHeader>
<CardContent> <CardContent>
<CardDescription className="line-clamp-3 text-card-foreground">{script.description}</CardDescription> <CardDescription className="line-clamp-3 text-card-foreground">
{script.description}
</CardDescription>
</CardContent> </CardContent>
<CardFooter className=""> <CardFooter className="">
<Button asChild variant="outline"> <Button asChild variant="outline">
@ -130,7 +151,9 @@ export function LatestScripts({ items }: { items: Category[] }) {
export function MostViewedScripts({ items }: { items: Category[] }) { export function MostViewedScripts({ items }: { items: Category[] }) {
const mostViewedScripts = items.reduce((acc: Script[], category) => { const mostViewedScripts = items.reduce((acc: Script[], category) => {
const foundScripts = category.scripts.filter((script) => mostPopularScripts.includes(script.slug)); const foundScripts = category.scripts.filter((script) =>
mostPopularScripts.includes(script.slug),
);
return acc.concat(foundScripts); return acc.concat(foundScripts);
}, []); }, []);
@ -143,7 +166,10 @@ export function MostViewedScripts({ items }: { items: Category[] }) {
)} )}
<div className="min-w flex w-full flex-row flex-wrap gap-4"> <div className="min-w flex w-full flex-row flex-wrap gap-4">
{mostViewedScripts.map((script) => ( {mostViewedScripts.map((script) => (
<Card key={script.slug} className="min-w-[250px] flex-1 flex-grow bg-accent/30"> <Card
key={script.slug}
className="min-w-[250px] flex-1 flex-grow bg-accent/30"
>
<CardHeader> <CardHeader>
<CardTitle className="flex items-center gap-3"> <CardTitle className="flex items-center gap-3">
<div className="flex size-16 min-w-16 items-center justify-center rounded-lg bg-accent p-1"> <div className="flex size-16 min-w-16 items-center justify-center rounded-lg bg-accent p-1">
@ -153,7 +179,10 @@ export function MostViewedScripts({ items }: { items: Category[] }) {
height={64} height={64}
width={64} width={64}
alt="" alt=""
onError={(e) => ((e.currentTarget as HTMLImageElement).src = `/${basePath}/logo.png`)} onError={(e) =>
((e.currentTarget as HTMLImageElement).src =
`/${basePath}/logo.png`)
}
className="h-11 w-11 object-contain" className="h-11 w-11 object-contain"
/> />
</div> </div>

View File

@ -14,12 +14,12 @@ import { Suspense } from "react";
import { ResourceDisplay } from "./ResourceDisplay"; import { ResourceDisplay } from "./ResourceDisplay";
import { getDisplayValueFromType } from "./ScriptInfoBlocks"; import { getDisplayValueFromType } from "./ScriptInfoBlocks";
import Alerts from "./ScriptItems/Alerts"; import Alerts from "./ScriptItems/Alerts";
import Buttons from "./ScriptItems/Buttons";
import DefaultPassword from "./ScriptItems/DefaultPassword"; import DefaultPassword from "./ScriptItems/DefaultPassword";
import Description from "./ScriptItems/Description"; import Description from "./ScriptItems/Description";
import InstallCommand from "./ScriptItems/InstallCommand"; import InstallCommand from "./ScriptItems/InstallCommand";
import InterFaces from "./ScriptItems/InterFaces";
import Tooltips from "./ScriptItems/Tooltips"; import Tooltips from "./ScriptItems/Tooltips";
import InterFaces from "./ScriptItems/InterFaces";
import Buttons from "./ScriptItems/Buttons";
interface ScriptItemProps { interface ScriptItemProps {
item: Script; item: Script;
@ -142,9 +142,7 @@ export function ScriptItem({ item, setSelectedScript }: ScriptItemProps) {
<div className="mt-4 rounded-lg border shadow-sm"> <div className="mt-4 rounded-lg border shadow-sm">
<div className="flex gap-3 px-4 py-2 bg-accent/25"> <div className="flex gap-3 px-4 py-2 bg-accent/25">
<h2 className="text-lg font-semibold"> <h2 className="text-lg font-semibold">How to {item.type === "misc" ? "use" : "install"}</h2>
How to {item.type === "pve" ? "use" : item.type === "addon" ? "apply" : "install"}
</h2>
<Tooltips item={item} /> <Tooltips item={item} />
</div> </div>
<Separator /> <Separator />

View File

@ -16,17 +16,7 @@ const generateInstallSourceUrl = (slug: string) => {
const generateSourceUrl = (slug: string, type: string) => { const generateSourceUrl = (slug: string, type: string) => {
const baseUrl = `https://raw.githubusercontent.com/community-scripts/${basePath}/main`; const baseUrl = `https://raw.githubusercontent.com/community-scripts/${basePath}/main`;
return type === "vm" ? `${baseUrl}/vm/${slug}.sh` : `${baseUrl}/misc/${slug}.sh`;
switch (type) {
case "vm":
return `${baseUrl}/vm/${slug}.sh`;
case "pve":
return `${baseUrl}/tools/pve/${slug}.sh`;
case "addon":
return `${baseUrl}/tools/addon/${slug}.sh`;
default:
return `${baseUrl}/ct/${slug}.sh`; // fallback for "ct"
}
}; };
const generateUpdateUrl = (slug: string) => { const generateUpdateUrl = (slug: string) => {

View File

@ -6,44 +6,50 @@ import { getDisplayValueFromType } from "../ScriptInfoBlocks";
const getInstallCommand = (scriptPath = "", isAlpine = false) => { const getInstallCommand = (scriptPath = "", isAlpine = false) => {
const url = `https://raw.githubusercontent.com/community-scripts/${basePath}/main/${scriptPath}`; const url = `https://raw.githubusercontent.com/community-scripts/${basePath}/main/${scriptPath}`;
return isAlpine ? `bash -c "$(curl -fsSL ${url})"` : `bash -c "$(curl -fsSL ${url})"`; return isAlpine
? `bash -c "$(curl -fsSL ${url})"`
: `bash -c "$(curl -fsSL ${url})"`;
}; };
export default function InstallCommand({ item }: { item: Script }) {
const alpineScript = item.install_methods.find((method) => method.type === "alpine");
const defaultScript = item.install_methods.find((method) => method.type === "default"); export default function InstallCommand({ item }: { item: Script }) {
const alpineScript = item.install_methods.find(
(method) => method.type === "alpine",
);
const defaultScript = item.install_methods.find(
(method) => method.type === "default",
);
const renderInstructions = (isAlpine = false) => ( const renderInstructions = (isAlpine = false) => (
<> <>
<p className="text-sm mt-2"> <p className="text-sm mt-2">
{isAlpine ? ( {isAlpine ? (
<> <>
As an alternative option, you can use Alpine Linux and the {item.name} package to create a {item.name}{" "} As an alternative option, you can use Alpine Linux and the{" "}
{getDisplayValueFromType(item.type)} container with faster creation time and minimal system resource usage. {item.name} package to create a {item.name}{" "}
You are also obliged to adhere to updates provided by the package maintainer. {getDisplayValueFromType(item.type)} container with faster creation
time and minimal system resource usage. You are also obliged to
adhere to updates provided by the package maintainer.
</> </>
) : item.type === "pve" ? ( ) : item.type == "misc" ? (
<> <>
To use the {item.name} script, run the command below **only** in the Proxmox VE Shell. This script is To use the {item.name} script, run the command below in the shell.
intended for managing or enhancing the host system directly.
</>
) : item.type === "addon" ? (
<>
This script enhances an existing setup. You can use it inside a running LXC container or directly on the
Proxmox VE host to extend functionality with {item.name}.
</> </>
) : ( ) : (
<> <>
To create a new Proxmox VE {item.name} {getDisplayValueFromType(item.type)}, run the command below in the {" "}
To create a new Proxmox VE {item.name}{" "}
{getDisplayValueFromType(item.type)}, run the command below in the
Proxmox VE Shell. Proxmox VE Shell.
</> </>
)} )}
</p> </p>
{isAlpine && ( {isAlpine && (
<p className="mt-2 text-sm"> <p className="mt-2 text-sm">
To create a new Proxmox VE Alpine-{item.name} {getDisplayValueFromType(item.type)}, run the command below in To create a new Proxmox VE Alpine-{item.name}{" "}
the Proxmox VE Shell. {getDisplayValueFromType(item.type)}, run the command below in the
Proxmox VE Shell
</p> </p>
)} )}
</> </>
@ -59,17 +65,23 @@ export default function InstallCommand({ item }: { item: Script }) {
</TabsList> </TabsList>
<TabsContent value="default"> <TabsContent value="default">
{renderInstructions()} {renderInstructions()}
<CodeCopyButton>{getInstallCommand(defaultScript?.script)}</CodeCopyButton> <CodeCopyButton>
{getInstallCommand(defaultScript?.script)}
</CodeCopyButton>
</TabsContent> </TabsContent>
<TabsContent value="alpine"> <TabsContent value="alpine">
{renderInstructions(true)} {renderInstructions(true)}
<CodeCopyButton>{getInstallCommand(alpineScript.script, true)}</CodeCopyButton> <CodeCopyButton>
{getInstallCommand(alpineScript.script, true)}
</CodeCopyButton>
</TabsContent> </TabsContent>
</Tabs> </Tabs>
) : defaultScript?.script ? ( ) : defaultScript?.script ? (
<> <>
{renderInstructions()} {renderInstructions()}
<CodeCopyButton>{getInstallCommand(defaultScript.script)}</CodeCopyButton> <CodeCopyButton>
{getInstallCommand(defaultScript.script)}
</CodeCopyButton>
</> </>
) : null} ) : null}
</div> </div>

View File

@ -6,7 +6,6 @@ import {
CommandItem, CommandItem,
CommandList, CommandList,
} from "@/components/ui/command"; } from "@/components/ui/command";
import { basePath } from "@/config/siteConfig";
import { fetchCategories } from "@/lib/data"; import { fetchCategories } from "@/lib/data";
import { Category } from "@/lib/types"; import { Category } from "@/lib/types";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
@ -16,17 +15,18 @@ import React from "react";
import { Badge } from "./ui/badge"; import { Badge } from "./ui/badge";
import { Button } from "./ui/button"; import { Button } from "./ui/button";
import { DialogTitle } from "./ui/dialog"; import { DialogTitle } from "./ui/dialog";
import { basePath } from "@/config/siteConfig";
export const formattedBadge = (type: string) => { export const formattedBadge = (type: string) => {
switch (type) { switch (type) {
case "vm": case "vm":
return <Badge className="text-blue-500/75 border-blue-500/75">VM</Badge>; return <Badge className="text-blue-500/75 border-blue-500/75">VM</Badge>;
case "ct": case "ct":
return <Badge className="text-yellow-500/75 border-yellow-500/75">LXC</Badge>; return (
case "pve": <Badge className="text-yellow-500/75 border-yellow-500/75">LXC</Badge>
return <Badge className="text-orange-500/75 border-orange-500/75">PVE</Badge>; );
case "addon": case "misc":
return <Badge className="text-green-500/75 border-green-500/75">ADDON</Badge>; return <Badge className="text-green-500/75 border-green-500/75">MISC</Badge>;
} }
return null; return null;
}; };
@ -84,9 +84,14 @@ export default function CommandMenu() {
<DialogTitle className="sr-only">Search scripts</DialogTitle> <DialogTitle className="sr-only">Search scripts</DialogTitle>
<CommandInput placeholder="Search for a script..." /> <CommandInput placeholder="Search for a script..." />
<CommandList> <CommandList>
<CommandEmpty>{isLoading ? "Loading..." : "No scripts found."}</CommandEmpty> <CommandEmpty>
{isLoading ? "Loading..." : "No scripts found."}
</CommandEmpty>
{links.map((category) => ( {links.map((category) => (
<CommandGroup key={`category:${category.name}`} heading={category.name}> <CommandGroup
key={`category:${category.name}`}
heading={category.name}
>
{category.scripts.map((script) => ( {category.scripts.map((script) => (
<CommandItem <CommandItem
key={`script:${script.slug}`} key={`script:${script.slug}`}
@ -99,7 +104,10 @@ export default function CommandMenu() {
<div className="flex gap-2" onClick={() => setOpen(false)}> <div className="flex gap-2" onClick={() => setOpen(false)}>
<Image <Image
src={script.logo || `/${basePath}/logo.png`} src={script.logo || `/${basePath}/logo.png`}
onError={(e) => ((e.currentTarget as HTMLImageElement).src = `/${basePath}/logo.png`)} onError={(e) =>
((e.currentTarget as HTMLImageElement).src =
`/${basePath}/logo.png`)
}
unoptimized unoptimized
width={16} width={16}
height={16} height={16}

View File

@ -5,7 +5,7 @@ export type Script = {
slug: string; slug: string;
categories: number[]; categories: number[];
date_created: string; date_created: string;
type: "vm" | "ct" | "pve" | "addon"; type: "vm" | "ct" | "misc";
updateable: boolean; updateable: boolean;
privileged: boolean; privileged: boolean;
interface_port: number | null; interface_port: number | null;

View File

@ -18,7 +18,7 @@ $STD apt-get install -y g++-multilib
msg_ok "Installed Dependencies" msg_ok "Installed Dependencies"
msg_info "Installing Daemon Sync Server" msg_info "Installing Daemon Sync Server"
curl -fsSL "https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/daemonsync_2.2.0.0059_amd64.deb" -o "daemonsync_2.2.0.0059_amd64.deb" curl -fsSL "https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/daemonsync_2.2.0.0059_amd64.deb" -o "daemonsync_2.2.0.0059_amd64.deb"
$STD dpkg -i daemonsync_2.2.0.0059_amd64.deb $STD dpkg -i daemonsync_2.2.0.0059_amd64.deb
msg_ok "Installed Daemon Sync Server" msg_ok "Installed Daemon Sync Server"

View File

@ -38,8 +38,7 @@ $STD apt-get install -y \
python3 \ python3 \
python3-dev \ python3-dev \
python3-setuptools \ python3-setuptools \
python3-pip \ python3-pip
python3-xmlsec
rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
msg_ok "Setup Python3" msg_ok "Setup Python3"

View File

@ -40,7 +40,7 @@ function clean_container() {
header_info header_info
name=$(pct exec "$container" hostname) name=$(pct exec "$container" hostname)
echo -e "${BL}[Info]${GN} Cleaning ${name} ${CL} \n" echo -e "${BL}[Info]${GN} Cleaning ${name} ${CL} \n"
pct exec "$container" -- bash -c "apt-get -y --purge autoremove && apt-get -y autoclean && bash <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/pve/clean.sh) && rm -rf /var/lib/apt/lists/* && apt-get update" pct exec $container -- bash -c "apt-get -y --purge autoremove && apt-get -y autoclean && bash <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/clean.sh) && rm -rf /var/lib/apt/lists/* && apt-get update"
} }
for container in $(pct list | awk '{if(NR>1) print $1}'); do for container in $(pct list | awk '{if(NR>1) print $1}'); do
if [[ " ${excluded_containers[@]} " =~ " $container " ]]; then if [[ " ${excluded_containers[@]} " =~ " $container " ]]; then
@ -56,18 +56,18 @@ for container in $(pct list | awk '{if(NR>1) print $1}'); do
continue continue
fi fi
status=$(pct status "$container") status=$(pct status $container)
template=$(pct config "$container" | grep -q "template:" && echo "true" || echo "false") template=$(pct config $container | grep -q "template:" && echo "true" || echo "false")
if [ "$template" == "false" ] && [ "$status" == "status: stopped" ]; then if [ "$template" == "false" ] && [ "$status" == "status: stopped" ]; then
echo -e "${BL}[Info]${GN} Starting${BL} $container ${CL} \n" echo -e "${BL}[Info]${GN} Starting${BL} $container ${CL} \n"
pct start "$container" pct start $container
echo -e "${BL}[Info]${GN} Waiting For${BL} $container${CL}${GN} To Start ${CL} \n" echo -e "${BL}[Info]${GN} Waiting For${BL} $container${CL}${GN} To Start ${CL} \n"
sleep 5 sleep 5
clean_container "$container" clean_container $container
echo -e "${BL}[Info]${GN} Shutting down${BL} $container ${CL} \n" echo -e "${BL}[Info]${GN} Shutting down${BL} $container ${CL} \n"
pct shutdown "$container" & pct shutdown $container &
elif [ "$status" == "status: running" ]; then elif [ "$status" == "status: running" ]; then
clean_container "$container" clean_container $container
fi fi
fi fi
done done

View File

@ -2,45 +2,45 @@
<div align="center"> To copy data from Home Assistant Container to Home Assistant Container </div> <div align="center"> To copy data from Home Assistant Container to Home Assistant Container </div>
``` ```
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/copy-data/home-assistant-container-copy-data-home-assistant-container.sh)" bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/copy-data/home-assistant-container-copy-data-home-assistant-container.sh)"
``` ```
<div align="center"> To copy data from Home Assistant Container to Home Assistant Core </div> <div align="center"> To copy data from Home Assistant Container to Home Assistant Core </div>
``` ```
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/copy-data/home-assistant-container-copy-data-home-assistant-core.sh)" bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/copy-data/home-assistant-container-copy-data-home-assistant-core.sh)"
``` ```
<div align="center"> To copy data from Home Assistant Container to Podman Home Assistant </div> <div align="center"> To copy data from Home Assistant Container to Podman Home Assistant </div>
``` ```
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/copy-data/home-assistant-container-copy-data-podman-home-assistant.sh)" bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/copy-data/home-assistant-container-copy-data-podman-home-assistant.sh)"
``` ```
<div align="center"> To copy data from Podman Home Assistant to Home Assistant Container </div> <div align="center"> To copy data from Podman Home Assistant to Home Assistant Container </div>
``` ```
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/copy-data/podman-home-assistant-copy-data-home-assistant-container.sh)" bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/copy-data/podman-home-assistant-copy-data-home-assistant-container.sh)"
``` ```
<div align="center"> To copy data from Home Assistant Core to Home Assistant Container </div> <div align="center"> To copy data from Home Assistant Core to Home Assistant Container </div>
``` ```
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/copy-data/home-assistant-core-copy-data-home-assistant-container.sh)" bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/copy-data/home-assistant-core-copy-data-home-assistant-container.sh)"
``` ```
<div align="center"> To copy data from Home Assistant Core to Home Assistant Core </div> <div align="center"> To copy data from Home Assistant Core to Home Assistant Core </div>
``` ```
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/copy-data/home-assistant-core-copy-data-home-assistant-core.sh)" bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/copy-data/home-assistant-core-copy-data-home-assistant-core.sh)"
``` ```
<div align="center"> To copy data from Plex to Plex </div> <div align="center"> To copy data from Plex to Plex </div>
``` ```
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/copy-data/plex-copy-data-plex.sh)" bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/copy-data/plex-copy-data-plex.sh)"
``` ```
<div align="center"> To copy data from Zigbee2MQTT to Zigbee2MQTT </div> <div align="center"> To copy data from Zigbee2MQTT to Zigbee2MQTT </div>
``` ```
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/copy-data/z2m-copy-data-z2m.sh)" bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/copy-data/z2m-copy-data-z2m.sh)"
``` ```
<div align="center"> To copy data from Zwavejs2MQTT to Zwave JS UI </div> <div align="center"> To copy data from Zwavejs2MQTT to Zwave JS UI </div>
``` ```
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/copy-data/zwavejs2mqtt-copy-data-zwavejsui.sh)" bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/copy-data/zwavejs2mqtt-copy-data-zwavejsui.sh)"
``` ```

View File

@ -35,7 +35,7 @@ function error_exit() {
local REASON="\e[97m${1:-$DEFAULT}\e[39m" local REASON="\e[97m${1:-$DEFAULT}\e[39m"
local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE"
msg "$FLAG $REASON" msg "$FLAG $REASON"
exit "$EXIT" exit $EXIT
} }
function warn() { function warn() {
local REASON="\e[97m$1\e[39m" local REASON="\e[97m$1\e[39m"
@ -52,13 +52,13 @@ function msg() {
echo -e "$TEXT" echo -e "$TEXT"
} }
function cleanup() { function cleanup() {
[ -d "${CTID_FROM_PATH:-}" ] && pct unmount "$CTID_FROM" [ -d "${CTID_FROM_PATH:-}" ] && pct unmount $CTID_FROM
[ -d "${CTID_TO_PATH:-}" ] && pct unmount "$CTID_TO" [ -d "${CTID_TO_PATH:-}" ] && pct unmount $CTID_TO
popd >/dev/null popd >/dev/null
rm -rf "$TEMP_DIR" rm -rf $TEMP_DIR
} }
TEMP_DIR=$(mktemp -d) TEMP_DIR=$(mktemp -d)
pushd "$TEMP_DIR" >/dev/null pushd $TEMP_DIR >/dev/null
TITLE="Home Assistant LXC Data Copy" TITLE="Home Assistant LXC Data Copy"
while read -r line; do while read -r line; do
@ -84,32 +84,32 @@ while [ -z "${CTID_TO:+x}" ]; do
done done
for i in ${!CTID_MENU[@]}; do for i in ${!CTID_MENU[@]}; do
[ "${CTID_MENU[$i]}" == "$CTID_FROM" ] && [ "${CTID_MENU[$i]}" == "$CTID_FROM" ] &&
CTID_FROM_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<"${CTID_MENU[$i + 1]}") CTID_FROM_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]})
[ "${CTID_MENU[$i]}" == "$CTID_TO" ] && [ "${CTID_MENU[$i]}" == "$CTID_TO" ] &&
CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<"${CTID_MENU[$i + 1]}") CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]})
done done
whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "$TITLE" --yesno \ whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "$TITLE" --yesno \
"Are you sure you want to copy data between the following LXCs? "Are you sure you want to copy data between the following LXCs?
$CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME}) $CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME})
Version: 2022.01.23" 13 50 || exit Version: 2022.01.23" 13 50 || exit
info "Home Assistant Data from '$CTID_FROM' to '$CTID_TO'" info "Home Assistant Data from '$CTID_FROM' to '$CTID_TO'"
if [ $(pct status "$CTID_TO" | sed 's/.* //') == 'running' ]; then if [ $(pct status $CTID_TO | sed 's/.* //') == 'running' ]; then
msg "Stopping '$CTID_TO'..." msg "Stopping '$CTID_TO'..."
pct stop "$CTID_TO" pct stop $CTID_TO
fi fi
msg "Mounting Container Disks..." msg "Mounting Container Disks..."
DOCKER_PATH=/var/lib/docker/volumes/hass_config/ DOCKER_PATH=/var/lib/docker/volumes/hass_config/
CTID_FROM_PATH=$(pct mount "$CTID_FROM" | sed -n "s/.*'\(.*\)'/\1/p") || CTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n "s/.*'\(.*\)'/\1/p") ||
die "There was a problem mounting the root disk of LXC '${CTID_FROM}'." die "There was a problem mounting the root disk of LXC '${CTID_FROM}'."
[ -d "${CTID_FROM_PATH}${DOCKER_PATH}" ] || [ -d "${CTID_FROM_PATH}${DOCKER_PATH}" ] ||
die "Home Assistant directories in '$CTID_FROM' not found." die "Home Assistant directories in '$CTID_FROM' not found."
CTID_TO_PATH=$(pct mount "$CTID_TO" | sed -n "s/.*'\(.*\)'/\1/p") || CTID_TO_PATH=$(pct mount $CTID_TO | sed -n "s/.*'\(.*\)'/\1/p") ||
die "There was a problem mounting the root disk of LXC '${CTID_TO}'." die "There was a problem mounting the root disk of LXC '${CTID_TO}'."
[ -d "${CTID_TO_PATH}${DOCKER_PATH}" ] || [ -d "${CTID_TO_PATH}${DOCKER_PATH}" ] ||
die "Home Assistant directories in '$CTID_TO' not found." die "Home Assistant directories in '$CTID_TO' not found."
rm -rf "${CTID_TO_PATH}"${DOCKER_PATH} rm -rf ${CTID_TO_PATH}${DOCKER_PATH}
mkdir "${CTID_TO_PATH}"${DOCKER_PATH} mkdir ${CTID_TO_PATH}${DOCKER_PATH}
msg "Copying Data Between Containers..." msg "Copying Data Between Containers..."
RSYNC_OPTIONS=( RSYNC_OPTIONS=(
@ -121,11 +121,11 @@ RSYNC_OPTIONS=(
--info=progress2 --info=progress2
) )
msg "<======== Docker Data ========>" msg "<======== Docker Data ========>"
rsync "${RSYNC_OPTIONS[*]}" "${CTID_FROM_PATH}"${DOCKER_PATH} "${CTID_TO_PATH}"${DOCKER_PATH} rsync ${RSYNC_OPTIONS[*]} ${CTID_FROM_PATH}${DOCKER_PATH} ${CTID_TO_PATH}${DOCKER_PATH}
echo -en "\e[1A\e[0K\e[1A\e[0K" echo -en "\e[1A\e[0K\e[1A\e[0K"
info "Successfully Transferred Data." info "Successfully Transferred Data."
# Use to copy all data from one Home Assistant LXC to another # Use to copy all data from one Home Assistant LXC to another
# run from the Proxmox Shell # run from the Proxmox Shell
# bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/mainmain/tools/copy-data//home-assistant-container-copy-data-home-assistant-container.sh)" # bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/copy-data/home-assistant-container-copy-data-home-assistant-container.sh)"

View File

@ -124,4 +124,4 @@ info "Successfully Transferred Data."
# Use to copy all data from a Home Assistant Container LXC to a Home Assistant Core LXC # Use to copy all data from a Home Assistant Container LXC to a Home Assistant Core LXC
# run from the Proxmox Shell # run from the Proxmox Shell
# bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/mainmain/tools/copy-data//home-assistant-container-copy-data-home-assistant-core.sh)" # bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/copy-data/home-assistant-container-copy-data-home-assistant-core.sh)"

View File

@ -129,4 +129,4 @@ info "Successfully Transferred Data."
# Use to copy all data from a Home Assistant LXC to a Podman Home Assistant LXC # Use to copy all data from a Home Assistant LXC to a Podman Home Assistant LXC
# run from the Proxmox Shell # run from the Proxmox Shell
# bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/mainmain/tools/copy-data//home-assistant-container-copy-data-podman-home-assistant.sh)" # bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/copy-data/home-assistant-container-copy-data-podman-home-assistant.sh)"

View File

@ -124,4 +124,4 @@ info "Successfully Transferred Data."
# Use to copy all data from a Home Assistant Core LXC to a Home Assistant Container LXC # Use to copy all data from a Home Assistant Core LXC to a Home Assistant Container LXC
# run from the Proxmox Shell # run from the Proxmox Shell
# bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/mainmain/tools/copy-data//home-assistant-core-copy-data-home-assistant-container.sh)" # bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/copy-data/home-assistant-core-copy-data-home-assistant-container.sh)"

View File

@ -123,4 +123,4 @@ info "Successfully Transferred Data."
# Use to copy all data from a Home Assistant Core LXC to a Home Assistant Container LXC # Use to copy all data from a Home Assistant Core LXC to a Home Assistant Container LXC
# run from the Proxmox Shell # run from the Proxmox Shell
# bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/mainmain/tools/copy-data//home-assistant-core-copy-data-home-assistant-core.sh)" # bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/copy-data/home-assistant-core-copy-data-home-assistant-core.sh)"

View File

@ -128,4 +128,4 @@ info "Successfully Transferred Data."
# Use to copy all data from one Plex Media Server LXC to another # Use to copy all data from one Plex Media Server LXC to another
# run from the Proxmox Shell # run from the Proxmox Shell
# bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/mainmain/tools/copy-data//plex-copy-data-plex.sh)" # bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/copy-data/plex-copy-data-plex.sh)"

View File

@ -129,4 +129,4 @@ info "Successfully Transferred Data."
# Use to copy all data from a Podman Home Assistant LXC to a Docker Home Assistant LXC. # Use to copy all data from a Podman Home Assistant LXC to a Docker Home Assistant LXC.
# run from the Proxmox Shell # run from the Proxmox Shell
# bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/mainmain/tools/copy-data//podman-home-assistant-copy-data-home-assistant-container.sh)" # bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/copy-data/podman-home-assistant-copy-data-home-assistant-container.sh)"

View File

@ -128,4 +128,4 @@ info "Successfully Transferred Data."
# Use to copy all data from one Zigbee2MQTT LXC to another # Use to copy all data from one Zigbee2MQTT LXC to another
# run from the Proxmox Shell # run from the Proxmox Shell
# bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/mainmain/tools/copy-data//z2m-copy-data-z2m.sh)" # bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/copy-data/z2m-copy-data-z2m.sh)"

View File

@ -130,4 +130,4 @@ info "Successfully Transferred Data."
# Use to copy all data from a Zwavejs2MQTT LXC to a Z-wave JS UI LXC # Use to copy all data from a Zwavejs2MQTT LXC to a Z-wave JS UI LXC
# run from the Proxmox Shell # run from the Proxmox Shell
# bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/mainmain/tools/copy-data//zwavejs2mqtt-copy-data-zwavejsui.sh)" # bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/copy-data/zwavejs2mqtt-copy-data-zwavejsui.sh)"

View File

@ -4,7 +4,7 @@
# Author: tteck (tteckster) # Author: tteck (tteckster)
# License: MIT # License: MIT
# https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE # https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/pve/cron-update-lxcs.sh)" # bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/cron-update-lxcs.sh)"
clear clear
cat <<"EOF" cat <<"EOF"
@ -25,13 +25,13 @@ add() {
*) echo "Please answer yes or no." ;; *) echo "Please answer yes or no." ;;
esac esac
done done
sh -c '(crontab -l -u root 2>/dev/null; echo "0 0 * * 0 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin /bin/bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/pve/update-lxcs-cron.sh)\" >>/var/log/update-lxcs-cron.log 2>/dev/null") | crontab -u root -' sh -c '(crontab -l -u root 2>/dev/null; echo "0 0 * * 0 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin /bin/bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/update-lxcs-cron.sh)\" >>/var/log/update-lxcs-cron.log 2>/dev/null") | crontab -u root -'
clear clear
echo -e "\n To view Cron Update LXCs logs: cat /var/log/update-lxcs-cron.log" echo -e "\n To view Cron Update LXCs logs: cat /var/log/update-lxcs-cron.log"
} }
remove() { remove() {
(crontab -l | grep -v "update-lxcs-cron.sh") | crontab - (crontab -l | grep -v "github.com/community-scripts/ProxmoxVE/raw/main/misc/update-lxcs-cron.sh") | crontab -
rm -rf /var/log/update-lxcs-cron.log rm -rf /var/log/update-lxcs-cron.log
echo "Removed Crontab Schedule from Proxmox VE" echo "Removed Crontab Schedule from Proxmox VE"
} }

Binary file not shown.

View File

@ -79,15 +79,15 @@ done
# Add autodev settings # Add autodev settings
CTID_CONFIG_PATH=/etc/pve/lxc/${CTID}.conf CTID_CONFIG_PATH=/etc/pve/lxc/${CTID}.conf
sed '/autodev/d' "$CTID_CONFIG_PATH" >CTID.conf sed '/autodev/d' $CTID_CONFIG_PATH >CTID.conf
cat CTID.conf >"$CTID_CONFIG_PATH" cat CTID.conf >$CTID_CONFIG_PATH
cat <<EOF >>"$CTID_CONFIG_PATH" cat <<EOF >>$CTID_CONFIG_PATH
lxc.autodev: 1 lxc.autodev: 1
lxc.hook.autodev: bash -c '$HOOK_SCRIPT' lxc.hook.autodev: bash -c '$HOOK_SCRIPT'
EOF EOF
echo -e "\e[1;33m \nFinished....Reboot ${CTID} LXC to apply the changes.\n \e[0m" echo -e "\e[1;33m \nFinished....Reboot ${CTID} LXC to apply the changes.\n \e[0m"
# In the Proxmox web shell run # In the Proxmox web shell run
# bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/pve/frigate-support.sh)" # bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/frigate-support.sh)"
# Reboot the LXC to apply the changes # Reboot the LXC to apply the changes

View File

@ -5,7 +5,7 @@
# License: MIT # License: MIT
# https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE # https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Execute within the Proxmox shell # Execute within the Proxmox shell
# bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/pve/hw-acceleration.sh)" # bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/hw-acceleration.sh)"
set -e set -e
function header_info { function header_info {
@ -76,7 +76,7 @@ else
fi fi
header_info header_info
cat <<EOF >>/etc/pve/lxc/"${privileged_container}".conf cat <<EOF >>/etc/pve/lxc/${privileged_container}.conf
lxc.cgroup2.devices.allow: c 226:0 rwm lxc.cgroup2.devices.allow: c 226:0 rwm
lxc.cgroup2.devices.allow: c 226:128 rwm lxc.cgroup2.devices.allow: c 226:128 rwm
lxc.cgroup2.devices.allow: c 29:0 rwm lxc.cgroup2.devices.allow: c 29:0 rwm
@ -89,7 +89,7 @@ read -r -p "Do you need the intel-media-va-driver-non-free driver (Debian 12 onl
if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then
header_info header_info
msg_info "Installing Hardware Acceleration (non-free)" msg_info "Installing Hardware Acceleration (non-free)"
pct exec "${privileged_container}" -- bash -c "cat <<EOF >/etc/apt/sources.list.d/non-free.list pct exec ${privileged_container} -- bash -c "cat <<EOF >/etc/apt/sources.list.d/non-free.list
deb http://deb.debian.org/debian bookworm main contrib non-free non-free-firmware deb http://deb.debian.org/debian bookworm main contrib non-free non-free-firmware
deb-src http://deb.debian.org/debian bookworm main contrib non-free non-free-firmware deb-src http://deb.debian.org/debian bookworm main contrib non-free non-free-firmware
@ -101,12 +101,12 @@ deb http://deb.debian.org/debian bookworm-updates main contrib non-free non-free
deb-src http://deb.debian.org/debian bookworm-updates main contrib non-free non-free-firmware deb-src http://deb.debian.org/debian bookworm-updates main contrib non-free non-free-firmware
EOF" EOF"
pct exec "${privileged_container}" -- bash -c "silent() { \"\$@\" >/dev/null 2>&1; } && $STD apt-get update && $STD apt-get install -y intel-media-va-driver-non-free ocl-icd-libopencl1 intel-opencl-icd vainfo intel-gpu-tools && $STD adduser \$(id -u -n) video && $STD adduser \$(id -u -n) render" pct exec ${privileged_container} -- bash -c "silent() { \"\$@\" >/dev/null 2>&1; } && $STD apt-get update && $STD apt-get install -y intel-media-va-driver-non-free ocl-icd-libopencl1 intel-opencl-icd vainfo intel-gpu-tools && $STD adduser \$(id -u -n) video && $STD adduser \$(id -u -n) render"
msg_ok "Installed Hardware Acceleration (non-free)" msg_ok "Installed Hardware Acceleration (non-free)"
else else
header_info header_info
msg_info "Installing Hardware Acceleration" msg_info "Installing Hardware Acceleration"
pct exec "${privileged_container}" -- bash -c "silent() { \"\$@\" >/dev/null 2>&1; } && $STD apt-get install -y va-driver-all ocl-icd-libopencl1 intel-opencl-icd vainfo intel-gpu-tools && chgrp video /dev/dri && chmod 755 /dev/dri && $STD adduser \$(id -u -n) video && $STD adduser \$(id -u -n) render" pct exec ${privileged_container} -- bash -c "silent() { \"\$@\" >/dev/null 2>&1; } && $STD apt-get install -y va-driver-all ocl-icd-libopencl1 intel-opencl-icd vainfo intel-gpu-tools && chgrp video /dev/dri && chmod 755 /dev/dri && $STD adduser \$(id -u -n) video && $STD adduser \$(id -u -n) render"
msg_ok "Installed Hardware Acceleration" msg_ok "Installed Hardware Acceleration"
fi fi
sleep 1 sleep 1