1
0
mirror of https://github.com/community-scripts/ProxmoxVE.git synced 2025-04-19 13:38:07 +00:00

core: move misc scripts to structured addon/pve paths | Refactor JSON Editor & Script Mapping (#3765)

* Move Scripts to Tools / Add-Ons

* fix json editor slug generating

* update type in jsons

* remove wrong method

* move copy-data to tools
This commit is contained in:
CanbiZ 2025-04-09 13:10:02 +02:00 committed by GitHub
parent f2f10376ac
commit 3dffd02f08
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
88 changed files with 1327 additions and 1481 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,11 +1,9 @@
{ {
"name": "Proxmox VE Cron LXC Updater", "name": "Proxmox VE Cron LXC Updater",
"slug": "cron-update-lxcs", "slug": "cron-update-lxcs",
"categories": [ "categories": [1],
1
],
"date_created": "2024-04-29", "date_created": "2024-04-29",
"type": "misc", "type": "pve",
"updateable": false, "updateable": false,
"privileged": false, "privileged": false,
"interface_port": null, "interface_port": null,
@ -16,7 +14,7 @@
"install_methods": [ "install_methods": [
{ {
"type": "default", "type": "default",
"script": "misc/cron-update-lxcs.sh", "script": "tools/pve/cron-update-lxcs.sh",
"resources": { "resources": {
"cpu": null, "cpu": null,
"ram": null, "ram": null,
@ -36,9 +34,8 @@
"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/misc/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/tools/pve/update-lxcs-cron.sh)' -s 103 111 >>/var/log/update-lxcs-cron.log 2>/dev/null`",
"type": "info" "type": "info"
} }
] ]
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,12 +1,12 @@
"use client"; "use client";
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 { Badge } from "@/components/ui/badge";
import { ChevronLeft, ChevronRight } from "lucide-react"; import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import { Category } from "@/lib/types"; import { Category } from "@/lib/types";
import { ChevronLeft, ChevronRight } from "lucide-react";
import { useRouter } from "next/navigation";
import React, { useEffect, useState } from "react";
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 ( return <Badge className="text-yellow-500/75 border-yellow-500/75 badge">LXC</Badge>;
<Badge className="text-yellow-500/75 border-yellow-500/75 badge">LXC</Badge> case "pve":
); return <Badge className="text-orange-500/75 border-orange-500/75 badge">PVE</Badge>;
case "misc": case "addon":
return <Badge className="text-green-500/75 border-green-500/75 badge">MISC</Badge>; return <Badge className="text-green-500/75 border-green-500/75 badge">ADDON</Badge>;
} }
return null; return null;
}; };
@ -100,9 +100,7 @@ const CategoryView = () => {
}; };
const truncateDescription = (text: string) => { const truncateDescription = (text: string) => {
return text.length > MAX_DESCRIPTION_LENGTH return text.length > MAX_DESCRIPTION_LENGTH ? `${text.slice(0, MAX_DESCRIPTION_LENGTH)}...` : text;
? `${text.slice(0, MAX_DESCRIPTION_LENGTH)}...`
: text;
}; };
const renderResources = (script: any) => { const renderResources = (script: any) => {
@ -111,9 +109,24 @@ const CategoryView = () => {
const hdd = script.install_methods[0]?.resources.hdd; const hdd = script.install_methods[0]?.resources.hdd;
const resourceParts = []; const resourceParts = [];
if (cpu) resourceParts.push(<span key="cpu"><b>CPU:</b> {cpu}vCPU</span>); if (cpu)
if (ram) resourceParts.push(<span key="ram"><b>RAM:</b> {ram}MB</span>); resourceParts.push(
if (hdd) resourceParts.push(<span key="hdd"><b>HDD:</b> {hdd}GB</span>); <span key="cpu">
<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,12 +1,6 @@
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 { import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
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";
@ -20,21 +14,29 @@ type InstallMethodProps = {
setZodErrors: (zodErrors: z.ZodError | null) => void; setZodErrors: (zodErrors: z.ZodError | null) => void;
}; };
function InstallMethod({ function InstallMethod({ script, setScript, setIsValid, setZodErrors }: InstallMethodProps) {
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: "default", type: newMethodType,
script: `${prev.type}/${prev.slug}.sh`, script: scriptPath,
resources: { resources: {
cpu: null, cpu: null,
ram: null, ram: null,
@ -43,6 +45,7 @@ function InstallMethod({
version: null, version: null,
}, },
}); });
return { return {
...prev, ...prev,
install_methods: [...prev.install_methods, method], install_methods: [...prev.install_methods, method],
@ -63,9 +66,7 @@ function InstallMethod({
if (key === "type") { if (key === "type") {
updatedMethod.script = updatedMethod.script =
value === "alpine" value === "alpine" ? `${prev.type}/alpine-${prev.slug}.sh` : `${prev.type}/${prev.slug}.sh`;
? `${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") {
@ -112,10 +113,7 @@ function InstallMethod({
<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 <Select value={method.type} onValueChange={(value) => updateInstallMethod(index, "type", value)}>
value={method.type}
onValueChange={(value) => updateInstallMethod(index, "type", value)}
>
<SelectTrigger> <SelectTrigger>
<SelectValue placeholder="Type" /> <SelectValue placeholder="Type" />
</SelectTrigger> </SelectTrigger>
@ -205,9 +203,7 @@ function InstallMethod({
<SelectValue placeholder="Version" /> <SelectValue placeholder="Version" />
</SelectTrigger> </SelectTrigger>
<SelectContent> <SelectContent>
{OperatingSystems.find( {OperatingSystems.find((os) => os.name === method.resources.os)?.versions.map((version) => (
(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>
@ -215,22 +211,12 @@ function InstallMethod({
</SelectContent> </SelectContent>
</Select> </Select>
</div> </div>
<Button <Button variant="destructive" size="sm" type="button" onClick={() => removeInstallMethod(index)}>
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 <Button type="button" size="sm" disabled={script.install_methods.length >= 2} onClick={addInstallMethod}>
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", "misc", "turnkey"], { type: z.enum(["vm", "ct", "pve", "addon", "turnkey"], {
errorMap: () => ({ message: "Type must be either 'vm', 'ct', 'misc' or 'turnkey'" }) errorMap: () => ({ message: "Type must be either 'vm', 'ct', 'pve', 'addon' or 'turnkey'" })
}), }),
updateable: z.boolean(), updateable: z.boolean(),
privileged: z.boolean(), privileged: z.boolean(),

View File

@ -5,18 +5,8 @@ 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 { import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
Popover, import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
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";
@ -66,19 +56,29 @@ export default function JSONGenerator() {
.catch((error) => console.error("Error fetching categories:", error)); .catch((error) => console.error("Error fetching categories:", error));
}, []); }, []);
const updateScript = useCallback( const updateScript = useCallback((key: keyof Script, value: Script[keyof Script]) => {
(key: keyof Script, value: Script[keyof Script]) => {
setScript((prev) => { setScript((prev) => {
const updated = { ...prev, [key]: value }; const updated = { ...prev, [key]: value };
if (key === "type" || key === "slug") { if (updated.slug && updated.type) {
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: script: scriptPath,
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,9 +86,7 @@ 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));
@ -120,16 +118,13 @@ 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 <Alert className={cn("text-black", isValid ? "bg-green-100" : "bg-red-100")}>
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
@ -160,21 +155,13 @@ export default function JSONGenerator() {
<Label> <Label>
Name <span className="text-red-500">*</span> Name <span className="text-red-500">*</span>
</Label> </Label>
<Input <Input placeholder="Example" value={script.name} onChange={(e) => updateScript("name", e.target.value)} />
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 <Input placeholder="example" value={script.slug} onChange={(e) => updateScript("slug", e.target.value)} />
placeholder="example"
value={script.slug}
onChange={(e) => updateScript("slug", e.target.value)}
/>
</div> </div>
</div> </div>
<div> <div>
@ -197,11 +184,7 @@ export default function JSONGenerator() {
onChange={(e) => updateScript("description", e.target.value)} onChange={(e) => updateScript("description", e.target.value)}
/> />
</div> </div>
<Categories <Categories script={script} setScript={setScript} 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>
@ -209,10 +192,7 @@ export default function JSONGenerator() {
<PopoverTrigger asChild className="flex-1"> <PopoverTrigger asChild className="flex-1">
<Button <Button
variant={"outline"} variant={"outline"}
className={cn( className={cn("pl-3 text-left font-normal w-full", !script.date_created && "text-muted-foreground")}
"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" />
@ -230,38 +210,26 @@ 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 <Select value={script.type} onValueChange={(value) => updateScript("type", value)}>
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="misc">Miscellaneous</SelectItem> <SelectItem value="pve">PVE-Tool</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 <Switch checked={script.updateable} onCheckedChange={(checked) => updateScript("updateable", checked)} />
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 <Switch checked={script.privileged} onCheckedChange={(checked) => updateScript("privileged", checked)} />
checked={script.privileged}
onCheckedChange={(checked) =>
updateScript("privileged", checked)
}
/>
<label>Privileged</label> <label>Privileged</label>
</div> </div>
</div> </div>
@ -269,12 +237,7 @@ export default function JSONGenerator() {
placeholder="Interface Port" placeholder="Interface Port"
type="number" type="number"
value={script.interface_port || ""} value={script.interface_port || ""}
onChange={(e) => onChange={(e) => updateScript("interface_port", e.target.value ? Number(e.target.value) : null)}
updateScript(
"interface_port",
e.target.value ? Number(e.target.value) : null,
)
}
/> />
<div className="flex gap-2"> <div className="flex gap-2">
<Input <Input
@ -285,17 +248,10 @@ export default function JSONGenerator() {
<Input <Input
placeholder="Documentation URL" placeholder="Documentation URL"
value={script.documentation || ""} value={script.documentation || ""}
onChange={(e) => onChange={(e) => updateScript("documentation", e.target.value || null)}
updateScript("documentation", e.target.value || null)
}
/> />
</div> </div>
<InstallMethod <InstallMethod script={script} setScript={setScript} setIsValid={setIsValid} setZodErrors={setZodErrors} />
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"
@ -317,30 +273,17 @@ export default function JSONGenerator() {
}) })
} }
/> />
<Note <Note script={script} setScript={setScript} setIsValid={setIsValid} setZodErrors={setZodErrors} />
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 <Button size="icon" variant="outline" onClick={handleCopy}>
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 <Button size="icon" variant="outline" onClick={handleDownload}>
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,12 +1,5 @@
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card";
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";
@ -23,7 +16,8 @@ export const getDisplayValueFromType = (type: string) => {
return "LXC"; return "LXC";
case "vm": case "vm":
return "VM"; return "VM";
case "misc": case "pve":
case "addon":
return ""; return "";
default: default:
return ""; return "";
@ -47,8 +41,7 @@ export function LatestScripts({ items }: { items: Category[] }) {
}); });
return Array.from(uniqueScriptsMap.values()).sort( return Array.from(uniqueScriptsMap.values()).sort(
(a, b) => (a, b) => new Date(b.date_created).getTime() - new Date(a.date_created).getTime(),
new Date(b.date_created).getTime() - new Date(a.date_created).getTime(),
); );
}, [items]); }, [items]);
@ -74,18 +67,12 @@ 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 <div className="cursor-pointer select-none p-2 text-sm font-semibold" onClick={goToPreviousPage}>
className="cursor-pointer select-none p-2 text-sm font-semibold"
onClick={goToPreviousPage}
>
Previous Previous
</div> </div>
)} )}
{endIndex < latestScripts.length && ( {endIndex < latestScripts.length && (
<div <div onClick={goToNextPage} className="cursor-pointer select-none p-2 text-sm font-semibold">
onClick={goToNextPage}
className="cursor-pointer select-none p-2 text-sm font-semibold"
>
{page === 1 ? "More.." : "Next"} {page === 1 ? "More.." : "Next"}
</div> </div>
)} )}
@ -94,10 +81,7 @@ 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 <Card key={script.slug} className="min-w-[250px] flex-1 flex-grow bg-accent/30">
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">
@ -107,10 +91,7 @@ export function LatestScripts({ items }: { items: Category[] }) {
height={64} height={64}
width={64} width={64}
alt="" alt=""
onError={(e) => onError={(e) => ((e.currentTarget as HTMLImageElement).src = `/${basePath}/logo.png`)}
((e.currentTarget as HTMLImageElement).src =
`/${basePath}/logo.png`)
}
className="h-11 w-11 object-contain" className="h-11 w-11 object-contain"
/> />
</div> </div>
@ -126,9 +107,7 @@ export function LatestScripts({ items }: { items: Category[] }) {
</CardTitle> </CardTitle>
</CardHeader> </CardHeader>
<CardContent> <CardContent>
<CardDescription className="line-clamp-3 text-card-foreground"> <CardDescription className="line-clamp-3 text-card-foreground">{script.description}</CardDescription>
{script.description}
</CardDescription>
</CardContent> </CardContent>
<CardFooter className=""> <CardFooter className="">
<Button asChild variant="outline"> <Button asChild variant="outline">
@ -151,9 +130,7 @@ 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) => const foundScripts = category.scripts.filter((script) => mostPopularScripts.includes(script.slug));
mostPopularScripts.includes(script.slug),
);
return acc.concat(foundScripts); return acc.concat(foundScripts);
}, []); }, []);
@ -166,10 +143,7 @@ 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 <Card key={script.slug} className="min-w-[250px] flex-1 flex-grow bg-accent/30">
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">
@ -179,10 +153,7 @@ export function MostViewedScripts({ items }: { items: Category[] }) {
height={64} height={64}
width={64} width={64}
alt="" alt=""
onError={(e) => onError={(e) => ((e.currentTarget as HTMLImageElement).src = `/${basePath}/logo.png`)}
((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 Tooltips from "./ScriptItems/Tooltips";
import InterFaces from "./ScriptItems/InterFaces"; import InterFaces from "./ScriptItems/InterFaces";
import Buttons from "./ScriptItems/Buttons"; import Tooltips from "./ScriptItems/Tooltips";
interface ScriptItemProps { interface ScriptItemProps {
item: Script; item: Script;
@ -142,7 +142,9 @@ 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">How to {item.type === "misc" ? "use" : "install"}</h2> <h2 className="text-lg font-semibold">
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,7 +16,17 @@ 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,50 +6,44 @@ 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 return isAlpine ? `bash -c "$(curl -fsSL ${url})"` : `bash -c "$(curl -fsSL ${url})"`;
? `bash -c "$(curl -fsSL ${url})"`
: `bash -c "$(curl -fsSL ${url})"`;
}; };
export default function InstallCommand({ item }: { item: Script }) { export default function InstallCommand({ item }: { item: Script }) {
const alpineScript = item.install_methods.find( const alpineScript = item.install_methods.find((method) => method.type === "alpine");
(method) => method.type === "alpine",
);
const defaultScript = item.install_methods.find( const defaultScript = item.install_methods.find((method) => method.type === "default");
(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{" "} As an alternative option, you can use Alpine Linux and the {item.name} package to create a {item.name}{" "}
{item.name} package to create a {item.name}{" "} {getDisplayValueFromType(item.type)} container with faster creation time and minimal system resource usage.
{getDisplayValueFromType(item.type)} container with faster creation You are also obliged to adhere to updates provided by the package maintainer.
time and minimal system resource usage. You are also obliged to
adhere to updates provided by the package maintainer.
</> </>
) : item.type == "misc" ? ( ) : item.type === "pve" ? (
<> <>
To use the {item.name} script, run the command below in the shell. To use the {item.name} script, run the command below **only** in the Proxmox VE Shell. This script is
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}{" "} To create a new Proxmox VE Alpine-{item.name} {getDisplayValueFromType(item.type)}, run the command below in
{getDisplayValueFromType(item.type)}, run the command below in the the Proxmox VE Shell.
Proxmox VE Shell
</p> </p>
)} )}
</> </>
@ -65,23 +59,17 @@ export default function InstallCommand({ item }: { item: Script }) {
</TabsList> </TabsList>
<TabsContent value="default"> <TabsContent value="default">
{renderInstructions()} {renderInstructions()}
<CodeCopyButton> <CodeCopyButton>{getInstallCommand(defaultScript?.script)}</CodeCopyButton>
{getInstallCommand(defaultScript?.script)}
</CodeCopyButton>
</TabsContent> </TabsContent>
<TabsContent value="alpine"> <TabsContent value="alpine">
{renderInstructions(true)} {renderInstructions(true)}
<CodeCopyButton> <CodeCopyButton>{getInstallCommand(alpineScript.script, true)}</CodeCopyButton>
{getInstallCommand(alpineScript.script, true)}
</CodeCopyButton>
</TabsContent> </TabsContent>
</Tabs> </Tabs>
) : defaultScript?.script ? ( ) : defaultScript?.script ? (
<> <>
{renderInstructions()} {renderInstructions()}
<CodeCopyButton> <CodeCopyButton>{getInstallCommand(defaultScript.script)}</CodeCopyButton>
{getInstallCommand(defaultScript.script)}
</CodeCopyButton>
</> </>
) : null} ) : null}
</div> </div>

View File

@ -6,6 +6,7 @@ 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";
@ -15,18 +16,17 @@ 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 ( return <Badge className="text-yellow-500/75 border-yellow-500/75">LXC</Badge>;
<Badge className="text-yellow-500/75 border-yellow-500/75">LXC</Badge> case "pve":
); return <Badge className="text-orange-500/75 border-orange-500/75">PVE</Badge>;
case "misc": case "addon":
return <Badge className="text-green-500/75 border-green-500/75">MISC</Badge>; return <Badge className="text-green-500/75 border-green-500/75">ADDON</Badge>;
} }
return null; return null;
}; };
@ -84,14 +84,9 @@ 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> <CommandEmpty>{isLoading ? "Loading..." : "No scripts found."}</CommandEmpty>
{isLoading ? "Loading..." : "No scripts found."}
</CommandEmpty>
{links.map((category) => ( {links.map((category) => (
<CommandGroup <CommandGroup key={`category:${category.name}`} heading={category.name}>
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}`}
@ -104,10 +99,7 @@ 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) => onError={(e) => ((e.currentTarget as HTMLImageElement).src = `/${basePath}/logo.png`)}
((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" | "misc"; type: "vm" | "ct" | "pve" | "addon";
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/misc/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/tools/addon/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"

Binary file not shown.

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/misc/copy-data/home-assistant-container-copy-data-home-assistant-container.sh)" bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/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/misc/copy-data/home-assistant-container-copy-data-home-assistant-core.sh)" bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/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/misc/copy-data/home-assistant-container-copy-data-podman-home-assistant.sh)" bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/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/misc/copy-data/podman-home-assistant-copy-data-home-assistant-container.sh)" bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/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/misc/copy-data/home-assistant-core-copy-data-home-assistant-container.sh)" bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/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/misc/copy-data/home-assistant-core-copy-data-home-assistant-core.sh)" bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/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/misc/copy-data/plex-copy-data-plex.sh)" bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/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/misc/copy-data/z2m-copy-data-z2m.sh)" bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/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/misc/copy-data/zwavejs2mqtt-copy-data-zwavejsui.sh)" bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/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/main/misc/copy-data/home-assistant-container-copy-data-home-assistant-container.sh)" # bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/mainmain/tools/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/main/misc/copy-data/home-assistant-container-copy-data-home-assistant-core.sh)" # bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/mainmain/tools/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/main/misc/copy-data/home-assistant-container-copy-data-podman-home-assistant.sh)" # bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/mainmain/tools/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/main/misc/copy-data/home-assistant-core-copy-data-home-assistant-container.sh)" # bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/mainmain/tools/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/main/misc/copy-data/home-assistant-core-copy-data-home-assistant-core.sh)" # bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/mainmain/tools/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/main/misc/copy-data/plex-copy-data-plex.sh)" # bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/mainmain/tools/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/main/misc/copy-data/podman-home-assistant-copy-data-home-assistant-container.sh)" # bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/mainmain/tools/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/main/misc/copy-data/z2m-copy-data-z2m.sh)" # bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/mainmain/tools/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/main/misc/copy-data/zwavejs2mqtt-copy-data-zwavejsui.sh)" # bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/mainmain/tools/copy-data//zwavejs2mqtt-copy-data-zwavejsui.sh)"