forked from forkanization/Proxmox-arm64
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1611df15b0 | |||
| a74611e979 | |||
| f0478feb12 |
+14
-136
@@ -3,149 +3,27 @@
|
|||||||
<img src="https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/logo.png" height="100px" />
|
<img src="https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/logo.png" height="100px" />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<h1 align="center">Changelog</h1>
|
<h1 align="center">Change Log</h1>
|
||||||
|
|
||||||
<h3 align="center">All notable changes to this project will be documented in this file.</h3>
|
<h3 align="center">All notable changes to this project will be documented in this file.</h3>
|
||||||
|
|
||||||
> [!CAUTION]
|
- All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment.
|
||||||
Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit the project's popularity for potentially malicious purposes.
|
|
||||||
|
|
||||||
> [!NOTE]
|
|
||||||
All LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment.
|
|
||||||
|
|
||||||
## 2024-10-27
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
- **Open WebUI LXC** [(Commit)](https://github.com/tteck/Proxmox/commit/8a21f6e7f025a911865395d4c0fa9a001bd0d512)
|
|
||||||
- Refactor Script to add an option to install Ollama.
|
|
||||||
|
|
||||||
## 2024-10-26
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
- **AdventureLog LXC** [(View Source)](https://github.com/tteck/Proxmox/blob/main/install/adventurelog-install.sh)
|
|
||||||
- NEW Script
|
|
||||||
|
|
||||||
## 2024-10-25
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
- **Zoraxy LXC** [(Commit)](https://github.com/tteck/Proxmox/commit/468a5d367ded4cf453a1507452e112ac3e234e2a)
|
|
||||||
- Switch built from source to a pre-compiled binary version.
|
|
||||||
- Breaking Change
|
|
||||||
|
|
||||||
## 2024-10-23
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
- **Wallos LXC** [(View Source)](https://github.com/tteck/Proxmox/blob/main/install/wallos-install.sh)
|
|
||||||
- NEW Script
|
|
||||||
- **Open WebUI LXC** [(View Source)](https://github.com/tteck/Proxmox/blob/main/install/openwebui-install.sh)
|
|
||||||
- NEW Script
|
|
||||||
|
|
||||||
## 2024-10-19
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
- **Cockpit LXC** [(View Source)](https://github.com/tteck/Proxmox/blob/main/install/cockpit-install.sh)
|
|
||||||
- NEW Script
|
|
||||||
- **Neo4j LXC** [(View Source)](https://github.com/tteck/Proxmox/blob/main/install/neo4j-install.sh)
|
|
||||||
- NEW Script
|
|
||||||
|
|
||||||
## 2024-10-18
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
- **ArchiveBox LXC** [(View Source)](https://github.com/tteck/Proxmox/blob/main/install/archivebox-install.sh)
|
|
||||||
- NEW Script
|
|
||||||
|
|
||||||
## 2024-10-15
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
- **evcc LXC** [(View Source)](https://github.com/tteck/Proxmox/blob/main/install/evcc-install.sh)
|
|
||||||
- NEW Script
|
|
||||||
|
|
||||||
## 2024-10-10
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
- **MySQL LXC** [(View Source)](https://github.com/tteck/Proxmox/blob/main/install/mysql-install.sh)
|
|
||||||
- NEW Script
|
|
||||||
- **Tianji LXC** [(Commit)](https://github.com/tteck/Proxmox/commit/4c83a790ac9b040da1f11ad2cbe13d3fc5f480e9)
|
|
||||||
- Breaking Change
|
|
||||||
- Switch from `pm2` process management to `systemd`
|
|
||||||
|
|
||||||
## 2024-10-03
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
- **Home Assistant Core LXC** [(Commit)](https://github.com/tteck/Proxmox/commit/f2937febe69b2bad8b3a14eb84aa562a8f14cc6a) [(Commit)](https://github.com/tteck/Proxmox/commit/f2966ced7f457fd506f865f7f5b70ea12c4b0049)
|
|
||||||
- Refactor Code
|
|
||||||
- Breaking Change
|
|
||||||
- Home Assistant has transitioned to using `uv` for managing the virtual environment and installing additional modules.
|
|
||||||
|
|
||||||
## 2024-09-16
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
- **HomeBox LXC** [(View Source)](https://github.com/tteck/Proxmox/blob/main/install/homebox-install.sh)
|
|
||||||
- NEW Script
|
|
||||||
- **Zipline LXC** [(View Source)](https://github.com/tteck/Proxmox/blob/main/install/zipline-install.sh)
|
|
||||||
- NEW Script
|
|
||||||
|
|
||||||
## 2024-09-13
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
- **Tianji LXC** [(View Source)](https://github.com/tteck/Proxmox/blob/main/install/tianji-install.sh)
|
|
||||||
- NEW Script
|
|
||||||
|
|
||||||
## 2024-08-21
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
- **WireGuard LXC** [(Commit)](https://github.com/tteck/Proxmox/commit/723365a79df7cc0fd29b1af8f7ef200a7e0921b1)
|
|
||||||
- Refactor Code
|
|
||||||
- Breaking Change
|
|
||||||
|
|
||||||
## 2024-08-19
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
- **CommaFeed LXC** [(Commit)](https://github.com/tteck/Proxmox/commit/0a33d1739ec3a49011411929bd46a260e92e99f9)
|
|
||||||
- Refactor Code
|
|
||||||
- Breaking Change
|
|
||||||
|
|
||||||
## 2024-08-06
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
- **lldap LXC** [(View Source)](https://github.com/tteck/Proxmox/blob/main/install/lldap-install.sh)
|
|
||||||
- NEW Script
|
|
||||||
|
|
||||||
## 2024-07-26
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
- **Gitea LXC** [(View Source)](https://github.com/tteck/Proxmox/blob/main/install/gitea-install.sh)
|
|
||||||
- NEW Script
|
|
||||||
|
|
||||||
## 2024-06-30
|
## 2024-06-30
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- **All Scripts** [(Commit)](https://github.com/tteck/Proxmox/commit/39ea1d4a20b83c07d084ebafdc811eec3548f289)
|
- **All Scripts**
|
||||||
- Requires Proxmox Virtual Environment version 8.1 or later.
|
- Requires Proxmox Virtual Environment version 8.1 or later.
|
||||||
|
|
||||||
## 2024-06-27
|
## 2024-06-27
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- **Kubo LXC** [(View Source)](https://github.com/tteck/Proxmox/blob/main/install/kubo-install.sh)
|
- **Kubo LXC**
|
||||||
- NEW Script
|
- NEW Script
|
||||||
- **RabbitMQ LXC** [(View Source)](https://github.com/tteck/Proxmox/blob/main/install/rabbitmq-install.sh)
|
- **RabbitMQ LXC**
|
||||||
- NEW Script
|
- NEW Script
|
||||||
- **Scrutiny LXC**
|
- **Scrutiny LXC**
|
||||||
- Removed from website, broken.
|
- Removed from website, broken.
|
||||||
@@ -161,27 +39,27 @@ All LXC instances created using this repository come pre-installed with Midnight
|
|||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- **MySpeed LXC** [(View Source)](https://github.com/tteck/Proxmox/blob/main/install/myspeed-install.sh)
|
- **MySpeed LXC**
|
||||||
- NEW Script
|
- NEW Script
|
||||||
|
|
||||||
## 2024-06-13
|
## 2024-06-13
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- **PeaNUT LXC** [(View Source)](https://github.com/tteck/Proxmox/blob/main/install/peanut-install.sh)
|
- **PeaNUT LXC**
|
||||||
- NEW Script
|
- NEW Script
|
||||||
- **Website**
|
- **Website**
|
||||||
- If the Changelog has changed recently, the link on the website will pulse.
|
- If the Changelog has changed recently, the link on the website will pulse.
|
||||||
- **Spoolman LXC** [(View Source)](https://github.com/tteck/Proxmox/blob/main/install/spoolman-install.sh)
|
- **Spoolman LXC**
|
||||||
- NEW Script
|
- NEW Script
|
||||||
|
|
||||||
## 2024-06-12
|
## 2024-06-12
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- **MeTube LXC** [(View Source)](https://github.com/tteck/Proxmox/blob/main/install/metube-install.sh)
|
- **MeTube LXC**
|
||||||
- NEW Script
|
- NEW Script
|
||||||
- **Matterbridge LXC** [(View Source)](https://github.com/tteck/Proxmox/blob/main/install/matterbridge-install.sh)
|
- **Matterbridge LXC**
|
||||||
- NEW Script
|
- NEW Script
|
||||||
- **Website**
|
- **Website**
|
||||||
- Reopen the gh-pages site (https://tteck.github.io/Proxmox/)
|
- Reopen the gh-pages site (https://tteck.github.io/Proxmox/)
|
||||||
@@ -190,14 +68,14 @@ All LXC instances created using this repository come pre-installed with Midnight
|
|||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- **Zabbix LXC** [(View Source)](https://github.com/tteck/Proxmox/blob/main/install/zabbix-install.sh)
|
- **Zabbix LXC**
|
||||||
- NEW Script
|
- NEW Script
|
||||||
|
|
||||||
## 2024-06-06
|
## 2024-06-06
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- **Petio LXC** [(View Source)](https://github.com/tteck/Proxmox/blob/main/install/petio-install.sh)
|
- **Petio LXC**
|
||||||
- NEW Script
|
- NEW Script
|
||||||
- **Website**
|
- **Website**
|
||||||
- Important notices will now be displayed on the landing page.
|
- Important notices will now be displayed on the landing page.
|
||||||
@@ -206,14 +84,14 @@ All LXC instances created using this repository come pre-installed with Midnight
|
|||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- **FlareSolverr LXC** [(View Source)](https://github.com/tteck/Proxmox/blob/main/install/flaresolverr-install.sh)
|
- **FlareSolverr LXC**
|
||||||
- NEW Script
|
- NEW Script
|
||||||
|
|
||||||
## 2024-05-31
|
## 2024-05-31
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- **Advanced Settings** [(Commit)](https://github.com/tteck/Proxmox/commit/fc9dff220b4ea426d3a75178ad8accacae4683ca)
|
- **Advanced Settings**
|
||||||
- Passwords are now masked
|
- Passwords are now masked
|
||||||
|
|
||||||
## 2024-05-30
|
## 2024-05-30
|
||||||
|
|||||||
@@ -31,6 +31,199 @@ Any issues with the scripts, please put an issue within this repository rather t
|
|||||||
|
|
||||||
If you would like to offer support, I would appreciate a star on the repository, or for you to support the creator of the Proxmox scripts [tteck on Ko-Fi](https://ko-fi.com/D1D7EP4GF)!
|
If you would like to offer support, I would appreciate a star on the repository, or for you to support the creator of the Proxmox scripts [tteck on Ko-Fi](https://ko-fi.com/D1D7EP4GF)!
|
||||||
|
|
||||||
## Compatibility Guide
|
## VM Compatibility Guide
|
||||||
|
|
||||||
[View Compatibility Guide here](https://pimox-scripts.com)
|
| Icon | Description |
|
||||||
|
| ---- | -------------------------------------------------- |
|
||||||
|
| ☑️ | Creating the LXC using the script has been tested. |
|
||||||
|
| ⭕ | Install script is ported, but has not been tested. |
|
||||||
|
| ❌ | Unsupported. View notes for reason. |
|
||||||
|
| 🔘 | Install script not ported to ARM64. |
|
||||||
|
|
||||||
|
| OS | Status | Notes |
|
||||||
|
| ------------------------------- | ------ | -------------------------------------------------------------------------------------------------------- |
|
||||||
|
| Debian | ⭕ | Needs testing. |
|
||||||
|
| Home Assistant OS | ❌ | Use Pimox HAOS VM script. |
|
||||||
|
| Mikrotik RouterOS | ❌ | No arm64 image available. |
|
||||||
|
| NextCloud | ❌ | No arm64 image available. Not present on website. |
|
||||||
|
| OpenWRT | ⭕ | Needs testing. |
|
||||||
|
| OwnCloud | ❌ | No arm64 image available. |
|
||||||
|
| Pimox HAOS | ☑️ | |
|
||||||
|
| Ubuntu 22.04 | ⭕ | Needs testing. |
|
||||||
|
| Ubuntu 24.04 | ⭕ | Needs testing. |
|
||||||
|
|
||||||
|
## LXC Compatibility Guide
|
||||||
|
|
||||||
|
| App | Status | Notes |
|
||||||
|
| ------------------------------- | ------ | -------------------------------------------------------------------------------------------------------- |
|
||||||
|
| Actual Budget | ☑️ | |
|
||||||
|
| AdGuard Home | ☑️ | |
|
||||||
|
| AgentDVR | ☑️ | |
|
||||||
|
| Apache-Cassandra | ☑️ | |
|
||||||
|
| Alpine Docker | ☑️ | |
|
||||||
|
| Alpine Grafana | ☑️ | |
|
||||||
|
| Alpine | ☑️ | |
|
||||||
|
| Alpine Nextcloud | ☑️ | |
|
||||||
|
| Alpine Vaultwarden | ☑️ | |
|
||||||
|
| Alpine Zigbee2mqtt | ☑️ | |
|
||||||
|
| Apache-CouchDB | ☑️ | |
|
||||||
|
| Apt-Cacher-NG | ☑️ | Won't work with Debian template from before 2024/06/08 (need to delete tar /var/lib/vz/template/cache/). |
|
||||||
|
| Aria2 | ☑️ | |
|
||||||
|
| Audiobookshelf | ☑️ | |
|
||||||
|
| Autobrr | ☑️ | |
|
||||||
|
| Bazarr | ☑️ | |
|
||||||
|
| Blocky | ☑️ | |
|
||||||
|
| Caddy | ☑️ | |
|
||||||
|
| Calibre-Web | ☑️ | |
|
||||||
|
| CasaOS | ☑️ | |
|
||||||
|
| Change Detection | ☑️ | |
|
||||||
|
| Channels DVR Server | ☑️ | |
|
||||||
|
| Cloudflared | ☑️ | |
|
||||||
|
| CommaFeed | ☑️ | |
|
||||||
|
| Cronicle Primary | ☑️ | |
|
||||||
|
| Dashy | ☑️ | |
|
||||||
|
| deCONZ | ☑️ | |
|
||||||
|
| Daemon Sync Server | ❌ | Built for x64 only. |
|
||||||
|
| Debian | ☑️ | |
|
||||||
|
| Deluge | ☑️ | |
|
||||||
|
| Docker | ☑️ | |
|
||||||
|
| Dockge | ☑️ | |
|
||||||
|
| Emby Media Server | ☑️ | |
|
||||||
|
| EMQX | ☑️ | |
|
||||||
|
| ErsatzTV | ☑️ | |
|
||||||
|
| ESPHome | ☑️ | |
|
||||||
|
| Fenrus | ☑️ | |
|
||||||
|
| FHEM | ☑️ | |
|
||||||
|
| FlareSolverr | ☑️ | |
|
||||||
|
| FlowiseAI | ☑️ | |
|
||||||
|
| Forgejo | ☑️ | |
|
||||||
|
| Frigate | ☑️ | |
|
||||||
|
| go2rtc | ☑️ | |
|
||||||
|
| Gokapi | ☑️ | |
|
||||||
|
| Gotify | ☑️ | |
|
||||||
|
| Grafana | ☑️ | |
|
||||||
|
| grocy | ☑️ | |
|
||||||
|
| Heimdall Dashboard | ☑️ | |
|
||||||
|
| HiveMQ CE | ☑️ | |
|
||||||
|
| Homarr | ☑️ | |
|
||||||
|
| Home Assistant Core | ☑️ | |
|
||||||
|
| Home Assistant Container | ☑️ | |
|
||||||
|
| Homebridge | ☑️ | |
|
||||||
|
| Homepage | ☑️ | |
|
||||||
|
| Homer | ☑️ | |
|
||||||
|
| HyperHDR | ☑️ | |
|
||||||
|
| Hyperion | ☑️ | |
|
||||||
|
| InfluxDB | ☑️ | |
|
||||||
|
| ioBroker | ☑️ | |
|
||||||
|
| iVentoy | ☑️ | |
|
||||||
|
| Jackett | ☑️ | |
|
||||||
|
| Jellyfin Media Server | ☑️ | |
|
||||||
|
| Jellyseerr | ☑️ | |
|
||||||
|
| k0s | ☑️ | |
|
||||||
|
| Kavita | ☑️ | |
|
||||||
|
| Keycloak | ☑️ | |
|
||||||
|
| Kubo | ☑️ | |
|
||||||
|
| LazyLibrarian | ☑️ | |
|
||||||
|
| Lidarr | ☑️ | |
|
||||||
|
| Linkwarden | ☑️ | |
|
||||||
|
| Mafl | ☑️ | |
|
||||||
|
| MagicMirror Server | ☑️ | |
|
||||||
|
| Mariadb | ☑️ | |
|
||||||
|
| Matterbridge | ☑️ | |
|
||||||
|
| MediaMTX | ☑️ | |
|
||||||
|
| Medusa | ☑️ | |
|
||||||
|
| MeshCentral | ☑️ | |
|
||||||
|
| MeTube | ☑️ | |
|
||||||
|
| MongoDB | ☑️ | Only supports ARMv8.2-a currently. (no RPI4 support). |
|
||||||
|
| MotionEye NVR | ☑️ | |
|
||||||
|
| MQTT | ☑️ | |
|
||||||
|
| n8n | ☑️ | |
|
||||||
|
| MySpeed | ☑️ | |
|
||||||
|
| Navidrome | ☑️ | |
|
||||||
|
| NextCloudPi | ☑️ | |
|
||||||
|
| Nginx Proxy Manager | ☑️ | |
|
||||||
|
| NocoDB | ☑️ | |
|
||||||
|
| Node-Red | ☑️ | |
|
||||||
|
| Notifiarr | ☑️ | |
|
||||||
|
| ntfy | ☑️ | |
|
||||||
|
| OctoPrint | ☑️ | |
|
||||||
|
| Omada Controller | ☑️ | |
|
||||||
|
| Ombi | ☑️ | |
|
||||||
|
| OpenMediaVault | ☑️ | |
|
||||||
|
| openHAB | ☑️ | |
|
||||||
|
| OpenObserve | ☑️ | |
|
||||||
|
| Overseerr | ☑️ | |
|
||||||
|
| Owncast | ☑️ | |
|
||||||
|
| PairDrop | ☑️ | |
|
||||||
|
| Paperless-ngx | ☑️ | |
|
||||||
|
| PBS | ☑️ | Proxmox Backup Server |
|
||||||
|
| PeaNUT | ☑️ | |
|
||||||
|
| Petio | ☑️ | Only supports ARMv8.2-a currently. (no RPI4 support). |
|
||||||
|
| PhotoPrism | ☑️ | |
|
||||||
|
| Pi.Alert | ☑️ | |
|
||||||
|
| Pi-Hole | ☑️ | |
|
||||||
|
| Pingvin Share | ☑️ | |
|
||||||
|
| Plex Media Server | ☑️ | |
|
||||||
|
| Pocketbase | ☑️ | |
|
||||||
|
| Podman Home Assistant Container | ☑️ | |
|
||||||
|
| Podman | ☑️ | |
|
||||||
|
| PostgreSQL | ☑️ | |
|
||||||
|
| Prometheus | ☑️ | |
|
||||||
|
| Prowlarr | ☑️ | |
|
||||||
|
| qBittorrent | ☑️ | |
|
||||||
|
| RabbitMQ | ☑️ | |
|
||||||
|
| Radarr | ☑️ | |
|
||||||
|
| RDTClient | ☑️ | Real-Debrid Torrent Client |
|
||||||
|
| Readarr | ☑️ | |
|
||||||
|
| Readeck | ☑️ | |
|
||||||
|
| Redis | ☑️ | |
|
||||||
|
| RTSPtoWeb | ☑️ | |
|
||||||
|
| Runtipi | ☑️ | |
|
||||||
|
| SABnzbd | ☑️ | |
|
||||||
|
| Scrypted | ☑️ | |
|
||||||
|
| Scrutiny | ☑️ | |
|
||||||
|
| SFTPGo | ☑️ | |
|
||||||
|
| Shinobi NVR | ☑️ | |
|
||||||
|
| SmokePing | ☑️ | |
|
||||||
|
| Sonarr | ☑️ | |
|
||||||
|
| SpoolMan | ☑️ | |
|
||||||
|
| Stirling-PDF | ☑️ | |
|
||||||
|
| Syncthing | ☑️ | |
|
||||||
|
| Tandoor Recipes | ☑️ | |
|
||||||
|
| TasmoAdmin | ☑️ | |
|
||||||
|
| Tautulli | ☑️ | |
|
||||||
|
| Tdarr | ☑️ | |
|
||||||
|
| Technitium DNS | ☑️ | |
|
||||||
|
| Threadfin | ☑️ | |
|
||||||
|
| Traccar | ☑️ | |
|
||||||
|
| Traefik | ☑️ | |
|
||||||
|
| Transmission | ☑️ | |
|
||||||
|
| Trilium | ❌ | Built for x64 only. |
|
||||||
|
| Umami | ☑️ | |
|
||||||
|
| Ubuntu | ☑️ | |
|
||||||
|
| Umbrel | ☑️ | |
|
||||||
|
| UniFi Network Server | ☑️ | |
|
||||||
|
| Unmanic | ☑️ | |
|
||||||
|
| Uptime Kuma | ☑️ | |
|
||||||
|
| Vaultwarden | ☑️ | Will probably work on default install if you have a lot of ram. Otherwise use the Alpine Linux version. |
|
||||||
|
| Wastebin | ☑️ | |
|
||||||
|
| WatchYourLAN | ☑️ | |
|
||||||
|
| Whisparr | ☑️ | |
|
||||||
|
| Whoogle | ☑️ | |
|
||||||
|
| Wiki.js | ☑️ | |
|
||||||
|
| WireGuard | ☑️ | |
|
||||||
|
| YunoHost | ☑️ | |
|
||||||
|
| Zabbix | ☑️ | |
|
||||||
|
| Zigbee2MQTT | ☑️ | |
|
||||||
|
| Zoraxy | ☑️ | |
|
||||||
|
| Z-Wave JS UI | ☑️ | |
|
||||||
|
|
||||||
|
## Miscellaneous Compatibility Guide
|
||||||
|
|
||||||
|
| Script | Status | Notes |
|
||||||
|
| -------------- | ------ | -------------------- |
|
||||||
|
| File Browser | ☑️ | |
|
||||||
|
| OliveTin | ☑️ | |
|
||||||
|
| NetBird | ☑️ | No changes required. |
|
||||||
|
| Tailscale | ☑️ | No changes required. |
|
||||||
|
| VS Code Server | ☑️ | |
|
||||||
|
|||||||
@@ -38,7 +38,3 @@
|
|||||||
[Proxmox + NetData](<https://dbt3ch.com/books/proxmox-netdata-for-better-insights-and-notifications/page/proxmox-netdata-for-better-insights-and-notifications>)
|
[Proxmox + NetData](<https://dbt3ch.com/books/proxmox-netdata-for-better-insights-and-notifications/page/proxmox-netdata-for-better-insights-and-notifications>)
|
||||||
|
|
||||||
[Proxmox Homelab Series](<https://blog.kye.dev/proxmox-series>)
|
[Proxmox Homelab Series](<https://blog.kye.dev/proxmox-series>)
|
||||||
|
|
||||||
[The fastest installation of Docker and Portainer on Proxmox VE](https://lavr.site/en-fastest-install-docker-portainer-proxmox/)
|
|
||||||
|
|
||||||
[How To Setup Proxmox Backuper Server Using Helper Scripts](<https://youtu.be/6C2JOsrZZZw?si=kkrrcL_nLCDBJkOB>)
|
|
||||||
|
|||||||
@@ -1,110 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2024 tteck
|
|
||||||
# Author: tteck
|
|
||||||
# Co-Author: MickLesk (Canbiz)
|
|
||||||
# License: MIT
|
|
||||||
# https://github.com/tteck/Proxmox/raw/main/LICENSE
|
|
||||||
|
|
||||||
function header_info {
|
|
||||||
clear
|
|
||||||
cat <<"EOF"
|
|
||||||
___ __ __ __
|
|
||||||
/ | ____/ / _____ ____ / /___ __________ / / ____ ____ _
|
|
||||||
/ /| |/ __ / | / / _ \/ __ \/ __/ / / / ___/ _ \/ / / __ \/ __ `/
|
|
||||||
/ ___ / /_/ /| |/ / __/ / / / /_/ /_/ / / / __/ /___/ /_/ / /_/ /
|
|
||||||
/_/ |_\__,_/ |___/\___/_/ /_/\__/\__,_/_/ \___/_____/\____/\__, /
|
|
||||||
/____/
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
header_info
|
|
||||||
echo -e "Loading..."
|
|
||||||
APP="AdventureLog"
|
|
||||||
var_disk="7"
|
|
||||||
var_cpu="2"
|
|
||||||
var_ram="2048"
|
|
||||||
var_os="debian"
|
|
||||||
var_version="12"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function default_settings() {
|
|
||||||
CT_TYPE="1"
|
|
||||||
PW=""
|
|
||||||
CT_ID=$NEXTID
|
|
||||||
HN=$NSAPP
|
|
||||||
DISK_SIZE="$var_disk"
|
|
||||||
CORE_COUNT="$var_cpu"
|
|
||||||
RAM_SIZE="$var_ram"
|
|
||||||
BRG="vmbr0"
|
|
||||||
NET="dhcp"
|
|
||||||
GATE=""
|
|
||||||
APT_CACHER=""
|
|
||||||
APT_CACHER_IP=""
|
|
||||||
DISABLEIP6="no"
|
|
||||||
MTU=""
|
|
||||||
SD=""
|
|
||||||
NS=""
|
|
||||||
MAC=""
|
|
||||||
VLAN=""
|
|
||||||
SSH="no"
|
|
||||||
VERB="no"
|
|
||||||
echo_default
|
|
||||||
}
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
if [[ ! -d /opt/adventurelog ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
|
||||||
if (( $(df /boot | awk 'NR==2{gsub("%","",$5); print $5}') > 80 )); then
|
|
||||||
read -r -p "Warning: Storage is dangerously low, continue anyway? <y/N> " prompt
|
|
||||||
[[ ${prompt,,} =~ ^(y|yes)$ ]] || exit
|
|
||||||
fi
|
|
||||||
RELEASE=$(curl -s https://api.github.com/repos/seanmorley15/AdventureLog/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
|
|
||||||
if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then
|
|
||||||
msg_info "Stopping Services"
|
|
||||||
systemctl stop adventurelog-backend
|
|
||||||
systemctl stop adventurelog-frontend
|
|
||||||
msg_ok "Services Stopped"
|
|
||||||
|
|
||||||
msg_info "Updating ${APP} to ${RELEASE}"
|
|
||||||
cp /opt/adventurelog/backend/server/.env /opt/server.env
|
|
||||||
cp /opt/adventurelog/frontend/env /opt/frontend.env
|
|
||||||
wget -q "https://github.com/seanmorley15/AdventureLog/archive/refs/tags/v${RELEASE}.zip"
|
|
||||||
unzip -q v${RELEASE}.zip
|
|
||||||
mv AdventureLog-${RELEASE} /opt/adventurelog
|
|
||||||
mv /opt/server.env /opt/adventurelog/backend/server/.env
|
|
||||||
cd /opt/adventurelog/backend/server
|
|
||||||
pip install --upgrade pip &>/dev/null
|
|
||||||
pip install -r requirements.txt &>/dev/null
|
|
||||||
python3 manage.py collectstatic --noinput &>/dev/null
|
|
||||||
python3 manage.py migrate &>/dev/null
|
|
||||||
|
|
||||||
mv /opt/frontend.env /opt/adventurelog/frontend/.env
|
|
||||||
cd /opt/adventurelog/frontend
|
|
||||||
pnpm install &>/dev/null
|
|
||||||
pnpm run build &>/dev/null
|
|
||||||
echo "${RELEASE}" >/opt/${APP}_version.txt
|
|
||||||
msg_ok "Updated ${APP}"
|
|
||||||
|
|
||||||
msg_info "Starting Services"
|
|
||||||
systemctl start adventurelog-backend
|
|
||||||
systemctl start adventurelog-frontend
|
|
||||||
msg_ok "Started Services"
|
|
||||||
|
|
||||||
msg_info "Cleaning Up"
|
|
||||||
rm -rf v${RELEASE}.zip
|
|
||||||
msg_ok "Cleaned"
|
|
||||||
msg_ok "Updated Successfully"
|
|
||||||
else
|
|
||||||
msg_ok "No update required. ${APP} is already at ${RELEASE}"
|
|
||||||
fi
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed Successfully!\n"
|
|
||||||
echo -e "${APP} Setup should be reachable by going to the following URL.
|
|
||||||
${BL}http://${IP}:3000${CL} \n"
|
|
||||||
@@ -71,7 +71,7 @@ function update_script() {
|
|||||||
header_info
|
header_info
|
||||||
case $CHOICE in
|
case $CHOICE in
|
||||||
1)
|
1)
|
||||||
apk update && apk upgrade && rc-service vaultwarden restart -q
|
apk update && apk upgrade
|
||||||
exit
|
exit
|
||||||
;;
|
;;
|
||||||
2)
|
2)
|
||||||
|
|||||||
@@ -1,86 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -s https://raw.githubusercontent.com/asylumexp/Proxmox/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2024 tteck
|
|
||||||
# Author: tteck
|
|
||||||
# License: MIT
|
|
||||||
# https://github.com/tteck/Proxmox/raw/main/LICENSE
|
|
||||||
|
|
||||||
function header_info {
|
|
||||||
clear
|
|
||||||
cat <<"EOF"
|
|
||||||
___ __ _ ____
|
|
||||||
/ | __________/ /_ (_) _____ / __ )____ _ __
|
|
||||||
/ /| | / ___/ ___/ __ \/ / | / / _ \/ __ / __ \| |/_/
|
|
||||||
/ ___ |/ / / /__/ / / / /| |/ / __/ /_/ / /_/ /> <
|
|
||||||
/_/ |_/_/ \___/_/ /_/_/ |___/\___/_____/\____/_/|_|
|
|
||||||
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
header_info
|
|
||||||
echo -e "Loading..."
|
|
||||||
APP="ArchiveBox"
|
|
||||||
var_disk="8"
|
|
||||||
var_cpu="2"
|
|
||||||
var_ram="1024"
|
|
||||||
var_os="debian"
|
|
||||||
var_version="12"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function default_settings() {
|
|
||||||
CT_TYPE="1"
|
|
||||||
PW=""
|
|
||||||
CT_ID=$NEXTID
|
|
||||||
HN=$NSAPP
|
|
||||||
DISK_SIZE="$var_disk"
|
|
||||||
CORE_COUNT="$var_cpu"
|
|
||||||
RAM_SIZE="$var_ram"
|
|
||||||
BRG="vmbr0"
|
|
||||||
NET="dhcp"
|
|
||||||
GATE=""
|
|
||||||
APT_CACHER=""
|
|
||||||
APT_CACHER_IP=""
|
|
||||||
DISABLEIP6="no"
|
|
||||||
MTU=""
|
|
||||||
SD=""
|
|
||||||
NS=""
|
|
||||||
MAC=""
|
|
||||||
VLAN=""
|
|
||||||
SSH="no"
|
|
||||||
VERB="no"
|
|
||||||
echo_default
|
|
||||||
}
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
if [[ ! -d /opt/archivebox ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
|
||||||
if (( $(df /boot | awk 'NR==2{gsub("%","",$5); print $5}') > 80 )); then
|
|
||||||
read -r -p "Warning: Storage is dangerously low, continue anyway? <y/N> " prompt
|
|
||||||
[[ ${prompt,,} =~ ^(y|yes)$ ]] || exit
|
|
||||||
fi
|
|
||||||
msg_info "Stopping ${APP}"
|
|
||||||
systemctl stop archivebox
|
|
||||||
msg_ok "Stopped ${APP}"
|
|
||||||
|
|
||||||
msg_info "Updating ${APP}"
|
|
||||||
cd /opt/archivebox/data
|
|
||||||
pip install --upgrade --ignore-installed archivebox
|
|
||||||
sudo -u archivebox archivebox init
|
|
||||||
msg_ok "Updated ${APP}"
|
|
||||||
|
|
||||||
msg_info "Starting ${APP}"
|
|
||||||
systemctl start archivebox
|
|
||||||
msg_ok "Started ${APP}"
|
|
||||||
|
|
||||||
msg_ok "Updated Successfully"
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed Successfully!\n"
|
|
||||||
echo -e "${APP} should be reachable by going to the following URL.
|
|
||||||
${BL}http://${IP}:8000/admin/login${CL} \n"
|
|
||||||
+5
-20
@@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
source <(curl -s https://raw.githubusercontent.com/asylumexp/Proxmox/main/misc/build.func)
|
source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)
|
||||||
# Copyright (c) 2021-2024 tteck
|
# Copyright (c) 2021-2024 tteck
|
||||||
# Author: tteck (tteckster)
|
# Author: tteck (tteckster)
|
||||||
# License: MIT
|
# License: MIT
|
||||||
@@ -55,25 +55,10 @@ function default_settings() {
|
|||||||
function update_script() {
|
function update_script() {
|
||||||
header_info
|
header_info
|
||||||
if [[ ! -d /etc/bunkerweb ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
if [[ ! -d /etc/bunkerweb ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
||||||
|
msg_info "Updating $APP"
|
||||||
RELEASE=$(curl -s https://api.github.com/repos/bunkerity/bunkerweb/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
|
apt-get update &>/dev/null
|
||||||
if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then
|
apt-get -y upgrade &>/dev/null
|
||||||
|
msg_ok "Updated $APP"
|
||||||
msg_info "Updating ${APP} to ${RELEASE}"
|
|
||||||
cat <<EOF >/etc/apt/preferences.d/bunkerweb
|
|
||||||
Package: bunkerweb
|
|
||||||
Pin: version ${RELEASE}
|
|
||||||
Pin-Priority: 1001
|
|
||||||
EOF
|
|
||||||
apt-get update
|
|
||||||
apt-get install -y nginx=1.26.2*
|
|
||||||
apt-get install -y bunkerweb=${RELEASE}
|
|
||||||
echo "${RELEASE}" >/opt/${APP}_version.txt
|
|
||||||
msg_ok "Updated ${APP} to ${RELEASE}"
|
|
||||||
|
|
||||||
else
|
|
||||||
msg_ok "No update required. ${APP} is already at ${RELEASE}"
|
|
||||||
fi
|
|
||||||
exit
|
exit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-1
@@ -65,6 +65,8 @@ function update_script() {
|
|||||||
rm kepubify-linux-arm64
|
rm kepubify-linux-arm64
|
||||||
curl -fsSLO https://github.com/pgaskin/kepubify/releases/latest/download/kepubify-linux-arm64 &>/dev/null
|
curl -fsSLO https://github.com/pgaskin/kepubify/releases/latest/download/kepubify-linux-arm64 &>/dev/null
|
||||||
chmod +x kepubify-linux-arm64
|
chmod +x kepubify-linux-arm64
|
||||||
|
rm /opt/calibre-web/metadata.db
|
||||||
|
wget https://github.com/janeczku/calibre-web/raw/master/library/metadata.db -P /opt/calibre-web
|
||||||
menu_array=("1" "Enables gdrive as storage backend for your ebooks" OFF \
|
menu_array=("1" "Enables gdrive as storage backend for your ebooks" OFF \
|
||||||
"2" "Enables sending emails via a googlemail account without enabling insecure apps" OFF \
|
"2" "Enables sending emails via a googlemail account without enabling insecure apps" OFF \
|
||||||
"3" "Enables displaying of additional author infos on the authors page" OFF \
|
"3" "Enables displaying of additional author infos on the authors page" OFF \
|
||||||
@@ -102,8 +104,8 @@ function update_script() {
|
|||||||
CHOICES=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "CALIBRE-WEB OPTIONS" --separate-output --checklist "Choose Additional Options" 15 125 8 "${menu_array[@]}" 3>&1 1>&2 2>&3)
|
CHOICES=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "CALIBRE-WEB OPTIONS" --separate-output --checklist "Choose Additional Options" 15 125 8 "${menu_array[@]}" 3>&1 1>&2 2>&3)
|
||||||
spinner &
|
spinner &
|
||||||
SPINNER_PID=$!
|
SPINNER_PID=$!
|
||||||
options=()
|
|
||||||
if [ ! -z "$CHOICES" ]; then
|
if [ ! -z "$CHOICES" ]; then
|
||||||
|
declare -a options
|
||||||
for CHOICE in $CHOICES; do
|
for CHOICE in $CHOICES; do
|
||||||
case "$CHOICE" in
|
case "$CHOICE" in
|
||||||
"1")
|
"1")
|
||||||
|
|||||||
@@ -62,17 +62,6 @@ if ! dpkg -s libjpeg-dev >/dev/null 2>&1; then
|
|||||||
fi
|
fi
|
||||||
pip3 install changedetection.io --upgrade &>/dev/null
|
pip3 install changedetection.io --upgrade &>/dev/null
|
||||||
pip3 install playwright --upgrade &>/dev/null
|
pip3 install playwright --upgrade &>/dev/null
|
||||||
if [[ -f /etc/systemd/system/browserless.service ]]; then
|
|
||||||
git -C /opt/browserless/ fetch --all &>/dev/null
|
|
||||||
git -C /opt/browserless/ reset --hard origin/main &>/dev/null
|
|
||||||
npm update --prefix /opt/browserless &>/dev/null
|
|
||||||
npm run build --prefix /opt/browserless &>/dev/null
|
|
||||||
npm run build:function --prefix /opt/browserless &>/dev/null
|
|
||||||
npm prune production --prefix /opt/browserless &>/dev/null
|
|
||||||
systemctl restart browserless
|
|
||||||
else
|
|
||||||
msg_error "No Browserless Installation Found!"
|
|
||||||
fi
|
|
||||||
systemctl restart changedetection
|
systemctl restart changedetection
|
||||||
msg_ok "Updated Successfully"
|
msg_ok "Updated Successfully"
|
||||||
exit
|
exit
|
||||||
|
|||||||
-125
@@ -1,125 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -s https://raw.githubusercontent.com/asylumexp/Proxmox/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2024 tteck
|
|
||||||
# Author: tteck
|
|
||||||
# Co-Author: havardthom
|
|
||||||
# License: MIT
|
|
||||||
# https://github.com/tteck/Proxmox/raw/main/LICENSE
|
|
||||||
|
|
||||||
function header_info {
|
|
||||||
clear
|
|
||||||
cat <<"EOF"
|
|
||||||
______ __ _ __
|
|
||||||
/ ____/___ _____/ /______ (_) /_
|
|
||||||
/ / / __ \/ ___/ //_/ __ \/ / __/
|
|
||||||
/ /___/ /_/ / /__/ ,< / /_/ / / /_
|
|
||||||
\____/\____/\___/_/|_/ .___/_/\__/
|
|
||||||
/_/
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
header_info
|
|
||||||
echo -e "Loading..."
|
|
||||||
APP="Cockpit"
|
|
||||||
var_disk="4"
|
|
||||||
var_cpu="2"
|
|
||||||
var_ram="1024"
|
|
||||||
var_os="debian"
|
|
||||||
var_version="12"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function default_settings() {
|
|
||||||
CT_TYPE="1"
|
|
||||||
PW=""
|
|
||||||
CT_ID=$NEXTID
|
|
||||||
HN=$NSAPP
|
|
||||||
DISK_SIZE="$var_disk"
|
|
||||||
CORE_COUNT="$var_cpu"
|
|
||||||
RAM_SIZE="$var_ram"
|
|
||||||
BRG="vmbr0"
|
|
||||||
NET="dhcp"
|
|
||||||
GATE=""
|
|
||||||
APT_CACHER=""
|
|
||||||
APT_CACHER_IP=""
|
|
||||||
DISABLEIP6="no"
|
|
||||||
MTU=""
|
|
||||||
SD=""
|
|
||||||
NS=""
|
|
||||||
MAC=""
|
|
||||||
VLAN=""
|
|
||||||
SSH="no"
|
|
||||||
VERB="no"
|
|
||||||
echo_default
|
|
||||||
}
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
if [[ ! -d /etc/cockpit ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
|
||||||
UPD=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 4 \
|
|
||||||
"1" "Update LXC" ON \
|
|
||||||
"2" "Install cockpit-file-sharing" OFF \
|
|
||||||
"3" "Install cockpit-identities" OFF \
|
|
||||||
"4" "Install cockpit-navigator" OFF \
|
|
||||||
3>&1 1>&2 2>&3)
|
|
||||||
|
|
||||||
header_info
|
|
||||||
if [ "$UPD" == "1" ]; then
|
|
||||||
msg_info "Updating ${APP} LXC"
|
|
||||||
apt-get update &>/dev/null
|
|
||||||
apt-get -y upgrade &>/dev/null
|
|
||||||
msg_ok "Updated ${APP} LXC"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
if [ "$UPD" == "2" ]; then
|
|
||||||
msg_info "Installing dependencies (patience)"
|
|
||||||
apt-get install -y attr &>/dev/null
|
|
||||||
apt-get install -y nfs-kernel-server &>/dev/null
|
|
||||||
apt-get install -y samba &>/dev/null
|
|
||||||
apt-get install -y samba-common-bin &>/dev/null
|
|
||||||
apt-get install -y winbind &>/dev/null
|
|
||||||
apt-get install -y gawk &>/dev/null
|
|
||||||
msg_ok "Installed dependencies"
|
|
||||||
msg_info "Installing Cockpit file sharing"
|
|
||||||
LATEST=$(curl -s https://api.github.com/repos/45Drives/cockpit-file-sharing/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
|
|
||||||
wget -q https://github.com/45Drives/cockpit-file-sharing/releases/download/v${LATEST}/cockpit-file-sharing_${LATEST}-1focal_all.deb
|
|
||||||
dpkg -i cockpit-file-sharing_${LATEST}-1focal_all.deb &>/dev/null
|
|
||||||
rm cockpit-file-sharing_${LATEST}-1focal_all.deb
|
|
||||||
msg_ok "Installed Cockpit file sharing"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
if [ "$UPD" == "3" ]; then
|
|
||||||
msg_info "Installing dependencies (patience)"
|
|
||||||
apt-get install -y psmisc &>/dev/null
|
|
||||||
apt-get install -y samba &>/dev/null
|
|
||||||
apt-get install -y samba-common-bin &>/dev/null
|
|
||||||
msg_ok "Installed dependencies"
|
|
||||||
msg_info "Installing Cockpit identities"
|
|
||||||
LATEST=$(curl -s https://api.github.com/repos/45Drives/cockpit-identities/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
|
|
||||||
wget -q https://github.com/45Drives/cockpit-identities/releases/download/v${LATEST}/cockpit-identities_${LATEST}-1focal_all.deb
|
|
||||||
dpkg -i cockpit-identities_${LATEST}-1focal_all.deb &>/dev/null
|
|
||||||
rm cockpit-identities_${LATEST}-1focal_all.deb
|
|
||||||
msg_ok "Installed Cockpit identities"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
if [ "$UPD" == "4" ]; then
|
|
||||||
msg_info "Installing dependencies"
|
|
||||||
apt-get install -y rsync &>/dev/null
|
|
||||||
apt-get install -y zip &>/dev/null
|
|
||||||
msg_ok "Installed dependencies"
|
|
||||||
msg_info "Installing Cockpit navigator"
|
|
||||||
LATEST=$(curl -s https://api.github.com/repos/45Drives/cockpit-navigator/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
|
|
||||||
wget -q https://github.com/45Drives/cockpit-navigator/releases/download/v${LATEST}/cockpit-navigator_${LATEST}-1focal_all.deb
|
|
||||||
dpkg -i cockpit-navigator_${LATEST}-1focal_all.deb &>/dev/null
|
|
||||||
rm cockpit-navigator_${LATEST}-1focal_all.deb
|
|
||||||
msg_ok "Installed Cockpit navigator"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed Successfully!\n"
|
|
||||||
echo -e "${APP} should be reachable by going to the following URL.
|
|
||||||
${BL}http://${IP}:9090${CL} \n"
|
|
||||||
+9
-17
@@ -55,27 +55,19 @@ function default_settings() {
|
|||||||
function update_script() {
|
function update_script() {
|
||||||
header_info
|
header_info
|
||||||
if [[ ! -d /opt/commafeed ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
if [[ ! -d /opt/commafeed ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
||||||
RELEASE=$(curl -sL https://api.github.com/repos/Athou/commafeed/releases/latest | grep '"tag_name":' | cut -d'"' -f4)
|
msg_info "Stopping CommaFeed"
|
||||||
if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then
|
|
||||||
msg_info "Stopping ${APP}"
|
|
||||||
systemctl stop commafeed
|
systemctl stop commafeed
|
||||||
msg_ok "Stopped ${APP}"
|
msg_ok "Stopped CommaFeed"
|
||||||
|
|
||||||
msg_info "Updating ${APP} to ${RELEASE}"
|
msg_info "Updating CommaFeed"
|
||||||
wget -q https://github.com/Athou/commafeed/releases/download/${RELEASE}/commafeed-${RELEASE}-h2-jvm.zip
|
cd /opt/commafeed
|
||||||
unzip -q commafeed-${RELEASE}-h2-jvm.zip
|
rm commafeed.jar
|
||||||
rsync -a --exclude 'data/' commafeed-${RELEASE}-h2/ /opt/commafeed/
|
wget -q https://github.com/Athou/commafeed/releases/latest/download/commafeed.jar
|
||||||
rm -rf commafeed-${RELEASE}-h2 commafeed-${RELEASE}-h2-jvm.zip
|
msg_ok "Updated CommaFeed"
|
||||||
echo "${RELEASE}" >/opt/${APP}_version.txt
|
|
||||||
msg_ok "Updated ${APP} to ${RELEASE}"
|
|
||||||
|
|
||||||
msg_info "Starting ${APP}"
|
msg_info "Starting CommaFeed"
|
||||||
systemctl start commafeed
|
systemctl start commafeed
|
||||||
msg_ok "Started ${APP}"
|
msg_ok "Update Completed Successfully"
|
||||||
msg_ok "Updated Successfully"
|
|
||||||
else
|
|
||||||
msg_ok "No update required. ${APP} is already at ${RELEASE}"
|
|
||||||
fi
|
|
||||||
exit
|
exit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -76,8 +76,8 @@ if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}
|
|||||||
mkdir -p /opt/dashy
|
mkdir -p /opt/dashy
|
||||||
wget -qO- https://github.com/Lissy93/dashy/archive/refs/tags/${RELEASE}.tar.gz | tar -xz -C /opt/dashy --strip-components=1
|
wget -qO- https://github.com/Lissy93/dashy/archive/refs/tags/${RELEASE}.tar.gz | tar -xz -C /opt/dashy --strip-components=1
|
||||||
cd /opt/dashy
|
cd /opt/dashy
|
||||||
npm install
|
npm install &>/dev/null
|
||||||
npm run build
|
npm run build &>/dev/null
|
||||||
echo "${RELEASE}" >/opt/${APP}_version.txt
|
echo "${RELEASE}" >/opt/${APP}_version.txt
|
||||||
msg_ok "Updated ${APP} to ${RELEASE}"
|
msg_ok "Updated ${APP} to ${RELEASE}"
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -29,7 +29,7 @@ color
|
|||||||
catch_errors
|
catch_errors
|
||||||
|
|
||||||
function default_settings() {
|
function default_settings() {
|
||||||
CT_TYPE="0"
|
CT_TYPE="1"
|
||||||
PW=""
|
PW=""
|
||||||
CT_ID=$NEXTID
|
CT_ID=$NEXTID
|
||||||
HN=$NSAPP
|
HN=$NSAPP
|
||||||
|
|||||||
+9
-7
@@ -32,7 +32,7 @@ color
|
|||||||
catch_errors
|
catch_errors
|
||||||
|
|
||||||
function default_settings() {
|
function default_settings() {
|
||||||
CT_TYPE="0"
|
CT_TYPE="1"
|
||||||
PW=""
|
PW=""
|
||||||
CT_ID=$NEXTID
|
CT_ID=$NEXTID
|
||||||
HN=$NSAPP
|
HN=$NSAPP
|
||||||
@@ -57,20 +57,22 @@ function default_settings() {
|
|||||||
function update_script() {
|
function update_script() {
|
||||||
header_info
|
header_info
|
||||||
if [[ ! -d /opt/ErsatzTV ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
if [[ ! -d /opt/ErsatzTV ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
||||||
|
if (( $(df /boot | awk 'NR==2{gsub("%","",$5); print $5}') > 80 )); then
|
||||||
|
read -r -p "Warning: Storage is dangerously low, continue anyway? <y/N> " prompt
|
||||||
|
[[ ${prompt,,} =~ ^(y|yes)$ ]] || exit
|
||||||
|
fi
|
||||||
msg_info "Stopping ErsatzTV"
|
msg_info "Stopping ErsatzTV"
|
||||||
systemctl stop ersatzTV
|
systemctl stop ersatzTV
|
||||||
msg_ok "Stopped ErsatzTV"
|
msg_ok "Stopped ErsatzTV"
|
||||||
|
|
||||||
msg_info "Updating ErsatzTV"
|
msg_info "Updating ErsatzTV"
|
||||||
RELEASE=$(curl -s https://api.github.com/repos/ErsatzTV/ErsatzTV/releases | grep -oP '"tag_name": "\K[^"]+' | head -n 1)
|
RELEASE=$(curl -s https://api.github.com/repos/ErsatzTV/ErsatzTV/releases | grep -oP '"tag_name": "\K[^"]+' | head -n 1)
|
||||||
cp -R /opt/ErsatzTV/ ErsatzTV-backup
|
if [ -d /opt/ErsatzTV/ErsatzTV_bak ]; then
|
||||||
rm ErsatzTV-backup/ErsatzTV
|
rm -rf /opt/ErsatzTV/ErsatzTV_bak
|
||||||
rm -rf /opt/ErsatzTV
|
fi
|
||||||
|
mv /opt/ErsatzTV/ErsatzTV /opt/ErsatzTV/ErsatzTV_bak
|
||||||
wget -qO- "https://github.com/ErsatzTV/ErsatzTV/releases/download/${RELEASE}/ErsatzTV-${RELEASE}-linux-arm64.tar.gz" | tar -xz -C /opt
|
wget -qO- "https://github.com/ErsatzTV/ErsatzTV/releases/download/${RELEASE}/ErsatzTV-${RELEASE}-linux-arm64.tar.gz" | tar -xz -C /opt
|
||||||
mv "/opt/ErsatzTV-${RELEASE}-linux-arm64" /opt/ErsatzTV
|
mv "/opt/ErsatzTV-${RELEASE}-linux-arm64" /opt/ErsatzTV
|
||||||
cp -R ErsatzTV-backup/* /opt/ErsatzTV/
|
|
||||||
rm -rf ErsatzTV-backup
|
|
||||||
msg_ok "Updated ErsatzTV"
|
msg_ok "Updated ErsatzTV"
|
||||||
|
|
||||||
msg_info "Starting ErsatzTV"
|
msg_info "Starting ErsatzTV"
|
||||||
|
|||||||
-70
@@ -1,70 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -s https://raw.githubusercontent.com/asylumexp/Proxmox/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2024 tteck
|
|
||||||
# Author: MickLesk (Canbiz)
|
|
||||||
# License: MIT
|
|
||||||
# https://github.com/tteck/Proxmox/raw/main/LICENSE
|
|
||||||
|
|
||||||
function header_info {
|
|
||||||
clear
|
|
||||||
cat <<"EOF"
|
|
||||||
___ _ ____________
|
|
||||||
/ _ \ | / / ___/ ___/
|
|
||||||
/ __/ |/ / /__/ /__
|
|
||||||
\___/|___/\___/\___/
|
|
||||||
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
header_info
|
|
||||||
echo -e "Loading..."
|
|
||||||
APP="evcc"
|
|
||||||
var_disk="4"
|
|
||||||
var_cpu="1"
|
|
||||||
var_ram="1024"
|
|
||||||
var_os="debian"
|
|
||||||
var_version="12"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function default_settings() {
|
|
||||||
CT_TYPE="1"
|
|
||||||
PW=""
|
|
||||||
CT_ID=$NEXTID
|
|
||||||
HN=$NSAPP
|
|
||||||
DISK_SIZE="$var_disk"
|
|
||||||
CORE_COUNT="$var_cpu"
|
|
||||||
RAM_SIZE="$var_ram"
|
|
||||||
BRG="vmbr0"
|
|
||||||
NET="dhcp"
|
|
||||||
GATE=""
|
|
||||||
APT_CACHER=""
|
|
||||||
APT_CACHER_IP=""
|
|
||||||
DISABLEIP6="no"
|
|
||||||
MTU=""
|
|
||||||
SD=""
|
|
||||||
NS=""
|
|
||||||
MAC=""
|
|
||||||
VLAN=""
|
|
||||||
SSH="no"
|
|
||||||
VERB="no"
|
|
||||||
echo_default
|
|
||||||
}
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
if [[ ! -f /etc/apt/sources.list.d/evcc-stable.list ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
|
||||||
msg_info "Updating evcc LXC"
|
|
||||||
apt update &>/dev/null
|
|
||||||
apt --only-upgrade install -y evcc &>/dev/null
|
|
||||||
msg_ok "Updated Successfully"
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed Successfully!\n"
|
|
||||||
echo -e "${APP} Setup should be reachable by going to the following URL.
|
|
||||||
${BL}http://${IP}:7070${CL} \n"
|
|
||||||
@@ -56,7 +56,6 @@ function default_settings() {
|
|||||||
function update_script() {
|
function update_script() {
|
||||||
header_info
|
header_info
|
||||||
if [[ ! -f /etc/systemd/system/flaresolverr.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
if [[ ! -f /etc/systemd/system/flaresolverr.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
||||||
whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "SET RESOURCES" "Please set the resources in your ${APP} LXC to ${var_cpu}vCPU and ${var_ram}RAM for the build process before continuing" 10 75
|
|
||||||
RELEASE=$(wget -q https://github.com/FlareSolverr/FlareSolverr/releases/latest -O - | grep "title>Release" | cut -d " " -f 4)
|
RELEASE=$(wget -q https://github.com/FlareSolverr/FlareSolverr/releases/latest -O - | grep "title>Release" | cut -d " " -f 4)
|
||||||
if [[ ! -d /opt/flaresolverr ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
if [[ ! -d /opt/flaresolverr ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
||||||
msg_info "Updating $APP LXC"
|
msg_info "Updating $APP LXC"
|
||||||
|
|||||||
@@ -55,7 +55,6 @@ function default_settings() {
|
|||||||
function update_script() {
|
function update_script() {
|
||||||
header_info
|
header_info
|
||||||
if [[ ! -f /etc/systemd/system/flowise.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
if [[ ! -f /etc/systemd/system/flowise.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
||||||
whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "SET RESOURCES" "Please set the resources in your ${APP} LXC to ${var_cpu}vCPU and ${var_ram}RAM for the build process before continuing" 10 75
|
|
||||||
msg_info "Updating ${APP}"
|
msg_info "Updating ${APP}"
|
||||||
systemctl stop flowise
|
systemctl stop flowise
|
||||||
npm install -g flowise --upgrade
|
npm install -g flowise --upgrade
|
||||||
|
|||||||
+2
-7
@@ -55,7 +55,7 @@ function default_settings() {
|
|||||||
|
|
||||||
function update_script() {
|
function update_script() {
|
||||||
if [[ ! -f /etc/systemd/system/frigate.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
if [[ ! -f /etc/systemd/system/frigate.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
||||||
msg_error "To update Frigate, create a new container and transfer your configuration."
|
msg_error "There is currently no update path available."
|
||||||
exit
|
exit
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,13 +64,8 @@ build_container
|
|||||||
description
|
description
|
||||||
|
|
||||||
msg_info "Setting Container to Normal Resources"
|
msg_info "Setting Container to Normal Resources"
|
||||||
STATUS=$(pct status $CTID | grep -oP '(?<=status: ).*')
|
|
||||||
if [ "$STATUS" == "running" ]; then
|
|
||||||
pct set $CTID -memory 1024
|
pct set $CTID -memory 1024
|
||||||
else
|
msg_ok "Set Container to Normal Resources"
|
||||||
echo -e " ⚠️ ${RD}Container is not running. Will need to change memory to 1024MB manually.${CL}"
|
|
||||||
fi
|
|
||||||
msg_ok "Set Normal Resources"
|
|
||||||
msg_ok "Completed Successfully!\n"
|
msg_ok "Completed Successfully!\n"
|
||||||
echo -e "${APP} should be reachable by going to the following URL.
|
echo -e "${APP} should be reachable by going to the following URL.
|
||||||
${BL}http://${IP}:5000${CL} \n"
|
${BL}http://${IP}:5000${CL} \n"
|
||||||
|
|||||||
-77
@@ -1,77 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -s https://raw.githubusercontent.com/asylumexp/Proxmox/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2024 tteck
|
|
||||||
# Author: tteck (tteckster)
|
|
||||||
# Co-author: Rogue-King
|
|
||||||
# License: MIT
|
|
||||||
# https://github.com/tteck/Proxmox/raw/main/LICENSE
|
|
||||||
|
|
||||||
function header_info {
|
|
||||||
clear
|
|
||||||
cat <<"EOF"
|
|
||||||
______ _ __
|
|
||||||
/ ____/(_)/ /____ ____ _
|
|
||||||
/ / __// // __/ _ \/ __ /
|
|
||||||
/ /_/ // // /_/ __/ /_/ /
|
|
||||||
\____//_/ \__/\___/\__,_/
|
|
||||||
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
header_info
|
|
||||||
echo -e "Loading..."
|
|
||||||
APP="Gitea"
|
|
||||||
var_disk="8"
|
|
||||||
var_cpu="1"
|
|
||||||
var_ram="1024"
|
|
||||||
var_os="debian"
|
|
||||||
var_version="12"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function default_settings() {
|
|
||||||
CT_TYPE="1"
|
|
||||||
PW=""
|
|
||||||
CT_ID=$NEXTID
|
|
||||||
HN=$NSAPP
|
|
||||||
DISK_SIZE="$var_disk"
|
|
||||||
CORE_COUNT="$var_cpu"
|
|
||||||
RAM_SIZE="$var_ram"
|
|
||||||
BRG="vmbr0"
|
|
||||||
NET="dhcp"
|
|
||||||
GATE=""
|
|
||||||
APT_CACHER=""
|
|
||||||
APT_CACHER_IP=""
|
|
||||||
DISABLEIP6="no"
|
|
||||||
MTU=""
|
|
||||||
SD=""
|
|
||||||
NS=""
|
|
||||||
MAC=""
|
|
||||||
VLAN=""
|
|
||||||
SSH="no"
|
|
||||||
VERB="no"
|
|
||||||
echo_default
|
|
||||||
}
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
if [[ ! -f /usr/local/bin/gitea ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
|
||||||
RELEASE=$(wget -q https://github.com/go-gitea/gitea/releases/latest -O - | grep "title>Release" | cut -d " " -f 4 | sed 's/^v//')
|
|
||||||
msg_info "Updating $APP to ${RELEASE}"
|
|
||||||
wget -q https://github.com/go-gitea/gitea/releases/download/v$RELEASE/gitea-$RELEASE-linux-arm64
|
|
||||||
systemctl stop gitea
|
|
||||||
rm -rf /usr/local/bin/gitea
|
|
||||||
mv gitea* /usr/local/bin/gitea
|
|
||||||
chmod +x /usr/local/bin/gitea
|
|
||||||
systemctl start gitea
|
|
||||||
msg_ok "Updated $APP Successfully"
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed Successfully!\n"
|
|
||||||
echo -e "${APP} should be reachable by going to the following URL.
|
|
||||||
${BL}http://${IP}:3000${CL} \n"
|
|
||||||
+1
-23
@@ -55,29 +55,7 @@ function default_settings() {
|
|||||||
function update_script() {
|
function update_script() {
|
||||||
header_info
|
header_info
|
||||||
if [[ ! -d /opt/gotify ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
if [[ ! -d /opt/gotify ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
||||||
|
msg_error "There is currently no update path available."
|
||||||
RELEASE=$(curl -s https://api.github.com/repos/gotify/server/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
|
|
||||||
if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then
|
|
||||||
msg_info "Stopping ${APP}"
|
|
||||||
systemctl stop gotify
|
|
||||||
msg_ok "Stopped ${APP}"
|
|
||||||
|
|
||||||
msg_info "Updating ${APP} to ${RELEASE}"
|
|
||||||
cd /opt/gotify
|
|
||||||
wget -q https://github.com/gotify/server/releases/download/v${RELEASE}/gotify-linux-amd64.zip
|
|
||||||
unzip -oq gotify-linux-amd64.zip
|
|
||||||
rm -rf gotify-linux-amd64.zip
|
|
||||||
chmod +x gotify-linux-amd64
|
|
||||||
echo "${RELEASE}" >/opt/${APP}_version.txt
|
|
||||||
msg_ok "Updated ${APP} to ${RELEASE}"
|
|
||||||
|
|
||||||
msg_info "Starting ${APP}"
|
|
||||||
systemctl start gotify
|
|
||||||
msg_ok "Started ${APP}"
|
|
||||||
msg_ok "Updated Successfully"
|
|
||||||
else
|
|
||||||
msg_ok "No update required. ${APP} is already at ${RELEASE}"
|
|
||||||
fi
|
|
||||||
exit
|
exit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
source <(curl -s https://raw.githubusercontent.com/asylumexp/Proxmox/main/misc/build.func)
|
source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)
|
||||||
# Copyright (c) 2021-2024 tteck
|
# Copyright (c) 2021-2024 tteck
|
||||||
# Author: tteck (tteckster)
|
# Author: tteck (tteckster)
|
||||||
# License: MIT
|
# License: MIT
|
||||||
@@ -63,9 +63,9 @@ if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}
|
|||||||
msg_ok "Stopped ${APP}"
|
msg_ok "Stopped ${APP}"
|
||||||
|
|
||||||
msg_info "Updating $APP to v${RELEASE}"
|
msg_info "Updating $APP to v${RELEASE}"
|
||||||
wget -q https://github.com/juanfont/headscale/releases/download/v${RELEASE}/headscale_${RELEASE}_linux_arm64.deb
|
wget -q https://github.com/juanfont/headscale/releases/download/v${RELEASE}/headscale_${RELEASE}_linux_amd64.deb
|
||||||
dpkg -i headscale_${RELEASE}_linux_arm64.deb
|
dpkg -i headscale_${RELEASE}_linux_amd64.deb
|
||||||
rm headscale_${RELEASE}_linux_arm64.deb
|
rm headscale_${RELEASE}_linux_amd64.deb
|
||||||
echo "${RELEASE}" >/opt/${APP}_version.txt
|
echo "${RELEASE}" >/opt/${APP}_version.txt
|
||||||
msg_ok "Updated $APP to ${RELEASE}"
|
msg_ok "Updated $APP to ${RELEASE}"
|
||||||
|
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ function update_script() {
|
|||||||
|
|
||||||
msg_info "Updating Home Assistant"
|
msg_info "Updating Home Assistant"
|
||||||
source /srv/homeassistant/bin/activate
|
source /srv/homeassistant/bin/activate
|
||||||
uv pip install ${BR}--upgrade homeassistant &>/dev/null
|
pip install ${BR}--upgrade homeassistant &>/dev/null
|
||||||
msg_ok "Updated Home Assistant"
|
msg_ok "Updated Home Assistant"
|
||||||
|
|
||||||
msg_info "Starting Home Assistant"
|
msg_info "Starting Home Assistant"
|
||||||
@@ -121,7 +121,7 @@ function update_script() {
|
|||||||
else
|
else
|
||||||
filebrowser config init -a '0.0.0.0' &>/dev/null
|
filebrowser config init -a '0.0.0.0' &>/dev/null
|
||||||
filebrowser config set -a '0.0.0.0' &>/dev/null
|
filebrowser config set -a '0.0.0.0' &>/dev/null
|
||||||
filebrowser users add admin helper-scripts.com --perm.admin &>/dev/null
|
filebrowser users add admin changeme --perm.admin &>/dev/null
|
||||||
fi
|
fi
|
||||||
msg_ok "Installed FileBrowser"
|
msg_ok "Installed FileBrowser"
|
||||||
|
|
||||||
@@ -142,7 +142,7 @@ WantedBy=default.target" >$service_path
|
|||||||
|
|
||||||
msg_ok "Completed Successfully!\n"
|
msg_ok "Completed Successfully!\n"
|
||||||
echo -e "FileBrowser should be reachable by going to the following URL.
|
echo -e "FileBrowser should be reachable by going to the following URL.
|
||||||
${BL}http://$IP:8080${CL} admin|helper-scripts.com\n"
|
${BL}http://$IP:8080${CL} admin|changeme\n"
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -105,7 +105,7 @@ function update_script() {
|
|||||||
curl -fsSL https://github.com/filebrowser/filebrowser/releases/download/v2.23.0/linux-arm64-filebrowser.tar.gz | tar -xzv -C /usr/local/bin &>/dev/null
|
curl -fsSL https://github.com/filebrowser/filebrowser/releases/download/v2.23.0/linux-arm64-filebrowser.tar.gz | tar -xzv -C /usr/local/bin &>/dev/null
|
||||||
filebrowser config init -a '0.0.0.0' &>/dev/null
|
filebrowser config init -a '0.0.0.0' &>/dev/null
|
||||||
filebrowser config set -a '0.0.0.0' &>/dev/null
|
filebrowser config set -a '0.0.0.0' &>/dev/null
|
||||||
filebrowser users add admin helper-scripts.com --perm.admin &>/dev/null
|
filebrowser users add admin changeme --perm.admin &>/dev/null
|
||||||
msg_ok "Installed FileBrowser"
|
msg_ok "Installed FileBrowser"
|
||||||
|
|
||||||
msg_info "Creating Service"
|
msg_info "Creating Service"
|
||||||
@@ -125,7 +125,7 @@ WantedBy=default.target" >$service_path
|
|||||||
|
|
||||||
msg_ok "Completed Successfully!\n"
|
msg_ok "Completed Successfully!\n"
|
||||||
echo -e "FileBrowser should be reachable by going to the following URL.
|
echo -e "FileBrowser should be reachable by going to the following URL.
|
||||||
${BL}http://$IP:8080${CL} admin|helper-scripts.com\n"
|
${BL}http://$IP:8080${CL} admin|changeme\n"
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,94 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -s https://raw.githubusercontent.com/asylumexp/Proxmox/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2024 tteck
|
|
||||||
# Author: tteck
|
|
||||||
# Co-Author: MickLesk (Canbiz)
|
|
||||||
# License: MIT
|
|
||||||
# https://github.com/tteck/Proxmox/raw/main/LICENSE
|
|
||||||
|
|
||||||
function header_info {
|
|
||||||
clear
|
|
||||||
cat <<"EOF"
|
|
||||||
__ __ ____
|
|
||||||
/ / / /___ ____ ___ ___ / __ )____ _ __
|
|
||||||
/ /_/ / __ \/ __ `__ \/ _ \/ __ / __ \| |/_/
|
|
||||||
/ __ / /_/ / / / / / / __/ /_/ / /_/ /> <
|
|
||||||
/_/ /_/\____/_/ /_/ /_/\___/_____/\____/_/|_|
|
|
||||||
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
header_info
|
|
||||||
echo -e "Loading..."
|
|
||||||
APP="HomeBox"
|
|
||||||
var_disk="4"
|
|
||||||
var_cpu="1"
|
|
||||||
var_ram="1024"
|
|
||||||
var_os="debian"
|
|
||||||
var_version="12"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function default_settings() {
|
|
||||||
CT_TYPE="1"
|
|
||||||
PW=""
|
|
||||||
CT_ID=$NEXTID
|
|
||||||
HN=$NSAPP
|
|
||||||
DISK_SIZE="$var_disk"
|
|
||||||
CORE_COUNT="$var_cpu"
|
|
||||||
RAM_SIZE="$var_ram"
|
|
||||||
BRG="vmbr0"
|
|
||||||
NET="dhcp"
|
|
||||||
GATE=""
|
|
||||||
APT_CACHER=""
|
|
||||||
APT_CACHER_IP=""
|
|
||||||
DISABLEIP6="no"
|
|
||||||
MTU=""
|
|
||||||
SD=""
|
|
||||||
NS=""
|
|
||||||
MAC=""
|
|
||||||
VLAN=""
|
|
||||||
SSH="no"
|
|
||||||
VERB="no"
|
|
||||||
echo_default
|
|
||||||
}
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
if [[ ! -f /opt/homebox ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
|
||||||
if (( $(df /boot | awk 'NR==2{gsub("%","",$5); print $5}') > 80 )); then
|
|
||||||
read -r -p "Warning: Storage is dangerously low, continue anyway? <y/N> " prompt
|
|
||||||
[[ ${prompt,,} =~ ^(y|yes)$ ]] || exit
|
|
||||||
fi
|
|
||||||
RELEASE=$(curl -s https://api.github.com/repos/sysadminsmedia/homebox/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
|
|
||||||
if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then
|
|
||||||
msg_info "Stopping ${APP}"
|
|
||||||
systemctl stop homebox
|
|
||||||
msg_ok "${APP} Stopped"
|
|
||||||
|
|
||||||
msg_info "Updating ${APP} to ${RELEASE}"
|
|
||||||
cd /opt
|
|
||||||
rm -rf homebox_bak
|
|
||||||
mv homebox homebox_bak
|
|
||||||
wget -qO- https://github.com/sysadminsmedia/homebox/releases/download/${RELEASE}/homebox_Linux_x86_64.tar.gz | tar -xzf - -C /opt
|
|
||||||
chmod +x /opt/homebox
|
|
||||||
echo "${RELEASE}" >/opt/${APP}_version.txt
|
|
||||||
msg_ok "Updated Homebox"
|
|
||||||
|
|
||||||
msg_info "Starting ${APP}"
|
|
||||||
systemctl start homebox
|
|
||||||
msg_ok "Started ${APP}"
|
|
||||||
|
|
||||||
msg_ok "Updated Successfully"
|
|
||||||
else
|
|
||||||
msg_ok "No update required. ${APP} is already at ${RELEASE}"
|
|
||||||
fi
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed Successfully!\n"
|
|
||||||
echo -e "${APP} Setup should be reachable by going to the following URL.
|
|
||||||
${BL}http://${IP}:7745${CL} \n"
|
|
||||||
+1
-1
@@ -30,7 +30,7 @@ color
|
|||||||
catch_errors
|
catch_errors
|
||||||
|
|
||||||
function default_settings() {
|
function default_settings() {
|
||||||
CT_TYPE="0"
|
CT_TYPE="1"
|
||||||
PW=""
|
PW=""
|
||||||
CT_ID=$NEXTID
|
CT_ID=$NEXTID
|
||||||
HN=$NSAPP
|
HN=$NSAPP
|
||||||
|
|||||||
+7
-35
@@ -20,7 +20,7 @@ header_info
|
|||||||
echo -e "Loading..."
|
echo -e "Loading..."
|
||||||
APP="Jellyseerr"
|
APP="Jellyseerr"
|
||||||
var_disk="8"
|
var_disk="8"
|
||||||
var_cpu="4"
|
var_cpu="2"
|
||||||
var_ram="4096"
|
var_ram="4096"
|
||||||
var_os="debian"
|
var_os="debian"
|
||||||
var_version="12"
|
var_version="12"
|
||||||
@@ -55,46 +55,19 @@ function default_settings() {
|
|||||||
function update_script() {
|
function update_script() {
|
||||||
header_info
|
header_info
|
||||||
if [[ ! -d /opt/jellyseerr ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
if [[ ! -d /opt/jellyseerr ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
||||||
if (( $(df /boot | awk 'NR==2{gsub("%","",$5); print $5}') > 80 )); then
|
|
||||||
read -r -p "Warning: Storage is dangerously low, continue anyway? <y/N> " prompt
|
|
||||||
[[ ${prompt,,} =~ ^(y|yes)$ ]] || exit
|
|
||||||
fi
|
|
||||||
whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "SET RESOURCES" "Please set the resources in your Jellyseerr LXC to 4vcpu and 4096RAM for the build process before continuing" 10 75
|
|
||||||
if ! command -v pnpm &> /dev/null; then
|
|
||||||
msg_error "pnpm not found. Installing..."
|
|
||||||
npm install -g pnpm &>/dev/null
|
|
||||||
else
|
|
||||||
msg_ok "pnpm is already installed."
|
|
||||||
fi
|
|
||||||
msg_info "Updating $APP"
|
msg_info "Updating $APP"
|
||||||
|
systemctl stop jellyseerr
|
||||||
cd /opt/jellyseerr
|
cd /opt/jellyseerr
|
||||||
output=$(git pull --no-rebase)
|
output=$(git pull)
|
||||||
|
git pull &>/dev/null
|
||||||
if echo "$output" | grep -q "Already up to date."
|
if echo "$output" | grep -q "Already up to date."
|
||||||
then
|
then
|
||||||
msg_ok " $APP is already up to date."
|
msg_ok " $APP is already up to date."
|
||||||
|
systemctl start jellyseerr
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
systemctl stop jellyseerr
|
yarn install &>/dev/null
|
||||||
export CYPRESS_INSTALL_BINARY=0
|
yarn build &>/dev/null
|
||||||
pnpm install --frozen-lockfile &>/dev/null
|
|
||||||
export NODE_OPTIONS="--max-old-space-size=3072"
|
|
||||||
pnpm build &>/dev/null
|
|
||||||
cat <<EOF >/etc/systemd/system/jellyseerr.service
|
|
||||||
[Unit]
|
|
||||||
Description=jellyseerr Service
|
|
||||||
After=network.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
EnvironmentFile=/etc/jellyseerr/jellyseerr.conf
|
|
||||||
Environment=NODE_ENV=production
|
|
||||||
Type=exec
|
|
||||||
WorkingDirectory=/opt/jellyseerr
|
|
||||||
ExecStart=/usr/bin/node dist/index.js
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
EOF
|
|
||||||
systemctl daemon-reload
|
|
||||||
systemctl start jellyseerr
|
systemctl start jellyseerr
|
||||||
msg_ok "Updated $APP"
|
msg_ok "Updated $APP"
|
||||||
exit
|
exit
|
||||||
@@ -106,7 +79,6 @@ description
|
|||||||
|
|
||||||
msg_info "Setting Container to Normal Resources"
|
msg_info "Setting Container to Normal Resources"
|
||||||
pct set $CTID -memory 2048
|
pct set $CTID -memory 2048
|
||||||
pct set $CTID -cores 2
|
|
||||||
msg_ok "Set Container to Normal Resources"
|
msg_ok "Set Container to Normal Resources"
|
||||||
|
|
||||||
msg_ok "Completed Successfully!\n"
|
msg_ok "Completed Successfully!\n"
|
||||||
|
|||||||
+13
-16
@@ -1,30 +1,29 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
source <(curl -s https://raw.githubusercontent.com/asylumexp/Proxmox/main/misc/build.func)
|
source <(curl -s https://raw.githubusercontent.com/asylumexp/Proxmox/main/misc/build.func)
|
||||||
# Copyright (c) 2021-2024 tteck
|
# Copyright (c) 2021-2024 tteck
|
||||||
# Author: tteck
|
# Author: tteck (tteckster)
|
||||||
# Co-Author: havardthom
|
|
||||||
# License: MIT
|
# License: MIT
|
||||||
# https://github.com/tteck/Proxmox/raw/main/LICENSE
|
# https://github.com/tteck/Proxmox/raw/main/LICENSE
|
||||||
|
|
||||||
function header_info {
|
function header_info {
|
||||||
clear
|
clear
|
||||||
cat <<"EOF"
|
cat <<"EOF"
|
||||||
_ __ __ __ _
|
__ ____ __ __ __ __
|
||||||
/ | / /__ ____ / // / (_)
|
/ /__/ __ \_____ / //_/_ __/ /_ ___ _________ ___ / /____ _____
|
||||||
/ |/ / _ \/ __ \/ // /_/ /
|
/ //_/ / / / ___/ / ,< / / / / __ \/ _ \/ ___/ __ \/ _ \/ __/ _ \/ ___/
|
||||||
/ /| / __/ /_/ /__ __/ /
|
/ ,< / /_/ (__ ) / /| / /_/ / /_/ / __/ / / / / / __/ /_/ __(__ )
|
||||||
/_/ |_/\___/\____/ /_/_/ /
|
/_/|_|\____/____/ /_/ |_\__,_/_.___/\___/_/ /_/ /_/\___/\__/\___/____/
|
||||||
/___/
|
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
header_info
|
header_info
|
||||||
echo -e "Loading..."
|
echo -e "Loading..."
|
||||||
APP="Neo4j"
|
APP="k0s"
|
||||||
var_disk="4"
|
var_disk="4"
|
||||||
var_cpu="1"
|
var_cpu="2"
|
||||||
var_ram="1024"
|
var_ram="2048"
|
||||||
var_os="debian"
|
var_os="debian"
|
||||||
var_version="12"
|
var_version="11"
|
||||||
variables
|
variables
|
||||||
color
|
color
|
||||||
catch_errors
|
catch_errors
|
||||||
@@ -55,8 +54,8 @@ function default_settings() {
|
|||||||
|
|
||||||
function update_script() {
|
function update_script() {
|
||||||
header_info
|
header_info
|
||||||
if [[ ! -d /etc/neo4j ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
if [[ ! -f /etc/k0s/k0s.yaml ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
||||||
msg_info "Updating ${APP}"
|
msg_info "Updating ${APP} LXC"
|
||||||
apt-get update &>/dev/null
|
apt-get update &>/dev/null
|
||||||
apt-get -y upgrade &>/dev/null
|
apt-get -y upgrade &>/dev/null
|
||||||
msg_ok "Updated Successfully"
|
msg_ok "Updated Successfully"
|
||||||
@@ -68,5 +67,3 @@ build_container
|
|||||||
description
|
description
|
||||||
|
|
||||||
msg_ok "Completed Successfully!\n"
|
msg_ok "Completed Successfully!\n"
|
||||||
echo -e "${APP} Browser should be reachable by going to the following URL.
|
|
||||||
${BL}http://${IP}:7474${CL} \n"
|
|
||||||
+1
-25
@@ -57,32 +57,8 @@ function update_script() {
|
|||||||
header_info
|
header_info
|
||||||
if [[ ! -f /etc/systemd/system/keycloak.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
if [[ ! -f /etc/systemd/system/keycloak.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
||||||
msg_info "Updating ${APP} LXC"
|
msg_info "Updating ${APP} LXC"
|
||||||
|
|
||||||
msg_info "Updating packages"
|
|
||||||
apt-get update &>/dev/null
|
apt-get update &>/dev/null
|
||||||
apt-get -y upgrade &>/dev/null
|
apt-get -y upgrade &>/dev/null
|
||||||
|
|
||||||
RELEASE=$(curl -s https://api.github.com/repos/keycloak/keycloak/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
|
|
||||||
msg_info "Downloading Keycloak v$RELEASE"
|
|
||||||
cd /opt
|
|
||||||
wget -q https://github.com/keycloak/keycloak/releases/download/$RELEASE/keycloak-$RELEASE.tar.gz
|
|
||||||
$STD tar -xvf keycloak-$RELEASE.tar.gz
|
|
||||||
|
|
||||||
msg_info "Merging configuration files"
|
|
||||||
cp -r keycloak/conf keycloak-$RELEASE
|
|
||||||
cp -r keycloak/providers keycloak-$RELEASE
|
|
||||||
cp -r keycloak/themes keycloak-$RELEASE
|
|
||||||
|
|
||||||
msg_info "Updating Keycloak"
|
|
||||||
mv keycloak keycloak.old
|
|
||||||
mv keycloak-$RELEASE keycloak
|
|
||||||
|
|
||||||
msg_info "Delete temporary installation files"
|
|
||||||
rm keycloak-$RELEASE.tar.gz
|
|
||||||
rm -rf keycloak.old
|
|
||||||
|
|
||||||
msg_info "Restating Keycloak"
|
|
||||||
systemctl restart keycloak
|
|
||||||
msg_ok "Updated Successfully"
|
msg_ok "Updated Successfully"
|
||||||
exit
|
exit
|
||||||
}
|
}
|
||||||
@@ -93,4 +69,4 @@ description
|
|||||||
|
|
||||||
msg_ok "Completed Successfully!\n"
|
msg_ok "Completed Successfully!\n"
|
||||||
echo -e "${APP} should be reachable by going to the following URL.
|
echo -e "${APP} should be reachable by going to the following URL.
|
||||||
${BL}http://${IP}:8080/admin${CL} \n"
|
${BL}http://${IP}:8080${CL} \n"
|
||||||
|
|||||||
@@ -67,7 +67,6 @@ if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}
|
|||||||
git pull
|
git pull
|
||||||
yarn
|
yarn
|
||||||
npx playwright install-deps
|
npx playwright install-deps
|
||||||
yarn playwright install
|
|
||||||
yarn prisma generate
|
yarn prisma generate
|
||||||
yarn build
|
yarn build
|
||||||
yarn prisma migrate deploy
|
yarn prisma migrate deploy
|
||||||
|
|||||||
-75
@@ -1,75 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
# source <(curl -s https://raw.githubusercontent.com/asylumexp/Proxmox/main/misc/build.func)
|
|
||||||
# # Copyright (c) 2021-2024 tteck
|
|
||||||
# # Author: tteck (tteckster)
|
|
||||||
# # Co-Author: remz1337
|
|
||||||
# # License: MIT
|
|
||||||
# # https://github.com/tteck/Proxmox/raw/main/LICENSE
|
|
||||||
|
|
||||||
echo "Unsupported."
|
|
||||||
|
|
||||||
# function header_info {
|
|
||||||
# clear
|
|
||||||
# cat <<"EOF"
|
|
||||||
# ____ __
|
|
||||||
# / / /___/ /___ _____
|
|
||||||
# / / / __ / __ `/ __ \
|
|
||||||
# / / / /_/ / /_/ / /_/ /
|
|
||||||
# /_/_/\__,_/\__,_/ .___/
|
|
||||||
# /_/
|
|
||||||
|
|
||||||
# EOF
|
|
||||||
# }
|
|
||||||
# header_info
|
|
||||||
# echo -e "Loading..."
|
|
||||||
# APP="lldap"
|
|
||||||
# var_disk="4"
|
|
||||||
# var_cpu="1"
|
|
||||||
# var_ram="512"
|
|
||||||
# var_os="debian"
|
|
||||||
# var_version="12"
|
|
||||||
# variables
|
|
||||||
# color
|
|
||||||
# catch_errors
|
|
||||||
|
|
||||||
# function default_settings() {
|
|
||||||
# CT_TYPE="1"
|
|
||||||
# PW=""
|
|
||||||
# CT_ID=$NEXTID
|
|
||||||
# HN=$NSAPP
|
|
||||||
# DISK_SIZE="$var_disk"
|
|
||||||
# CORE_COUNT="$var_cpu"
|
|
||||||
# RAM_SIZE="$var_ram"
|
|
||||||
# BRG="vmbr0"
|
|
||||||
# NET="dhcp"
|
|
||||||
# GATE=""
|
|
||||||
# APT_CACHER=""
|
|
||||||
# APT_CACHER_IP=""
|
|
||||||
# DISABLEIP6="no"
|
|
||||||
# MTU=""
|
|
||||||
# SD=""
|
|
||||||
# NS=""
|
|
||||||
# MAC=""
|
|
||||||
# VLAN=""
|
|
||||||
# SSH="no"
|
|
||||||
# VERB="no"
|
|
||||||
# echo_default
|
|
||||||
# }
|
|
||||||
|
|
||||||
# function update_script() {
|
|
||||||
# header_info
|
|
||||||
# if [[ ! -f /etc/systemd/system/lldap.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
|
||||||
# msg_info "Updating $APP"
|
|
||||||
# apt update
|
|
||||||
# apt upgrade -y lldap
|
|
||||||
# msg_ok "Updated $APP"
|
|
||||||
# exit
|
|
||||||
# }
|
|
||||||
|
|
||||||
# start
|
|
||||||
# build_container
|
|
||||||
# description
|
|
||||||
|
|
||||||
# msg_ok "Completed Successfully!\n"
|
|
||||||
# echo -e "${APP} should be reachable by going to the following URL.
|
|
||||||
# ${BL}http://${IP}:17170${CL} \n"
|
|
||||||
+1
-1
@@ -55,7 +55,7 @@ function default_settings() {
|
|||||||
function update_script() {
|
function update_script() {
|
||||||
header_info
|
header_info
|
||||||
if [[ ! -d /opt/mafl ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
if [[ ! -d /opt/mafl ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
||||||
whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "SET RESOURCES" "Please set the resources in your ${APP} LXC to ${var_cpu}vCPU and ${var_ram}RAM for the build process before continuing" 10 75
|
|
||||||
RELEASE=$(curl -s https://api.github.com/repos/hywax/mafl/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
|
RELEASE=$(curl -s https://api.github.com/repos/hywax/mafl/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
|
||||||
msg_info "Updating Mafl to v${RELEASE} (Patience)"
|
msg_info "Updating Mafl to v${RELEASE} (Patience)"
|
||||||
systemctl stop mafl
|
systemctl stop mafl
|
||||||
|
|||||||
+31
-2
@@ -54,8 +54,37 @@ function default_settings() {
|
|||||||
|
|
||||||
function update_script() {
|
function update_script() {
|
||||||
header_info
|
header_info
|
||||||
if [[ ! -d /root/Matterbridge ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
if [[ ! -d /opt/matterbridge ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
||||||
msg_error "Update via the Matterbridge UI"
|
|
||||||
|
RELEASE=$(curl -s https://api.github.com/repos/Luligu/matterbridge/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3)}')
|
||||||
|
if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then
|
||||||
|
msg_info "Stopping ${APP} Service"
|
||||||
|
systemctl stop matterbridge
|
||||||
|
msg_ok "Stopped ${APP} Service"
|
||||||
|
|
||||||
|
msg_info "Updating ${APP} to ${RELEASE}"
|
||||||
|
cd /opt/matterbridge
|
||||||
|
wget -q "https://github.com/Luligu/matterbridge/archive/refs/tags/${RELEASE}.zip"
|
||||||
|
unzip -q ${RELEASE}.zip
|
||||||
|
mv matterbridge-${RELEASE} /opt/matterbridge
|
||||||
|
cd /opt/matterbridge
|
||||||
|
npm ci >/dev/null 2>&1
|
||||||
|
npm run build >/dev/null 2>&1
|
||||||
|
echo "${RELEASE}" >/opt/${APP}_version.txt
|
||||||
|
msg_ok "Updated ${APP} to ${RELEASE}"
|
||||||
|
|
||||||
|
msg_info "Cleaning up"
|
||||||
|
rm /opt/${RELEASE}.zip
|
||||||
|
msg_ok "Cleaned"
|
||||||
|
|
||||||
|
msg_info "Starting ${APP} Service"
|
||||||
|
systemctl start matterbridge
|
||||||
|
sleep 1
|
||||||
|
msg_ok "Started ${APP} Service"
|
||||||
|
msg_ok "Updated Successfully!\n"
|
||||||
|
else
|
||||||
|
msg_ok "No update required. ${APP} is already at ${RELEASE}"
|
||||||
|
fi
|
||||||
exit
|
exit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
-88
@@ -1,88 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2024 tteck
|
|
||||||
# Author: tteck
|
|
||||||
# Co-Author: MickLesk (Canbiz)
|
|
||||||
# License: MIT
|
|
||||||
# https://github.com/tteck/Proxmox/raw/main/LICENSE
|
|
||||||
|
|
||||||
function header_info {
|
|
||||||
clear
|
|
||||||
cat <<"EOF"
|
|
||||||
__ ___
|
|
||||||
/ |/ /__ ____ ___ ____ _____
|
|
||||||
/ /|_/ / _ \/ __ `__ \/ __ \/ ___/
|
|
||||||
/ / / / __/ / / / / / /_/ (__ )
|
|
||||||
/_/ /_/\___/_/ /_/ /_/\____/____/
|
|
||||||
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
header_info
|
|
||||||
echo -e "Loading..."
|
|
||||||
APP="Memos"
|
|
||||||
var_disk="7"
|
|
||||||
var_cpu="2"
|
|
||||||
var_ram="2048"
|
|
||||||
var_os="debian"
|
|
||||||
var_version="12"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function default_settings() {
|
|
||||||
CT_TYPE="1"
|
|
||||||
PW=""
|
|
||||||
CT_ID=$NEXTID
|
|
||||||
HN=$NSAPP
|
|
||||||
DISK_SIZE="$var_disk"
|
|
||||||
CORE_COUNT="$var_cpu"
|
|
||||||
RAM_SIZE="$var_ram"
|
|
||||||
BRG="vmbr0"
|
|
||||||
NET="dhcp"
|
|
||||||
GATE=""
|
|
||||||
APT_CACHER=""
|
|
||||||
APT_CACHER_IP=""
|
|
||||||
DISABLEIP6="no"
|
|
||||||
MTU=""
|
|
||||||
SD=""
|
|
||||||
NS=""
|
|
||||||
MAC=""
|
|
||||||
VLAN=""
|
|
||||||
SSH="no"
|
|
||||||
VERB="no"
|
|
||||||
echo_default
|
|
||||||
}
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
if [[ ! -d /opt/memos ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
|
||||||
msg_info "Updating $APP (Patience)"
|
|
||||||
cd /opt/memos
|
|
||||||
output=$(git pull --no-rebase)
|
|
||||||
if echo "$output" | grep -q "Already up to date."
|
|
||||||
then
|
|
||||||
msg_ok "$APP is already up to date."
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
systemctl stop memos
|
|
||||||
cd /opt/memos/web
|
|
||||||
pnpm i --frozen-lockfile &>/dev/null
|
|
||||||
pnpm build &>/dev/null
|
|
||||||
cd /opt/memos
|
|
||||||
mkdir -p /opt/memos/server/dist
|
|
||||||
cp -r web/dist/* /opt/memos/server/dist/
|
|
||||||
cp -r web/dist/* /opt/memos/server/router/frontend/dist/
|
|
||||||
go build -o /opt/memos/memos -tags=embed bin/memos/main.go &>/dev/null
|
|
||||||
systemctl start memos
|
|
||||||
msg_ok "Updated $APP"
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed Successfully!\n"
|
|
||||||
echo -e "${APP} should be reachable by going to the following URL.
|
|
||||||
${BL}http://${IP}:9030${CL} \n"
|
|
||||||
-72
@@ -1,72 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
# source <(curl -s https://raw.githubusercontent.com/asylumexp/Proxmox/main/misc/build.func)
|
|
||||||
# # Copyright (c) 2021-2024 tteck
|
|
||||||
# # Author: tteck
|
|
||||||
# # Co-Author: MickLesk (Canbiz)
|
|
||||||
# # License: MIT
|
|
||||||
# # https://github.com/tteck/Proxmox/raw/main/LICENSE
|
|
||||||
|
|
||||||
echo "Unsupported."
|
|
||||||
|
|
||||||
# function header_info {
|
|
||||||
# clear
|
|
||||||
# cat <<"EOF"
|
|
||||||
# __ ___ _____ ____ __
|
|
||||||
# / |/ /_ __/ ___// __ \ / /
|
|
||||||
# / /|_/ / / / /\__ \/ / / / / /
|
|
||||||
# / / / / /_/ /___/ / /_/ / / /___
|
|
||||||
# /_/ /_/\__, //____/\___\_\/_____/
|
|
||||||
# /____/
|
|
||||||
# EOF
|
|
||||||
# }
|
|
||||||
# header_info
|
|
||||||
# echo -e "Loading..."
|
|
||||||
# APP="MySQL"
|
|
||||||
# var_disk="4"
|
|
||||||
# var_cpu="1"
|
|
||||||
# var_ram="1024"
|
|
||||||
# var_os="debian"
|
|
||||||
# var_version="12"
|
|
||||||
# variables
|
|
||||||
# color
|
|
||||||
# catch_errors
|
|
||||||
|
|
||||||
# function default_settings() {
|
|
||||||
# CT_TYPE="1"
|
|
||||||
# PW=""
|
|
||||||
# CT_ID=$NEXTID
|
|
||||||
# HN=$NSAPP
|
|
||||||
# DISK_SIZE="$var_disk"
|
|
||||||
# CORE_COUNT="$var_cpu"
|
|
||||||
# RAM_SIZE="$var_ram"
|
|
||||||
# BRG="vmbr0"
|
|
||||||
# NET="dhcp"
|
|
||||||
# GATE=""
|
|
||||||
# APT_CACHER=""
|
|
||||||
# APT_CACHER_IP=""
|
|
||||||
# DISABLEIP6="no"
|
|
||||||
# MTU=""
|
|
||||||
# SD=""
|
|
||||||
# NS=""
|
|
||||||
# MAC=""
|
|
||||||
# VLAN=""
|
|
||||||
# SSH="no"
|
|
||||||
# VERB="no"
|
|
||||||
# echo_default
|
|
||||||
# }
|
|
||||||
|
|
||||||
# function update_script() {
|
|
||||||
# header_info
|
|
||||||
# if [[ ! -f /usr/share/keyrings/mysql.gpg ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
|
||||||
# msg_info "Updating ${APP} LXC"
|
|
||||||
# apt-get update &>/dev/null
|
|
||||||
# apt-get -y upgrade &>/dev/null
|
|
||||||
# msg_ok "Updated Successfully"
|
|
||||||
# exit
|
|
||||||
# }
|
|
||||||
|
|
||||||
# start
|
|
||||||
# build_container
|
|
||||||
# description
|
|
||||||
|
|
||||||
# msg_ok "Completed Successfully!\n"
|
|
||||||
@@ -65,7 +65,6 @@ if [[ ! -f /etc/systemd/system/n8n.service ]]; then msg_error "No ${APP} Install
|
|||||||
fi
|
fi
|
||||||
msg_info "Updating ${APP} LXC"
|
msg_info "Updating ${APP} LXC"
|
||||||
npm update -g n8n &>/dev/null
|
npm update -g n8n &>/dev/null
|
||||||
systemctl restart n8n
|
|
||||||
msg_ok "Updated Successfully"
|
msg_ok "Updated Successfully"
|
||||||
exit
|
exit
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,8 +23,8 @@ APP="Nginx Proxy Manager"
|
|||||||
var_disk="4"
|
var_disk="4"
|
||||||
var_cpu="2"
|
var_cpu="2"
|
||||||
var_ram="1024"
|
var_ram="1024"
|
||||||
var_os="debian"
|
var_os="ubuntu"
|
||||||
var_version="12"
|
var_version="22.04"
|
||||||
variables
|
variables
|
||||||
color
|
color
|
||||||
catch_errors
|
catch_errors
|
||||||
@@ -61,7 +61,7 @@ function update_script() {
|
|||||||
fi
|
fi
|
||||||
if ! command -v pnpm &> /dev/null; then
|
if ! command -v pnpm &> /dev/null; then
|
||||||
msg_info "Installing pnpm"
|
msg_info "Installing pnpm"
|
||||||
#export NODE_OPTIONS=--openssl-legacy-provider
|
export NODE_OPTIONS=--openssl-legacy-provider
|
||||||
npm install -g pnpm@8.15 &>/dev/null
|
npm install -g pnpm@8.15 &>/dev/null
|
||||||
msg_ok "Installed pnpm"
|
msg_ok "Installed pnpm"
|
||||||
fi
|
fi
|
||||||
@@ -168,7 +168,6 @@ EOF
|
|||||||
|
|
||||||
msg_info "Starting Services"
|
msg_info "Starting Services"
|
||||||
sed -i 's/user npm/user root/g; s/^pid/#pid/g' /usr/local/openresty/nginx/conf/nginx.conf
|
sed -i 's/user npm/user root/g; s/^pid/#pid/g' /usr/local/openresty/nginx/conf/nginx.conf
|
||||||
sed -i 's/su npm npm/su root root/g' /etc/logrotate.d/nginx-proxy-manager
|
|
||||||
sed -i 's/include-system-site-packages = false/include-system-site-packages = true/g' /opt/certbot/pyvenv.cfg
|
sed -i 's/include-system-site-packages = false/include-system-site-packages = true/g' /opt/certbot/pyvenv.cfg
|
||||||
systemctl enable -q --now openresty
|
systemctl enable -q --now openresty
|
||||||
systemctl enable -q --now npm
|
systemctl enable -q --now npm
|
||||||
@@ -186,6 +185,9 @@ start
|
|||||||
build_container
|
build_container
|
||||||
description
|
description
|
||||||
|
|
||||||
|
msg_info "Setting Container to Normal Resources"
|
||||||
|
pct set $CTID -cores 1
|
||||||
|
msg_ok "Set Container to Normal Resources"
|
||||||
msg_ok "Completed Successfully!\n"
|
msg_ok "Completed Successfully!\n"
|
||||||
echo -e "${APP} should be reachable by going to the following URL.
|
echo -e "${APP} should be reachable by going to the following URL.
|
||||||
${BL}http://${IP}:81${CL}\n"
|
${BL}http://${IP}:81${CL}\n"
|
||||||
|
|||||||
@@ -1,72 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2024 tteck
|
|
||||||
# Author: tteck
|
|
||||||
# Co-Author: havardthom
|
|
||||||
# License: MIT
|
|
||||||
# https://github.com/tteck/Proxmox/raw/main/LICENSE
|
|
||||||
|
|
||||||
function header_info {
|
|
||||||
clear
|
|
||||||
cat <<"EOF"
|
|
||||||
_ _______ ____ ______ __
|
|
||||||
/ | / /__ / / __ )/ ____/__ / /_
|
|
||||||
/ |/ / / / / __ / / __/ _ \/ __/
|
|
||||||
/ /| / / /__/ /_/ / /_/ / __/ /_
|
|
||||||
/_/ |_/ /____/_____/\____/\___/\__/
|
|
||||||
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
header_info
|
|
||||||
echo -e "Loading..."
|
|
||||||
APP="NZBGet"
|
|
||||||
var_disk="4"
|
|
||||||
var_cpu="2"
|
|
||||||
var_ram="2048"
|
|
||||||
var_os="debian"
|
|
||||||
var_version="12"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function default_settings() {
|
|
||||||
CT_TYPE="1"
|
|
||||||
PW=""
|
|
||||||
CT_ID=$NEXTID
|
|
||||||
HN=$NSAPP
|
|
||||||
DISK_SIZE="$var_disk"
|
|
||||||
CORE_COUNT="$var_cpu"
|
|
||||||
RAM_SIZE="$var_ram"
|
|
||||||
BRG="vmbr0"
|
|
||||||
NET="dhcp"
|
|
||||||
GATE=""
|
|
||||||
APT_CACHER=""
|
|
||||||
APT_CACHER_IP=""
|
|
||||||
DISABLEIP6="no"
|
|
||||||
MTU=""
|
|
||||||
SD=""
|
|
||||||
NS=""
|
|
||||||
MAC=""
|
|
||||||
VLAN=""
|
|
||||||
SSH="no"
|
|
||||||
VERB="no"
|
|
||||||
echo_default
|
|
||||||
}
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
if [[ ! -f /lib/systemd/system/nzbget.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
|
||||||
msg_info "Updating $APP LXC"
|
|
||||||
apt-get update &>/dev/null
|
|
||||||
apt-get -y upgrade &>/dev/null
|
|
||||||
msg_ok "Updated $APP LXC"
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed Successfully!\n"
|
|
||||||
echo -e "${APP} should be reachable by going to the following URL.
|
|
||||||
${BL}http://${IP}:6789${CL} \n"
|
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2024 tteck
|
|
||||||
# Author: tteck
|
|
||||||
# Co-Author: havardthom
|
|
||||||
# License: MIT
|
|
||||||
# https://github.com/tteck/Proxmox/raw/main/LICENSE
|
|
||||||
|
|
||||||
function header_info {
|
|
||||||
clear
|
|
||||||
cat <<"EOF"
|
|
||||||
____ ____
|
|
||||||
/ __ \/ / /___ _____ ___ ____ _
|
|
||||||
/ / / / / / __ `/ __ `__ \/ __ `/
|
|
||||||
/ /_/ / / / /_/ / / / / / / /_/ /
|
|
||||||
\____/_/_/\__,_/_/ /_/ /_/\__,_/
|
|
||||||
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
header_info
|
|
||||||
echo -e "Loading..."
|
|
||||||
APP="Ollama"
|
|
||||||
var_disk="24"
|
|
||||||
var_cpu="4"
|
|
||||||
var_ram="4096"
|
|
||||||
var_os="ubuntu"
|
|
||||||
var_version="22.04"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function default_settings() {
|
|
||||||
CT_TYPE="1"
|
|
||||||
PW=""
|
|
||||||
CT_ID=$NEXTID
|
|
||||||
HN=$NSAPP
|
|
||||||
DISK_SIZE="$var_disk"
|
|
||||||
CORE_COUNT="$var_cpu"
|
|
||||||
RAM_SIZE="$var_ram"
|
|
||||||
BRG="vmbr0"
|
|
||||||
NET="dhcp"
|
|
||||||
GATE=""
|
|
||||||
APT_CACHER=""
|
|
||||||
APT_CACHER_IP=""
|
|
||||||
DISABLEIP6="no"
|
|
||||||
MTU=""
|
|
||||||
SD=""
|
|
||||||
NS=""
|
|
||||||
MAC=""
|
|
||||||
VLAN=""
|
|
||||||
SSH="no"
|
|
||||||
VERB="no"
|
|
||||||
echo_default
|
|
||||||
}
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
if [[ ! -d /opt/ollama ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
|
||||||
msg_info "Updating ${APP}"
|
|
||||||
apt-get update &>/dev/null
|
|
||||||
apt-get -y upgrade &>/dev/null
|
|
||||||
msg_ok "Updated Successfully"
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed Successfully!\n"
|
|
||||||
echo -e "${APP} should be reachable by going to the following URL.
|
|
||||||
${BL}http://${IP}:11434${CL} \n"
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2024 tteck
|
|
||||||
# Author: tteck
|
|
||||||
# Co-Author: havardthom
|
|
||||||
# License: MIT
|
|
||||||
# https://github.com/tteck/Proxmox/raw/main/LICENSE
|
|
||||||
|
|
||||||
function header_info {
|
|
||||||
clear
|
|
||||||
cat <<"EOF"
|
|
||||||
____ _ __ __ __ ______
|
|
||||||
/ __ \____ ___ ____ | | / /__ / /_ / / / / _/
|
|
||||||
/ / / / __ \/ _ \/ __ \ | | /| / / _ \/ __ \/ / / // /
|
|
||||||
/ /_/ / /_/ / __/ / / / | |/ |/ / __/ /_/ / /_/ // /
|
|
||||||
\____/ .___/\___/_/ /_/ |__/|__/\___/_.___/\____/___/
|
|
||||||
/_/
|
|
||||||
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
header_info
|
|
||||||
echo -e "Loading..."
|
|
||||||
APP="Open WebUI"
|
|
||||||
var_disk="16"
|
|
||||||
var_cpu="4"
|
|
||||||
var_ram="4096"
|
|
||||||
var_os="debian"
|
|
||||||
var_version="12"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function default_settings() {
|
|
||||||
CT_TYPE="1"
|
|
||||||
PW=""
|
|
||||||
CT_ID=$NEXTID
|
|
||||||
HN=$NSAPP
|
|
||||||
DISK_SIZE="$var_disk"
|
|
||||||
CORE_COUNT="$var_cpu"
|
|
||||||
RAM_SIZE="$var_ram"
|
|
||||||
BRG="vmbr0"
|
|
||||||
NET="dhcp"
|
|
||||||
GATE=""
|
|
||||||
APT_CACHER=""
|
|
||||||
APT_CACHER_IP=""
|
|
||||||
DISABLEIP6="no"
|
|
||||||
MTU=""
|
|
||||||
SD=""
|
|
||||||
NS=""
|
|
||||||
MAC=""
|
|
||||||
VLAN=""
|
|
||||||
SSH="no"
|
|
||||||
VERB="no"
|
|
||||||
echo_default
|
|
||||||
}
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
if [[ ! -d /opt/open-webui ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
|
||||||
msg_info "Updating ${APP} (Patience)"
|
|
||||||
cd /opt/open-webui
|
|
||||||
output=$(git pull --no-rebase)
|
|
||||||
if echo "$output" | grep -q "Already up to date."
|
|
||||||
then
|
|
||||||
msg_ok "$APP is already up to date."
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
systemctl stop open-webui.service
|
|
||||||
npm install &>/dev/null
|
|
||||||
export NODE_OPTIONS="--max-old-space-size=3584"
|
|
||||||
npm run build &>/dev/null
|
|
||||||
cd ./backend
|
|
||||||
pip install -r requirements.txt -U &>/dev/null
|
|
||||||
systemctl start open-webui.service
|
|
||||||
msg_ok "Updated Successfully"
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed Successfully!\n"
|
|
||||||
echo -e "${APP} should be reachable by going to the following URL.
|
|
||||||
${BL}http://${IP}:8080${CL} \n"
|
|
||||||
+1
-1
@@ -21,7 +21,7 @@ echo -e "Loading..."
|
|||||||
APP="Overseerr"
|
APP="Overseerr"
|
||||||
var_disk="8"
|
var_disk="8"
|
||||||
var_cpu="2"
|
var_cpu="2"
|
||||||
var_ram="3072"
|
var_ram="2048"
|
||||||
var_os="debian"
|
var_os="debian"
|
||||||
var_version="12"
|
var_version="12"
|
||||||
variables
|
variables
|
||||||
|
|||||||
@@ -67,18 +67,6 @@ function update_script() {
|
|||||||
header_info
|
header_info
|
||||||
if [ "$UPD" == "1" ]; then
|
if [ "$UPD" == "1" ]; then
|
||||||
if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then
|
if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then
|
||||||
if [[ "$(gs --version 2>/dev/null)" != "10.04.0" ]]; then
|
|
||||||
msg_info "Updating Ghostscript"
|
|
||||||
cd /tmp
|
|
||||||
wget -q https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/gs10040/ghostscript-10.04.0.tar.gz
|
|
||||||
tar -xzf ghostscript-10.04.0.tar.gz
|
|
||||||
cd ghostscript-10.04.0
|
|
||||||
./configure &>/dev/null
|
|
||||||
make &>/dev/null
|
|
||||||
sudo make install &>/dev/null
|
|
||||||
rm -rf /tmp/ghostscript*
|
|
||||||
msg_ok "Ghostscript updated to 10.04.0"
|
|
||||||
fi
|
|
||||||
msg_info "Stopping all Paperless-ngx Services"
|
msg_info "Stopping all Paperless-ngx Services"
|
||||||
systemctl stop paperless-consumer paperless-webserver paperless-scheduler paperless-task-queue.service
|
systemctl stop paperless-consumer paperless-webserver paperless-scheduler paperless-task-queue.service
|
||||||
msg_ok "Stopped all Paperless-ngx Services"
|
msg_ok "Stopped all Paperless-ngx Services"
|
||||||
|
|||||||
@@ -55,7 +55,6 @@ function default_settings() {
|
|||||||
function update_script() {
|
function update_script() {
|
||||||
header_info
|
header_info
|
||||||
if [[ ! -f /etc/systemd/system/peanut.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
if [[ ! -f /etc/systemd/system/peanut.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
||||||
whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "SET RESOURCES" "Please set the resources in your ${APP} LXC to ${var_cpu}vCPU and ${var_ram}RAM for the build process before continuing" 10 75
|
|
||||||
RELEASE=$(curl -sL https://api.github.com/repos/Brandawg93/PeaNUT/releases/latest | grep '"tag_name":' | cut -d'"' -f4)
|
RELEASE=$(curl -sL https://api.github.com/repos/Brandawg93/PeaNUT/releases/latest | grep '"tag_name":' | cut -d'"' -f4)
|
||||||
if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then
|
if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then
|
||||||
msg_info "Updating $APP to ${RELEASE}"
|
msg_info "Updating $APP to ${RELEASE}"
|
||||||
@@ -67,8 +66,6 @@ function update_script() {
|
|||||||
pnpm i &>/dev/null
|
pnpm i &>/dev/null
|
||||||
pnpm run build &>/dev/null
|
pnpm run build &>/dev/null
|
||||||
cp -r .next/static .next/standalone/.next/
|
cp -r .next/static .next/standalone/.next/
|
||||||
mkdir -p /opt/peanut/.next/standalone/config
|
|
||||||
ln -sf /etc/peanut/settings.yml /opt/peanut/.next/standalone/config/settings.yml
|
|
||||||
systemctl start peanut
|
systemctl start peanut
|
||||||
echo "${RELEASE}" >/opt/${APP}_version.txt
|
echo "${RELEASE}" >/opt/${APP}_version.txt
|
||||||
msg_ok "Updated $APP to ${RELEASE}"
|
msg_ok "Updated $APP to ${RELEASE}"
|
||||||
|
|||||||
+2
-4
@@ -56,7 +56,7 @@ function update_script() {
|
|||||||
header_info
|
header_info
|
||||||
if [[ ! -d /opt/pingvin-share ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
if [[ ! -d /opt/pingvin-share ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
||||||
msg_info "Stopping Pingvin Share"
|
msg_info "Stopping Pingvin Share"
|
||||||
systemctl stop pm2-root.service
|
pm2 stop pingvin-share-backend pingvin-share-frontend &>/dev/null
|
||||||
msg_ok "Stopped Pingvin Share"
|
msg_ok "Stopped Pingvin Share"
|
||||||
|
|
||||||
msg_info "Updating Pingvin Share"
|
msg_info "Updating Pingvin Share"
|
||||||
@@ -64,15 +64,13 @@ cd /opt/pingvin-share
|
|||||||
git fetch --tags
|
git fetch --tags
|
||||||
git checkout $(git describe --tags `git rev-list --tags --max-count=1`) &>/dev/null
|
git checkout $(git describe --tags `git rev-list --tags --max-count=1`) &>/dev/null
|
||||||
cd backend
|
cd backend
|
||||||
npm install &>/dev/null
|
|
||||||
npm run build &>/dev/null
|
npm run build &>/dev/null
|
||||||
cd ../frontend
|
cd ../frontend
|
||||||
npm install &>/dev/null
|
|
||||||
npm run build &>/dev/null
|
npm run build &>/dev/null
|
||||||
msg_ok "Updated Pingvin Share"
|
msg_ok "Updated Pingvin Share"
|
||||||
|
|
||||||
msg_info "Starting Pingvin Share"
|
msg_info "Starting Pingvin Share"
|
||||||
systemctl start pm2-root.service
|
pm2 start pingvin-share-backend pingvin-share-frontend &>/dev/null
|
||||||
msg_ok "Started Pingvin Share"
|
msg_ok "Started Pingvin Share"
|
||||||
|
|
||||||
msg_ok "Updated Successfully"
|
msg_ok "Updated Successfully"
|
||||||
|
|||||||
+1
-1
@@ -29,7 +29,7 @@ color
|
|||||||
catch_errors
|
catch_errors
|
||||||
|
|
||||||
function default_settings() {
|
function default_settings() {
|
||||||
CT_TYPE="0"
|
CT_TYPE="1"
|
||||||
PW=""
|
PW=""
|
||||||
CT_ID=$NEXTID
|
CT_ID=$NEXTID
|
||||||
HN=$NSAPP
|
HN=$NSAPP
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ if [ "$UPD" == "3" ]; then
|
|||||||
curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bash &>/dev/null
|
curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bash &>/dev/null
|
||||||
filebrowser config init -a '0.0.0.0' &>/dev/null
|
filebrowser config init -a '0.0.0.0' &>/dev/null
|
||||||
filebrowser config set -a '0.0.0.0' &>/dev/null
|
filebrowser config set -a '0.0.0.0' &>/dev/null
|
||||||
filebrowser users add admin helper-scripts.com --perm.admin &>/dev/null
|
filebrowser users add admin changeme --perm.admin &>/dev/null
|
||||||
msg_ok "Installed FileBrowser"
|
msg_ok "Installed FileBrowser"
|
||||||
|
|
||||||
msg_info "Creating Service"
|
msg_info "Creating Service"
|
||||||
@@ -122,7 +122,7 @@ if [ "$UPD" == "3" ]; then
|
|||||||
|
|
||||||
msg_ok "Completed Successfully!\n"
|
msg_ok "Completed Successfully!\n"
|
||||||
echo -e "FileBrowser should be reachable by going to the following URL.
|
echo -e "FileBrowser should be reachable by going to the following URL.
|
||||||
${BL}http://$IP:8080${CL} admin|helper-scripts.com\n"
|
${BL}http://$IP:8080${CL} admin|changeme\n"
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
if [ "$UPD" == "4" ]; then
|
if [ "$UPD" == "4" ]; then
|
||||||
|
|||||||
+1
-23
@@ -55,29 +55,7 @@ function default_settings() {
|
|||||||
function update_script() {
|
function update_script() {
|
||||||
header_info
|
header_info
|
||||||
if [[ ! -f /etc/systemd/system/prometheus.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
if [[ ! -f /etc/systemd/system/prometheus.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
||||||
RELEASE=$(curl -s https://api.github.com/repos/prometheus/prometheus/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
|
msg_error "There is currently no update path available."
|
||||||
if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then
|
|
||||||
msg_info "Stopping ${APP}"
|
|
||||||
systemctl stop prometheus
|
|
||||||
msg_ok "Stopped ${APP}"
|
|
||||||
|
|
||||||
msg_info "Updating ${APP} to ${RELEASE}"
|
|
||||||
wget -q https://github.com/prometheus/prometheus/releases/download/v${RELEASE}/prometheus-${RELEASE}.linux-amd64.tar.gz
|
|
||||||
tar -xf prometheus-${RELEASE}.linux-amd64.tar.gz
|
|
||||||
cd prometheus-${RELEASE}.linux-amd64
|
|
||||||
cp -rf prometheus promtool /usr/local/bin/
|
|
||||||
cd ~
|
|
||||||
rm -rf prometheus-${RELEASE}.linux-amd64 prometheus-${RELEASE}.linux-amd64.tar.gz
|
|
||||||
echo "${RELEASE}" >/opt/${APP}_version.txt
|
|
||||||
msg_ok "Updated ${APP} to ${RELEASE}"
|
|
||||||
|
|
||||||
msg_info "Starting ${APP}"
|
|
||||||
systemctl start prometheus
|
|
||||||
msg_ok "Started ${APP}"
|
|
||||||
msg_ok "Updated Successfully"
|
|
||||||
else
|
|
||||||
msg_ok "No update required. ${APP} is already at ${RELEASE}"
|
|
||||||
fi
|
|
||||||
exit
|
exit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-1
@@ -55,7 +55,10 @@ function default_settings() {
|
|||||||
function update_script() {
|
function update_script() {
|
||||||
header_info
|
header_info
|
||||||
if [[ ! -d /var/lib/radarr/ ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
if [[ ! -d /var/lib/radarr/ ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
||||||
msg_error "There is currently no update path available."
|
msg_info "Updating $APP LXC"
|
||||||
|
apt-get update &>/dev/null
|
||||||
|
apt-get -y upgrade &>/dev/null
|
||||||
|
msg_ok "Updated $APP LXC"
|
||||||
exit
|
exit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-8
@@ -55,21 +55,16 @@ function default_settings() {
|
|||||||
function update_script() {
|
function update_script() {
|
||||||
header_info
|
header_info
|
||||||
if [[ ! -d /opt/sabnzbd ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
if [[ ! -d /opt/sabnzbd ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
||||||
RELEASE=$(curl -s https://api.github.com/repos/sabnzbd/sabnzbd/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
|
msg_info "Updating $APP"
|
||||||
if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then
|
|
||||||
msg_info "Updating $APP to ${RELEASE}"
|
|
||||||
systemctl stop sabnzbd.service
|
systemctl stop sabnzbd.service
|
||||||
|
RELEASE=$(curl -s https://api.github.com/repos/sabnzbd/sabnzbd/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
|
||||||
tar zxvf <(curl -fsSL https://github.com/sabnzbd/sabnzbd/releases/download/$RELEASE/SABnzbd-${RELEASE}-src.tar.gz) &>/dev/null
|
tar zxvf <(curl -fsSL https://github.com/sabnzbd/sabnzbd/releases/download/$RELEASE/SABnzbd-${RELEASE}-src.tar.gz) &>/dev/null
|
||||||
\cp -r SABnzbd-${RELEASE}/* /opt/sabnzbd &>/dev/null
|
\cp -r SABnzbd-${RELEASE}/* /opt/sabnzbd &>/dev/null
|
||||||
rm -rf SABnzbd-${RELEASE}
|
rm -rf SABnzbd-${RELEASE}
|
||||||
cd /opt/sabnzbd
|
cd /opt/sabnzbd
|
||||||
python3 -m pip install -r requirements.txt &>/dev/null
|
python3 -m pip install -r requirements.txt &>/dev/null
|
||||||
echo "${RELEASE}" >/opt/${APP}_version.txt
|
|
||||||
systemctl start sabnzbd.service
|
systemctl start sabnzbd.service
|
||||||
msg_ok "Updated ${APP} to ${RELEASE}"
|
msg_ok "Updated $APP"
|
||||||
else
|
|
||||||
msg_info "No update required. ${APP} is already at ${RELEASE}"
|
|
||||||
fi
|
|
||||||
exit
|
exit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -30,7 +30,7 @@ color
|
|||||||
catch_errors
|
catch_errors
|
||||||
|
|
||||||
function default_settings() {
|
function default_settings() {
|
||||||
CT_TYPE="0"
|
CT_TYPE="1"
|
||||||
PW=""
|
PW=""
|
||||||
CT_ID=$NEXTID
|
CT_ID=$NEXTID
|
||||||
HN=$NSAPP
|
HN=$NSAPP
|
||||||
|
|||||||
+1
-1
@@ -74,7 +74,7 @@ if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_v
|
|||||||
unzip -q spoolman.zip -d spoolman
|
unzip -q spoolman.zip -d spoolman
|
||||||
cd spoolman
|
cd spoolman
|
||||||
pip3 install -r requirements.txt >/dev/null 2>&1
|
pip3 install -r requirements.txt >/dev/null 2>&1
|
||||||
wget -q https://raw.githubusercontent.com/Donkie/Spoolman/master/.env.example -O .env
|
cp .env.example .env
|
||||||
echo "${RELEASE}" >/opt/${APP}_version.txt
|
echo "${RELEASE}" >/opt/${APP}_version.txt
|
||||||
msg_ok "Updated ${APP} to ${RELEASE}"
|
msg_ok "Updated ${APP} to ${RELEASE}"
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -29,7 +29,7 @@ color
|
|||||||
catch_errors
|
catch_errors
|
||||||
|
|
||||||
function default_settings() {
|
function default_settings() {
|
||||||
CT_TYPE="0"
|
CT_TYPE="1"
|
||||||
PW=""
|
PW=""
|
||||||
CT_ID=$NEXTID
|
CT_ID=$NEXTID
|
||||||
HN=$NSAPP
|
HN=$NSAPP
|
||||||
|
|||||||
-115
@@ -1,115 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -s https://raw.githubusercontent.com/asylumexp/Proxmox/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2024 tteck
|
|
||||||
# Author: tteck
|
|
||||||
# Co-Author: MickLesk (Canbiz)
|
|
||||||
# License: MIT
|
|
||||||
# https://github.com/tteck/Proxmox/raw/main/LICENSE
|
|
||||||
|
|
||||||
function header_info {
|
|
||||||
clear
|
|
||||||
cat <<"EOF"
|
|
||||||
_______ _ _
|
|
||||||
/_ __(_)___ _____ (_|_)
|
|
||||||
/ / / / __ `/ __ \ / / /
|
|
||||||
/ / / / /_/ / / / / / / /
|
|
||||||
/_/ /_/\__,_/_/ /_/_/ /_/
|
|
||||||
/___/
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
header_info
|
|
||||||
echo -e "Loading..."
|
|
||||||
APP="Tianji"
|
|
||||||
var_disk="12"
|
|
||||||
var_cpu="4"
|
|
||||||
var_ram="4096"
|
|
||||||
var_os="debian"
|
|
||||||
var_version="12"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function default_settings() {
|
|
||||||
CT_TYPE="1"
|
|
||||||
PW=""
|
|
||||||
CT_ID=$NEXTID
|
|
||||||
HN=$NSAPP
|
|
||||||
DISK_SIZE="$var_disk"
|
|
||||||
CORE_COUNT="$var_cpu"
|
|
||||||
RAM_SIZE="$var_ram"
|
|
||||||
BRG="vmbr0"
|
|
||||||
NET="dhcp"
|
|
||||||
GATE=""
|
|
||||||
APT_CACHER=""
|
|
||||||
APT_CACHER_IP=""
|
|
||||||
DISABLEIP6="no"
|
|
||||||
MTU=""
|
|
||||||
SD=""
|
|
||||||
NS=""
|
|
||||||
MAC=""
|
|
||||||
VLAN=""
|
|
||||||
SSH="no"
|
|
||||||
VERB="no"
|
|
||||||
echo_default
|
|
||||||
}
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
if [[ ! -d /opt/tianji ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
|
||||||
if (( $(df /boot | awk 'NR==2{gsub("%","",$5); print $5}') > 80 )); then
|
|
||||||
read -r -p "Warning: Storage is dangerously low, continue anyway? <y/N> " prompt
|
|
||||||
[[ ${prompt,,} =~ ^(y|yes)$ ]] || exit
|
|
||||||
fi
|
|
||||||
RELEASE=$(curl -s https://api.github.com/repos/msgbyte/tianji/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
|
|
||||||
if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then
|
|
||||||
whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "SET RESOURCES" "Please set the resources in your ${APP} LXC to ${var_cpu}vCPU and ${var_ram}RAM for the build process before continuing" 10 75
|
|
||||||
msg_info "Stopping ${APP} Service"
|
|
||||||
systemctl stop tianji
|
|
||||||
msg_ok "Stopped ${APP} Service"
|
|
||||||
msg_info "Updating ${APP} to ${RELEASE}"
|
|
||||||
cd /opt
|
|
||||||
cp /opt/tianji/src/server/.env /opt/.env
|
|
||||||
mv /opt/tianji /opt/tianji_bak
|
|
||||||
wget -q "https://github.com/msgbyte/tianji/archive/refs/tags/v${RELEASE}.zip"
|
|
||||||
unzip -q v${RELEASE}.zip
|
|
||||||
mv tianji-${RELEASE} /opt/tianji
|
|
||||||
cd tianji
|
|
||||||
pnpm install --filter @tianji/client... --config.dedupe-peer-dependents=false --frozen-lockfile >/dev/null 2>&1
|
|
||||||
pnpm build:static >/dev/null 2>&1
|
|
||||||
pnpm install --filter @tianji/server... --config.dedupe-peer-dependents=false >/dev/null 2>&1
|
|
||||||
mkdir -p ./src/server/public >/dev/null 2>&1
|
|
||||||
cp -r ./geo ./src/server/public >/dev/null 2>&1
|
|
||||||
pnpm build:server >/dev/null 2>&1
|
|
||||||
mv /opt/.env /opt/tianji/src/server/.env
|
|
||||||
cd src/server
|
|
||||||
pnpm db:migrate:apply >/dev/null 2>&1
|
|
||||||
echo "${RELEASE}" >/opt/${APP}_version.txt
|
|
||||||
msg_ok "Updated ${APP} to ${RELEASE}"
|
|
||||||
msg_info "Starting ${APP}"
|
|
||||||
systemctl start tianji
|
|
||||||
msg_ok "Started ${APP}"
|
|
||||||
msg_info "Cleaning up"
|
|
||||||
rm -R /opt/v${RELEASE}.zip
|
|
||||||
rm -rf /opt/tianji_bak
|
|
||||||
rm -rf /opt/tianji/src/client
|
|
||||||
rm -rf /opt/tianji/website
|
|
||||||
rm -rf /opt/tianji/reporter
|
|
||||||
msg_ok "Cleaned"
|
|
||||||
msg_ok "Updated Successfully"
|
|
||||||
else
|
|
||||||
msg_ok "No update required. ${APP} is already at ${RELEASE}."
|
|
||||||
fi
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_info "Setting Container to Normal Resources"
|
|
||||||
pct set $CTID -memory 1024
|
|
||||||
pct set $CTID -cores 1
|
|
||||||
msg_ok "Set Container to Normal Resources"
|
|
||||||
|
|
||||||
msg_ok "Completed Successfully!\n"
|
|
||||||
echo -e "${APP} Setup should be reachable by going to the following URL.
|
|
||||||
${BL}http://${IP}:12345${CL} \n"
|
|
||||||
+1
-2
@@ -55,14 +55,13 @@ function default_settings() {
|
|||||||
function update_script() {
|
function update_script() {
|
||||||
header_info
|
header_info
|
||||||
if [[ ! -f /etc/systemd/system/traefik.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
if [[ ! -f /etc/systemd/system/traefik.service ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
||||||
RELEASE=$(curl -s https://api.github.com/repos/traefik/traefik/releases | grep -oP '"tag_name":\s*"v\K[\d.]+?(?=")' | sort -V | tail -n 1)
|
RELEASE=$(curl -s https://api.github.com/repos/traefik/traefik/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
|
||||||
msg_info "Updating $APP LXC"
|
msg_info "Updating $APP LXC"
|
||||||
if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then
|
if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then
|
||||||
wget -q https://github.com/traefik/traefik/releases/download/v${RELEASE}/traefik_v${RELEASE}_linux_arm64.tar.gz
|
wget -q https://github.com/traefik/traefik/releases/download/v${RELEASE}/traefik_v${RELEASE}_linux_arm64.tar.gz
|
||||||
tar -C /tmp -xzf traefik*.tar.gz
|
tar -C /tmp -xzf traefik*.tar.gz
|
||||||
mv /tmp/traefik /usr/bin/
|
mv /tmp/traefik /usr/bin/
|
||||||
rm -rf traefik*.tar.gz
|
rm -rf traefik*.tar.gz
|
||||||
systemctl restart traefik.service
|
|
||||||
msg_ok "Updated $APP LXC"
|
msg_ok "Updated $APP LXC"
|
||||||
else
|
else
|
||||||
msg_ok "No update required. ${APP} is already at ${RELEASE}"
|
msg_ok "No update required. ${APP} is already at ${RELEASE}"
|
||||||
|
|||||||
+10
-8
@@ -1,11 +1,11 @@
|
|||||||
#!/usr/bin/env bash
|
# #!/usr/bin/env bash
|
||||||
# source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)
|
# source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)
|
||||||
# # Copyright (c) 2021-2024 tteck
|
# # Copyright (c) 2021-2024 tteck
|
||||||
# # Author: tteck (tteckster)
|
# # Author: tteck (tteckster)
|
||||||
# # License: MIT
|
# # License: MIT
|
||||||
# # https://github.com/tteck/Proxmox/raw/main/LICENSE
|
# # https://github.com/tteck/Proxmox/raw/main/LICENSE
|
||||||
|
|
||||||
echo "Unsupported."
|
echo "Unsupported. View notes on GitHub."
|
||||||
|
|
||||||
# function header_info {
|
# function header_info {
|
||||||
# clear
|
# clear
|
||||||
@@ -57,21 +57,23 @@ echo "Unsupported."
|
|||||||
# function update_script() {
|
# function update_script() {
|
||||||
# header_info
|
# header_info
|
||||||
# if [[ ! -d /opt/trilium ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
# if [[ ! -d /opt/trilium ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
||||||
# RELEASE=$(curl -s https://api.github.com/repos/TriliumNext/Notes/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
|
# RELEASE=$(curl -s https://api.github.com/repos/zadam/trilium/releases/latest |
|
||||||
|
# grep "tag_name" |
|
||||||
|
# awk '{print substr($2, 3, length($2)-4) }')
|
||||||
|
|
||||||
# msg_info "Stopping ${APP}"
|
# msg_info "Stopping ${APP}"
|
||||||
# systemctl stop trilium.service
|
# systemctl stop trilium.service
|
||||||
# sleep 1
|
# sleep 1
|
||||||
# msg_ok "Stopped ${APP}"
|
# msg_ok "Stopped ${APP}"
|
||||||
|
|
||||||
# msg_info "Updating to ${RELEASE}"
|
# msg_info "Updating to v${RELEASE}"
|
||||||
# wget -q https://github.com/TriliumNext/Notes/releases/download/${RELEASE}/TriliumNextNotes-${RELEASE}-server-linux-x64.tar.xz
|
# wget -q https://github.com/zadam/trilium/releases/download/v$RELEASE/trilium-linux-x64-server-$RELEASE.tar.xz
|
||||||
# tar -xf TriliumNextNotes-${RELEASE}-server-linux-x64.tar.xz
|
# tar -xvf trilium-linux-x64-server-$RELEASE.tar.xz &>/dev/null
|
||||||
# cp -r trilium-linux-x64-server/* /opt/trilium/
|
# cp -r trilium-linux-x64-server/* /opt/trilium/
|
||||||
# msg_ok "Updated to ${RELEASE}"
|
# msg_ok "Updated to v${RELEASE}"
|
||||||
|
|
||||||
# msg_info "Cleaning up"
|
# msg_info "Cleaning up"
|
||||||
# rm -rf TriliumNextNotes-${RELEASE}-server-linux-x64.tar.xz trilium-linux-x64-server
|
# rm -rf trilium-linux-x64-server-$RELEASE.tar.xz trilium-linux-x64-server
|
||||||
# msg_ok "Cleaned"
|
# msg_ok "Cleaned"
|
||||||
|
|
||||||
# msg_info "Starting ${APP}"
|
# msg_info "Starting ${APP}"
|
||||||
|
|||||||
@@ -55,7 +55,6 @@ function default_settings() {
|
|||||||
function update_script() {
|
function update_script() {
|
||||||
header_info
|
header_info
|
||||||
if [[ ! -d /opt/umami ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
if [[ ! -d /opt/umami ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
||||||
whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "SET RESOURCES" "Please set the resources in your ${APP} LXC to ${var_cpu}vCPU and ${var_ram}RAM for the build process before continuing" 10 75
|
|
||||||
if (( $(df /boot | awk 'NR==2{gsub("%","",$5); print $5}') > 80 )); then
|
if (( $(df /boot | awk 'NR==2{gsub("%","",$5); print $5}') > 80 )); then
|
||||||
read -r -p "Warning: Storage is dangerously low, continue anyway? <y/N> " prompt
|
read -r -p "Warning: Storage is dangerously low, continue anyway? <y/N> " prompt
|
||||||
[[ ${prompt,,} =~ ^(y|yes)$ ]] || exit
|
[[ ${prompt,,} =~ ^(y|yes)$ ]] || exit
|
||||||
|
|||||||
@@ -17,10 +17,6 @@ cat <<"EOF"
|
|||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
header_info
|
header_info
|
||||||
if ! grep -q -m1 'avx[^ ]*' /proc/cpuinfo; then
|
|
||||||
echo "AVX instruction set is not supported on this CPU."
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
echo -e "Loading..."
|
echo -e "Loading..."
|
||||||
APP="Unifi"
|
APP="Unifi"
|
||||||
var_disk="8"
|
var_disk="8"
|
||||||
|
|||||||
+1
-5
@@ -57,7 +57,6 @@ function update_script() {
|
|||||||
msg_error "No ${APP} Installation Found!"
|
msg_error "No ${APP} Installation Found!"
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
VAULT=$(curl -s https://api.github.com/repos/dani-garcia/vaultwarden/releases/latest |
|
VAULT=$(curl -s https://api.github.com/repos/dani-garcia/vaultwarden/releases/latest |
|
||||||
grep "tag_name" |
|
grep "tag_name" |
|
||||||
awk '{print substr($2, 2, length($2)-3) }')
|
awk '{print substr($2, 2, length($2)-3) }')
|
||||||
@@ -73,7 +72,7 @@ function update_script() {
|
|||||||
|
|
||||||
header_info
|
header_info
|
||||||
if [ "$UPD" == "1" ]; then
|
if [ "$UPD" == "1" ]; then
|
||||||
whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "SET RESOURCES" "Please set the resources in your ${APP} LXC to ${var_cpu}vCPU and ${var_ram}RAM for the build process before continuing" 10 75
|
echo -e "\n ⚠️ Ensure you set 4vCPU & 4096MiB RAM minimum!!! \n"
|
||||||
msg_info "Stopping Vaultwarden"
|
msg_info "Stopping Vaultwarden"
|
||||||
systemctl stop vaultwarden.service
|
systemctl stop vaultwarden.service
|
||||||
msg_ok "Stopped Vaultwarden"
|
msg_ok "Stopped Vaultwarden"
|
||||||
@@ -129,9 +128,6 @@ function update_script() {
|
|||||||
if ! command -v argon2 >/dev/null 2>&1; then apt-get install -y argon2 &>/dev/null; fi
|
if ! command -v argon2 >/dev/null 2>&1; then apt-get install -y argon2 &>/dev/null; fi
|
||||||
TOKEN=$(echo -n ${NEWTOKEN} | argon2 "$(openssl rand -base64 32)" -t 2 -m 16 -p 4 -l 64 -e)
|
TOKEN=$(echo -n ${NEWTOKEN} | argon2 "$(openssl rand -base64 32)" -t 2 -m 16 -p 4 -l 64 -e)
|
||||||
sed -i "s|ADMIN_TOKEN=.*|ADMIN_TOKEN='${TOKEN}'|" /opt/vaultwarden/.env
|
sed -i "s|ADMIN_TOKEN=.*|ADMIN_TOKEN='${TOKEN}'|" /opt/vaultwarden/.env
|
||||||
if [[ -f /opt/vaultwarden/data/config.json ]]; then
|
|
||||||
sed -i "s|\"admin_token\":.*|\"admin_token\": \"${TOKEN}\"|" /opt/vaultwarden/data/config.json
|
|
||||||
fi
|
|
||||||
systemctl restart vaultwarden
|
systemctl restart vaultwarden
|
||||||
fi
|
fi
|
||||||
exit
|
exit
|
||||||
|
|||||||
@@ -1,99 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2024 tteck
|
|
||||||
# Author: tteck
|
|
||||||
# Co-Author: MickLesk (Canbiz)
|
|
||||||
# License: MIT
|
|
||||||
# https://github.com/tteck/Proxmox/raw/main/LICENSE
|
|
||||||
|
|
||||||
function header_info {
|
|
||||||
clear
|
|
||||||
cat <<"EOF"
|
|
||||||
_ __ ____
|
|
||||||
| | / /___ _/ / /___ _____
|
|
||||||
| | /| / / __ `/ / / __ \/ ___/
|
|
||||||
| |/ |/ / /_/ / / / /_/ (__ )
|
|
||||||
|__/|__/\__,_/_/_/\____/____/
|
|
||||||
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
header_info
|
|
||||||
echo -e "Loading..."
|
|
||||||
APP="Wallos"
|
|
||||||
var_disk="5"
|
|
||||||
var_cpu="1"
|
|
||||||
var_ram="1024"
|
|
||||||
var_os="debian"
|
|
||||||
var_version="12"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function default_settings() {
|
|
||||||
CT_TYPE="1"
|
|
||||||
PW=""
|
|
||||||
CT_ID=$NEXTID
|
|
||||||
HN=$NSAPP
|
|
||||||
DISK_SIZE="$var_disk"
|
|
||||||
CORE_COUNT="$var_cpu"
|
|
||||||
RAM_SIZE="$var_ram"
|
|
||||||
BRG="vmbr0"
|
|
||||||
NET="dhcp"
|
|
||||||
GATE=""
|
|
||||||
APT_CACHER=""
|
|
||||||
APT_CACHER_IP=""
|
|
||||||
DISABLEIP6="no"
|
|
||||||
MTU=""
|
|
||||||
SD=""
|
|
||||||
NS=""
|
|
||||||
MAC=""
|
|
||||||
VLAN=""
|
|
||||||
SSH="no"
|
|
||||||
VERB="no"
|
|
||||||
echo_default
|
|
||||||
}
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
if [[ ! -d /opt/wallos ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
|
||||||
if (( $(df /boot | awk 'NR==2{gsub("%","",$5); print $5}') > 80 )); then
|
|
||||||
read -r -p "Warning: Storage is dangerously low, continue anyway? <y/N> " prompt
|
|
||||||
[[ ${prompt,,} =~ ^(y|yes)$ ]] || exit
|
|
||||||
fi
|
|
||||||
RELEASE=$(curl -s https://api.github.com/repos/ellite/Wallos/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
|
|
||||||
if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then
|
|
||||||
msg_info "Updating ${APP} to ${RELEASE}"
|
|
||||||
cd /opt
|
|
||||||
wget -q "https://github.com/ellite/Wallos/archive/refs/tags/v${RELEASE}.zip"
|
|
||||||
mv /opt/wallos/db/wallos.db /opt/wallos.db
|
|
||||||
unzip -q v${RELEASE}.zip
|
|
||||||
mv Wallos-${RELEASE} /opt/wallos
|
|
||||||
rm -rf /opt/wallos/db/wallos.empty.db
|
|
||||||
mv /opt/wallos.db /opt/wallos/db/wallos.db
|
|
||||||
chown -R www-data:www-data /opt/wallos
|
|
||||||
chmod -R 755 /opt/wallos
|
|
||||||
curl http://localhost/endpoints/db/migrate.php &>/dev/null
|
|
||||||
echo "${RELEASE}" >/opt/${APP}_version.txt
|
|
||||||
msg_ok "Updated ${APP}"
|
|
||||||
|
|
||||||
msg_info "Reload Apache2"
|
|
||||||
systemctl reload apache2
|
|
||||||
msg_ok "Apache2 Reloaded"
|
|
||||||
|
|
||||||
msg_info "Cleaning Up"
|
|
||||||
rm -R /opt/v${RELEASE}.zip
|
|
||||||
msg_ok "Cleaned"
|
|
||||||
msg_ok "Updated Successfully"
|
|
||||||
else
|
|
||||||
msg_ok "No update required. ${APP} is already at ${RELEASE}"
|
|
||||||
fi
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed Successfully!\n"
|
|
||||||
echo -e "${APP} should be reachable by going to the following URL.
|
|
||||||
${BL}http://${IP} ${CL} \n"
|
|
||||||
+25
-13
@@ -23,8 +23,8 @@ header_info
|
|||||||
echo -e "Loading..."
|
echo -e "Loading..."
|
||||||
APP="Wastebin"
|
APP="Wastebin"
|
||||||
var_disk="4"
|
var_disk="4"
|
||||||
var_cpu="1"
|
var_cpu="4"
|
||||||
var_ram="1024"
|
var_ram="2048"
|
||||||
var_os="debian"
|
var_os="debian"
|
||||||
var_version="12"
|
var_version="12"
|
||||||
variables
|
variables
|
||||||
@@ -58,18 +58,27 @@ function default_settings() {
|
|||||||
function update_script() {
|
function update_script() {
|
||||||
header_info
|
header_info
|
||||||
if [[ ! -d /opt/wastebin ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
if [[ ! -d /opt/wastebin ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
||||||
RELEASE=$(curl -s https://api.github.com/repos/matze/wastebin/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
|
if (( $(df /boot | awk 'NR==2{gsub("%","",$5); print $5}') > 80 )); then
|
||||||
if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then
|
read -r -p "Warning: Storage is dangerously low, continue anyway? <y/N> " prompt
|
||||||
|
[[ ${prompt,,} =~ ^(y|yes)$ ]] || exit
|
||||||
|
fi
|
||||||
msg_info "Stopping Wastebin"
|
msg_info "Stopping Wastebin"
|
||||||
systemctl stop wastebin
|
systemctl stop wastebin
|
||||||
msg_ok "Wastebin Stopped"
|
msg_ok "Wastebin Stopped"
|
||||||
|
|
||||||
msg_info "Updating Wastebin"
|
msg_info "Updating Wastebin"
|
||||||
wget -q https://github.com/matze/wastebin/releases/download/${RELEASE}/wastebin_${RELEASE}_x86_64-unknown-linux-musl.tar.zst
|
RELEASE=$(curl -s https://api.github.com/repos/matze/wastebin/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
|
||||||
tar -xf wastebin_${RELEASE}_x86_64-unknown-linux-musl.tar.zst
|
cd /opt
|
||||||
cp -f wastebin /opt/wastebin/
|
if [ -d wastebin_bak ]; then
|
||||||
chmod +x /opt/wastebin/wastebin
|
rm -rf wastebin_bak
|
||||||
echo "${RELEASE}" >/opt/${APP}_version.txt
|
fi
|
||||||
|
mv wastebin wastebin_bak
|
||||||
|
wget -q "https://github.com/matze/wastebin/archive/refs/tags/${RELEASE}.zip"
|
||||||
|
unzip -q ${RELEASE}.zip
|
||||||
|
mv wastebin-${RELEASE} /opt/wastebin
|
||||||
|
cd /opt/wastebin
|
||||||
|
cargo update -q
|
||||||
|
cargo build -q --release
|
||||||
msg_ok "Updated Wastebin"
|
msg_ok "Updated Wastebin"
|
||||||
|
|
||||||
msg_info "Starting Wastebin"
|
msg_info "Starting Wastebin"
|
||||||
@@ -77,12 +86,11 @@ if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_v
|
|||||||
msg_ok "Started Wastebin"
|
msg_ok "Started Wastebin"
|
||||||
|
|
||||||
msg_info "Cleaning Up"
|
msg_info "Cleaning Up"
|
||||||
rm -rf wastebin_${RELEASE}_x86_64-unknown-linux-musl.tar.zst
|
cd /opt
|
||||||
|
rm -R ${RELEASE}.zip
|
||||||
|
rm -R wastebin_bak
|
||||||
msg_ok "Cleaned"
|
msg_ok "Cleaned"
|
||||||
msg_ok "Updated Successfully"
|
msg_ok "Updated Successfully"
|
||||||
else
|
|
||||||
msg_ok "No update required. ${APP} is already at ${RELEASE}"
|
|
||||||
fi
|
|
||||||
exit
|
exit
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,6 +98,10 @@ start
|
|||||||
build_container
|
build_container
|
||||||
description
|
description
|
||||||
|
|
||||||
|
msg_info "Setting Container to Normal Resources"
|
||||||
|
pct set $CTID -cores 2
|
||||||
|
msg_ok "Set Container to Normal Resources"
|
||||||
|
|
||||||
msg_ok "Completed Successfully!\n"
|
msg_ok "Completed Successfully!\n"
|
||||||
echo -e "${APP} Setup should be reachable by going to the following URL.
|
echo -e "${APP} Setup should be reachable by going to the following URL.
|
||||||
${BL}http://${IP}:8088${CL} \n"
|
${BL}http://${IP}:8088${CL} \n"
|
||||||
|
|||||||
@@ -57,7 +57,6 @@ header_info
|
|||||||
if [[ ! -f /usr/local/bin/whoogle-search ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
if [[ ! -f /usr/local/bin/whoogle-search ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
||||||
msg_info "Updating ${APP} LXC"
|
msg_info "Updating ${APP} LXC"
|
||||||
pip3 install whoogle-search --upgrade &>/dev/null
|
pip3 install whoogle-search --upgrade &>/dev/null
|
||||||
systemctl restart whoogle.service
|
|
||||||
msg_ok "Updated Successfully"
|
msg_ok "Updated Successfully"
|
||||||
exit
|
exit
|
||||||
}
|
}
|
||||||
|
|||||||
+67
-11
@@ -19,11 +19,11 @@ EOF
|
|||||||
header_info
|
header_info
|
||||||
echo -e "Loading..."
|
echo -e "Loading..."
|
||||||
APP="Wireguard"
|
APP="Wireguard"
|
||||||
var_disk="4"
|
var_disk="2"
|
||||||
var_cpu="1"
|
var_cpu="1"
|
||||||
var_ram="512"
|
var_ram="512"
|
||||||
var_os="debian"
|
var_os="ubuntu"
|
||||||
var_version="12"
|
var_version="20.04"
|
||||||
variables
|
variables
|
||||||
color
|
color
|
||||||
catch_errors
|
catch_errors
|
||||||
@@ -53,13 +53,71 @@ function default_settings() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function update_script() {
|
function update_script() {
|
||||||
if [[ ! -d /etc/wireguard ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
if [[ ! -d /etc/pivpn/wireguard ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
||||||
apt-get update
|
UPD=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 2 \
|
||||||
apt-get -y upgrade
|
"1" "Update ${APP} LXC" ON \
|
||||||
sleep 2
|
"2" "Install WGDashboard" OFF \
|
||||||
cd /etc/wgdashboard/src
|
3>&1 1>&2 2>&3)
|
||||||
./wgd.sh update
|
header_info
|
||||||
|
if [ "$UPD" == "1" ]; then
|
||||||
|
msg_info "Updating ${APP} LXC"
|
||||||
|
apt-get update &>/dev/null
|
||||||
|
apt-get -y upgrade &>/dev/null
|
||||||
|
msg_ok "Updated ${APP} LXC"
|
||||||
exit
|
exit
|
||||||
|
fi
|
||||||
|
if [ "$UPD" == "2" ]; then
|
||||||
|
if [[ -f /etc/systemd/system/wg-dashboard.service ]]; then
|
||||||
|
cd /etc/wgdashboard/src
|
||||||
|
chmod u+x wgd.sh
|
||||||
|
./wgd.sh update
|
||||||
|
msg_ok "Updated Successfully"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
IP=$(hostname -I | awk '{print $1}')
|
||||||
|
msg_info "Installing Python3-pip"
|
||||||
|
apt-get install -y python3-pip &>/dev/null
|
||||||
|
rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
|
||||||
|
pip install flask &>/dev/null
|
||||||
|
pip install ifcfg &>/dev/null
|
||||||
|
pip install flask_qrcode &>/dev/null
|
||||||
|
pip install icmplib &>/dev/null
|
||||||
|
msg_ok "Installed Python3-pip"
|
||||||
|
|
||||||
|
msg_info "Installing WGDashboard"
|
||||||
|
WGDREL=$(curl -s https://api.github.com/repos/donaldzou/WGDashboard/releases/latest |
|
||||||
|
grep "tag_name" |
|
||||||
|
awk '{print substr($2, 2, length($2)-3) }')
|
||||||
|
|
||||||
|
git clone -b ${WGDREL} https://github.com/donaldzou/WGDashboard.git /etc/wgdashboard &>/dev/null
|
||||||
|
cd /etc/wgdashboard/src
|
||||||
|
chmod u+x wgd.sh
|
||||||
|
./wgd.sh install &>/dev/null
|
||||||
|
chmod -R 755 /etc/wireguard
|
||||||
|
msg_ok "Installed WGDashboard"
|
||||||
|
|
||||||
|
msg_info "Creating Service"
|
||||||
|
service_path="/etc/systemd/system/wg-dashboard.service"
|
||||||
|
echo "[Unit]
|
||||||
|
After=systemd-networkd.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
WorkingDirectory=/etc/wgdashboard/src
|
||||||
|
ExecStart=/usr/bin/python3 /etc/wgdashboard/src/dashboard.py
|
||||||
|
Restart=always
|
||||||
|
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target" >$service_path
|
||||||
|
chmod 664 /etc/systemd/system/wg-dashboard.service
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl enable wg-dashboard.service &>/dev/null
|
||||||
|
systemctl start wg-dashboard.service &>/dev/null
|
||||||
|
msg_ok "Created Service"
|
||||||
|
echo -e "WGDashboard should be reachable by going to the following URL.
|
||||||
|
${BL}http://${IP}:10086${CL} admin|admin \n"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
start
|
start
|
||||||
@@ -67,5 +125,3 @@ build_container
|
|||||||
description
|
description
|
||||||
|
|
||||||
msg_ok "Completed Successfully!\n"
|
msg_ok "Completed Successfully!\n"
|
||||||
echo -e "WGDashboard should be reachable by going to the following URL.
|
|
||||||
${BL}http://${IP}:10086${CL} admin|admin \n"
|
|
||||||
|
|||||||
@@ -58,7 +58,6 @@ if [[ ! -f /etc/zabbix/zabbix_server.conf ]]; then msg_error "No ${APP} Installa
|
|||||||
msg_info "Updating $APP LXC"
|
msg_info "Updating $APP LXC"
|
||||||
apt-get update &>/dev/null
|
apt-get update &>/dev/null
|
||||||
apt-get -y upgrade &>/dev/null
|
apt-get -y upgrade &>/dev/null
|
||||||
systemctl restart zabbix-server
|
|
||||||
msg_ok "Updated $APP LXC"
|
msg_ok "Updated $APP LXC"
|
||||||
exit
|
exit
|
||||||
}
|
}
|
||||||
|
|||||||
-101
@@ -1,101 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -s https://raw.githubusercontent.com/asylumexp/Proxmox/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2024 tteck
|
|
||||||
# Author: tteck
|
|
||||||
# Co-Author: MickLesk (Canbiz)
|
|
||||||
# License: MIT
|
|
||||||
# https://github.com/tteck/Proxmox/raw/main/LICENSE
|
|
||||||
|
|
||||||
function header_info {
|
|
||||||
clear
|
|
||||||
cat <<"EOF"
|
|
||||||
_____ _ ___
|
|
||||||
/__ / (_)___ / (_)___ ___
|
|
||||||
/ / / / __ \/ / / __ \/ _ \
|
|
||||||
/ /__/ / /_/ / / / / / / __/
|
|
||||||
/____/_/ .___/_/_/_/ /_/\___/
|
|
||||||
/_/
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
header_info
|
|
||||||
echo -e "Loading..."
|
|
||||||
APP="Zipline"
|
|
||||||
var_disk="5"
|
|
||||||
var_cpu="2"
|
|
||||||
var_ram="2048"
|
|
||||||
var_os="debian"
|
|
||||||
var_version="12"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function default_settings() {
|
|
||||||
CT_TYPE="1"
|
|
||||||
PW=""
|
|
||||||
CT_ID=$NEXTID
|
|
||||||
HN=$NSAPP
|
|
||||||
DISK_SIZE="$var_disk"
|
|
||||||
CORE_COUNT="$var_cpu"
|
|
||||||
RAM_SIZE="$var_ram"
|
|
||||||
BRG="vmbr0"
|
|
||||||
NET="dhcp"
|
|
||||||
GATE=""
|
|
||||||
APT_CACHER=""
|
|
||||||
APT_CACHER_IP=""
|
|
||||||
DISABLEIP6="no"
|
|
||||||
MTU=""
|
|
||||||
SD=""
|
|
||||||
NS=""
|
|
||||||
MAC=""
|
|
||||||
VLAN=""
|
|
||||||
SSH="no"
|
|
||||||
VERB="no"
|
|
||||||
echo_default
|
|
||||||
}
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
if [[ ! -d /opt/zipline ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
|
||||||
if (( $(df /boot | awk 'NR==2{gsub("%","",$5); print $5}') > 80 )); then
|
|
||||||
read -r -p "Warning: Storage is dangerously low, continue anyway? <y/N> " prompt
|
|
||||||
[[ ${prompt,,} =~ ^(y|yes)$ ]] || exit
|
|
||||||
fi
|
|
||||||
RELEASE=$(curl -s https://api.github.com/repos/diced/zipline/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
|
|
||||||
if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then
|
|
||||||
msg_info "Stopping ${APP}"
|
|
||||||
systemctl stop zipline
|
|
||||||
msg_ok "${APP} Stopped"
|
|
||||||
|
|
||||||
msg_info "Updating ${APP} to ${RELEASE}"
|
|
||||||
cp /opt/zipline/.env /opt/
|
|
||||||
rm -R /opt/zipline
|
|
||||||
wget -q "https://github.com/diced/zipline/archive/refs/tags/v${RELEASE}.zip"
|
|
||||||
unzip -q v${RELEASE}.zip
|
|
||||||
mv zipline-${RELEASE} /opt/zipline
|
|
||||||
cd /opt/zipline
|
|
||||||
mv /opt/.env /opt/zipline/.env
|
|
||||||
yarn install &>/dev/null
|
|
||||||
yarn build &>/dev/null
|
|
||||||
echo "${RELEASE}" >/opt/${APP}_version.txt
|
|
||||||
msg_ok "Updated ${APP}"
|
|
||||||
|
|
||||||
msg_info "Starting ${APP}"
|
|
||||||
systemctl start zipline
|
|
||||||
msg_ok "Started ${APP}"
|
|
||||||
|
|
||||||
msg_info "Cleaning Up"
|
|
||||||
rm -rf v${RELEASE}.zip
|
|
||||||
msg_ok "Cleaned"
|
|
||||||
msg_ok "Updated Successfully"
|
|
||||||
else
|
|
||||||
msg_ok "No update required. ${APP} is already at ${RELEASE}"
|
|
||||||
fi
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed Successfully!\n"
|
|
||||||
echo -e "${APP} Setup should be reachable by going to the following URL.
|
|
||||||
${BL}http://${IP}:3000${CL} \n"
|
|
||||||
+14
-13
@@ -20,7 +20,7 @@ header_info
|
|||||||
echo -e "Loading..."
|
echo -e "Loading..."
|
||||||
APP="Zoraxy"
|
APP="Zoraxy"
|
||||||
var_disk="6"
|
var_disk="6"
|
||||||
var_cpu="2"
|
var_cpu="4"
|
||||||
var_ram="2048"
|
var_ram="2048"
|
||||||
var_os="debian"
|
var_os="debian"
|
||||||
var_version="12"
|
var_version="12"
|
||||||
@@ -54,21 +54,19 @@ function default_settings() {
|
|||||||
|
|
||||||
function update_script() {
|
function update_script() {
|
||||||
header_info
|
header_info
|
||||||
if [[ ! -d /opt/zoraxy/ ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
if [[ ! -d /opt/zoraxy/src ]]; then msg_error "No ${APP} Installation Found!"; exit; fi
|
||||||
RELEASE=$(curl -s https://api.github.com/repos/tobychui/zoraxy/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
|
msg_info "Updating $APP"
|
||||||
if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then
|
|
||||||
msg_info "Updating $APP to ${RELEASE}"
|
|
||||||
systemctl stop zoraxy
|
systemctl stop zoraxy
|
||||||
wget -q "https://github.com/tobychui/zoraxy/releases/download/${RELEASE}/zoraxy_linux_amd64"
|
cd /opt/zoraxy/src
|
||||||
rm /opt/zoraxy/zoraxy
|
systemctl stop zoraxy
|
||||||
mv zoraxy_linux_amd64 /opt/zoraxy/zoraxy
|
if git pull | grep -q 'Already up to date.'; then
|
||||||
chmod +x /opt/zoraxy/zoraxy
|
msg_ok "Already up to date. No update required."
|
||||||
systemctl start zoraxy
|
|
||||||
echo "${RELEASE}" >/opt/${APP}_version.txt
|
|
||||||
msg_ok "Updated $APP"
|
|
||||||
else
|
else
|
||||||
msg_ok "No update required. ${APP} is already at ${RELEASE}"
|
go mod tidy
|
||||||
|
go build
|
||||||
|
msg_ok "Updated $APP"
|
||||||
fi
|
fi
|
||||||
|
systemctl start zoraxy
|
||||||
exit
|
exit
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,6 +74,9 @@ start
|
|||||||
build_container
|
build_container
|
||||||
description
|
description
|
||||||
|
|
||||||
|
msg_info "Setting Container to Normal Resources"
|
||||||
|
pct set $CTID -cores 2
|
||||||
|
msg_ok "Set Container to Normal Resources"
|
||||||
msg_ok "Completed Successfully!\n"
|
msg_ok "Completed Successfully!\n"
|
||||||
echo -e "${APP} should be reachable by going to the following URL.
|
echo -e "${APP} should be reachable by going to the following URL.
|
||||||
${BL}http://${IP}:8000${CL} \n"
|
${BL}http://${IP}:8000${CL} \n"
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": ["next/core-web-vitals"],
|
|
||||||
"parser": "@typescript-eslint/parser",
|
|
||||||
"plugins": ["@typescript-eslint"]
|
|
||||||
}
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
|
||||||
|
|
||||||
# dependencies
|
|
||||||
/node_modules
|
|
||||||
/.pnp
|
|
||||||
.pnp.js
|
|
||||||
.yarn/install-state.gz
|
|
||||||
|
|
||||||
# wrangler
|
|
||||||
.worker-next
|
|
||||||
.wrangler
|
|
||||||
|
|
||||||
# testing
|
|
||||||
/coverage
|
|
||||||
|
|
||||||
# next.js
|
|
||||||
/.next/
|
|
||||||
out
|
|
||||||
# production
|
|
||||||
/build
|
|
||||||
|
|
||||||
# misc
|
|
||||||
.DS_Store
|
|
||||||
*.pem
|
|
||||||
|
|
||||||
# debug
|
|
||||||
npm-debug.log*
|
|
||||||
yarn-debug.log*
|
|
||||||
yarn-error.log*
|
|
||||||
|
|
||||||
# # local env files
|
|
||||||
# .env*.local
|
|
||||||
# .env
|
|
||||||
# vercel
|
|
||||||
.vercel
|
|
||||||
|
|
||||||
# typescript
|
|
||||||
*.tsbuildinfo
|
|
||||||
next-env.d.ts
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
dist
|
|
||||||
node_modules
|
|
||||||
.next
|
|
||||||
build
|
|
||||||
.contentlayer
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"plugins": ["prettier-plugin-tailwindcss", "prettier-plugin-organize-imports"]
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2024 Bram Suurd
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "https://ui.shadcn.com/schema.json",
|
|
||||||
"style": "default",
|
|
||||||
"rsc": true,
|
|
||||||
"tsx": true,
|
|
||||||
"tailwind": {
|
|
||||||
"config": "tailwind.config.ts",
|
|
||||||
"css": "@/styles/globals.css",
|
|
||||||
"baseColor": "slate",
|
|
||||||
"cssVariables": true,
|
|
||||||
"prefix": ""
|
|
||||||
},
|
|
||||||
"aliases": {
|
|
||||||
"components": "@/components",
|
|
||||||
"utils": "@/lib/utils"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
/** @type {import('next').NextConfig} */
|
|
||||||
const nextConfig = {
|
|
||||||
webpack: (config) => {
|
|
||||||
config.resolve.alias.canvas = false;
|
|
||||||
|
|
||||||
return config;
|
|
||||||
},
|
|
||||||
images: {
|
|
||||||
remotePatterns: [
|
|
||||||
{
|
|
||||||
protocol: "https",
|
|
||||||
hostname: "**",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
env: {
|
|
||||||
BASE_PATH: "ProxmoxVE",
|
|
||||||
},
|
|
||||||
|
|
||||||
output: "export",
|
|
||||||
basePath: `/ProxmoxVE`,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default nextConfig;
|
|
||||||
Generated
-10090
File diff suppressed because it is too large
Load Diff
@@ -1,88 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "proxmox-helper-scripts-website",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"license": "MIT",
|
|
||||||
"private": true,
|
|
||||||
"author": {
|
|
||||||
"name": "Bram Suurd",
|
|
||||||
"url": "https://github.com/community-scripts"
|
|
||||||
},
|
|
||||||
"type": "module",
|
|
||||||
"scripts": {
|
|
||||||
"dev": "next dev --turbopack",
|
|
||||||
"build": "next build",
|
|
||||||
"start": "next start",
|
|
||||||
"lint": "next lint",
|
|
||||||
"test": "vitest",
|
|
||||||
"deploy": "next build && touch out/.nojekyll && git add out/ && git commit -m \"Deploy\" && git subtree push --prefix out origin gh-pages",
|
|
||||||
"format:write": "prettier --write \"**/*.{ts,tsx,mdx}\" --cache",
|
|
||||||
"format:check": "prettier --check \"**/*.{ts,tsx,mdx}\" --cache",
|
|
||||||
"typecheck": "tsc --noEmit"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@radix-ui/react-accordion": "^1.1.2",
|
|
||||||
"@radix-ui/react-dialog": "^1.0.5",
|
|
||||||
"@radix-ui/react-dropdown-menu": "^2.0.6",
|
|
||||||
"@radix-ui/react-icons": "^1.3.1",
|
|
||||||
"@radix-ui/react-label": "^2.1.0",
|
|
||||||
"@radix-ui/react-navigation-menu": "^1.1.4",
|
|
||||||
"@radix-ui/react-popover": "^1.1.2",
|
|
||||||
"@radix-ui/react-select": "^2.1.2",
|
|
||||||
"@radix-ui/react-separator": "^1.1.0",
|
|
||||||
"@radix-ui/react-slot": "^1.1.0",
|
|
||||||
"@radix-ui/react-switch": "^1.1.1",
|
|
||||||
"@radix-ui/react-tabs": "^1.1.0",
|
|
||||||
"@radix-ui/react-tooltip": "^1.1.2",
|
|
||||||
"@vercel/analytics": "^1.2.2",
|
|
||||||
"class-variance-authority": "^0.7.0",
|
|
||||||
"clsx": "^2.1.1",
|
|
||||||
"cmdk": "^1.0.0",
|
|
||||||
"date-fns": "^4.1.0",
|
|
||||||
"framer-motion": "^11.11.11",
|
|
||||||
"fuse.js": "^7.0.0",
|
|
||||||
"lucide-react": "^0.453.0",
|
|
||||||
"mini-svg-data-uri": "^1.4.4",
|
|
||||||
"next": "15.1.3",
|
|
||||||
"next-themes": "^0.3.0",
|
|
||||||
"nuqs": "^2.1.1",
|
|
||||||
"pocketbase": "^0.21.4",
|
|
||||||
"prettier-plugin-organize-imports": "^4.1.0",
|
|
||||||
"react": "19.0.0-rc-02c0e824-20241028",
|
|
||||||
"react-code-blocks": "^0.1.6",
|
|
||||||
"react-day-picker": "8.10.1",
|
|
||||||
"react-dom": "19.0.0-rc-02c0e824-20241028",
|
|
||||||
"react-icons": "^5.1.0",
|
|
||||||
"react-simple-typewriter": "^5.0.1",
|
|
||||||
"sharp": "^0.33.5",
|
|
||||||
"simple-icons": "^13.5.0",
|
|
||||||
"sonner": "^1.5.0",
|
|
||||||
"tailwind-merge": "^2.3.0",
|
|
||||||
"zod": "^3.23.8"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@testing-library/dom": "^10.4.0",
|
|
||||||
"@testing-library/react": "^16.0.1",
|
|
||||||
"@types/node": "^22",
|
|
||||||
"@types/react-dom": "npm:types-react-dom@19.0.0-rc.1",
|
|
||||||
"@types/react": "npm:types-react@19.0.0-rc.1",
|
|
||||||
"@typescript-eslint/eslint-plugin": "^8.8.1",
|
|
||||||
"@typescript-eslint/parser": "^8.8.1",
|
|
||||||
"@vitejs/plugin-react": "^4.3.4",
|
|
||||||
"eslint-config-next": "15.0.2",
|
|
||||||
"eslint": "^9.13.0",
|
|
||||||
"jsdom": "^25.0.1",
|
|
||||||
"postcss": "^8",
|
|
||||||
"prettier-plugin-tailwindcss": "^0.6.5",
|
|
||||||
"prettier": "^3.2.5",
|
|
||||||
"tailwindcss-animate": "^1.0.7",
|
|
||||||
"tailwindcss-animated": "^1.1.2",
|
|
||||||
"tailwindcss": "^3.4.9",
|
|
||||||
"typescript": "^5",
|
|
||||||
"vite-tsconfig-paths": "^5.1.3",
|
|
||||||
"vitest": "^2.1.6"
|
|
||||||
},
|
|
||||||
"overrides": {
|
|
||||||
"@types/react": "npm:types-react@19.0.0-rc.1",
|
|
||||||
"@types/react-dom": "npm:types-react-dom@19.0.0-rc.1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
/** @type {import('postcss-load-config').Config} */
|
|
||||||
const config = {
|
|
||||||
plugins: {
|
|
||||||
tailwindcss: {},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export default config;
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 76 KiB |
@@ -1 +0,0 @@
|
|||||||
../../json
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 63 KiB |
@@ -1,11 +0,0 @@
|
|||||||
import { screen } from "@testing-library/dom";
|
|
||||||
import { render } from "@testing-library/react";
|
|
||||||
import { describe, expect, it } from "vitest";
|
|
||||||
import Page from "@/app/page";
|
|
||||||
|
|
||||||
describe("Page", () => {
|
|
||||||
it("should show button to view scripts", () => {
|
|
||||||
render(<Page />);
|
|
||||||
expect(screen.getByRole("button", { name: "View Scripts" })).toBeDefined();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
import { describe, it, assert, beforeAll } from "vitest";
|
|
||||||
import { promises as fs } from "fs";
|
|
||||||
import path from "path";
|
|
||||||
import { ScriptSchema, type Script } from "@/app/json-editor/_schemas/schemas";
|
|
||||||
import { Metadata } from "@/lib/types";
|
|
||||||
|
|
||||||
const jsonDir = "public/json";
|
|
||||||
const metadataFileName = "metadata.json";
|
|
||||||
const encoding = "utf-8";
|
|
||||||
|
|
||||||
const fileNames = (await fs.readdir(jsonDir))
|
|
||||||
.filter((fileName) => fileName !== metadataFileName)
|
|
||||||
|
|
||||||
describe.each(fileNames)("%s", async (fileName) => {
|
|
||||||
let script: Script;
|
|
||||||
|
|
||||||
beforeAll(async () => {
|
|
||||||
const filePath = path.resolve(jsonDir, fileName);
|
|
||||||
const fileContent = await fs.readFile(filePath, encoding)
|
|
||||||
script = JSON.parse(fileContent);
|
|
||||||
})
|
|
||||||
|
|
||||||
it("should have valid json according to script schema", () => {
|
|
||||||
ScriptSchema.parse(script);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should have a corresponding script file", () => {
|
|
||||||
script.install_methods.forEach((method) => {
|
|
||||||
const scriptPath = path.resolve("..", method.script)
|
|
||||||
assert(fs.stat(scriptPath), `Script file not found: ${scriptPath}`)
|
|
||||||
})
|
|
||||||
});
|
|
||||||
})
|
|
||||||
|
|
||||||
describe(`${metadataFileName}`, async () => {
|
|
||||||
let metadata: Metadata;
|
|
||||||
|
|
||||||
beforeAll(async () => {
|
|
||||||
const filePath = path.resolve(jsonDir, metadataFileName);
|
|
||||||
const fileContent = await fs.readFile(filePath, encoding)
|
|
||||||
metadata = JSON.parse(fileContent);
|
|
||||||
})
|
|
||||||
|
|
||||||
it("should have valid json according to metadata schema", () => {
|
|
||||||
// TODO: create zod schema for metadata. Move zod schemas to /lib/types.ts
|
|
||||||
assert(metadata.categories.length > 0);
|
|
||||||
metadata.categories.forEach((category) => {
|
|
||||||
assert.isString(category.name)
|
|
||||||
assert.isNumber(category.id)
|
|
||||||
assert.isNumber(category.sort_order)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
})
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
import { vi } from "vitest";
|
|
||||||
|
|
||||||
// Mock canvas getContext
|
|
||||||
HTMLCanvasElement.prototype.getContext = vi.fn();
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
import { Metadata, Script } from "@/lib/types";
|
|
||||||
import { promises as fs } from "fs";
|
|
||||||
import { NextResponse } from "next/server";
|
|
||||||
import path from "path";
|
|
||||||
|
|
||||||
export const dynamic = "force-static";
|
|
||||||
|
|
||||||
const jsonDir = "public/json";
|
|
||||||
const metadataFileName = "metadata.json";
|
|
||||||
const encoding = "utf-8";
|
|
||||||
|
|
||||||
const getMetadata = async () => {
|
|
||||||
const filePath = path.resolve(jsonDir, metadataFileName);
|
|
||||||
const fileContent = await fs.readFile(filePath, encoding);
|
|
||||||
const metadata: Metadata = JSON.parse(fileContent);
|
|
||||||
return metadata;
|
|
||||||
};
|
|
||||||
|
|
||||||
const getScripts = async () => {
|
|
||||||
const filePaths = (await fs.readdir(jsonDir))
|
|
||||||
.filter((fileName) => fileName !== metadataFileName)
|
|
||||||
.map((fileName) => path.resolve(jsonDir, fileName));
|
|
||||||
|
|
||||||
const scripts = await Promise.all(
|
|
||||||
filePaths.map(async (filePath) => {
|
|
||||||
const fileContent = await fs.readFile(filePath, encoding);
|
|
||||||
const script: Script = JSON.parse(fileContent);
|
|
||||||
return script;
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
return scripts;
|
|
||||||
};
|
|
||||||
|
|
||||||
export async function GET() {
|
|
||||||
try {
|
|
||||||
const metadata = await getMetadata();
|
|
||||||
const scripts = await getScripts();
|
|
||||||
|
|
||||||
const categories = metadata.categories
|
|
||||||
.map((category) => {
|
|
||||||
category.scripts = scripts.filter((script) =>
|
|
||||||
script.categories.includes(category.id),
|
|
||||||
);
|
|
||||||
return category;
|
|
||||||
})
|
|
||||||
.sort((a, b) => a.sort_order - b.sort_order);
|
|
||||||
|
|
||||||
return NextResponse.json(categories);
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error as Error);
|
|
||||||
return NextResponse.json(
|
|
||||||
{ error: "Failed to fetch categories" },
|
|
||||||
{ status: 500 },
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.8 KiB |
@@ -1,117 +0,0 @@
|
|||||||
import { Label } from "@/components/ui/label";
|
|
||||||
import {
|
|
||||||
Select,
|
|
||||||
SelectContent,
|
|
||||||
SelectItem,
|
|
||||||
SelectTrigger,
|
|
||||||
SelectValue,
|
|
||||||
} from "@/components/ui/select";
|
|
||||||
import { Category } from "@/lib/types";
|
|
||||||
import { cn } from "@/lib/utils";
|
|
||||||
import { z } from "zod";
|
|
||||||
import { type Script } from "../_schemas/schemas";
|
|
||||||
import { memo } from "react";
|
|
||||||
|
|
||||||
type CategoryProps = {
|
|
||||||
script: Script;
|
|
||||||
setScript: (script: Script) => void;
|
|
||||||
setIsValid: (isValid: boolean) => void;
|
|
||||||
setZodErrors: (zodErrors: z.ZodError | null) => void;
|
|
||||||
categories: Category[];
|
|
||||||
};
|
|
||||||
|
|
||||||
const CategoryTag = memo(({
|
|
||||||
category,
|
|
||||||
onRemove
|
|
||||||
}: {
|
|
||||||
category: Category;
|
|
||||||
onRemove: () => void;
|
|
||||||
}) => (
|
|
||||||
<span className="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800">
|
|
||||||
{category.name}
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className="ml-1 inline-flex text-blue-400 hover:text-blue-600"
|
|
||||||
onClick={onRemove}
|
|
||||||
>
|
|
||||||
<span className="sr-only">Remove</span>
|
|
||||||
<svg
|
|
||||||
className="h-3 w-3"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round"
|
|
||||||
strokeWidth={2}
|
|
||||||
d="M6 18L18 6M6 6l12 12"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
</span>
|
|
||||||
));
|
|
||||||
|
|
||||||
CategoryTag.displayName = 'CategoryTag';
|
|
||||||
|
|
||||||
function Categories({
|
|
||||||
script,
|
|
||||||
setScript,
|
|
||||||
categories,
|
|
||||||
}: Omit<CategoryProps, "setIsValid" | "setZodErrors">) {
|
|
||||||
const addCategory = (categoryId: number) => {
|
|
||||||
setScript({
|
|
||||||
...script,
|
|
||||||
categories: [...new Set([...script.categories, categoryId])],
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const removeCategory = (categoryId: number) => {
|
|
||||||
setScript({
|
|
||||||
...script,
|
|
||||||
categories: script.categories.filter((id: number) => id !== categoryId),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const categoryMap = new Map(categories.map(c => [c.id, c]));
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<Label>
|
|
||||||
Category <span className="text-red-500">*</span>
|
|
||||||
</Label>
|
|
||||||
<Select onValueChange={(value) => addCategory(Number(value))}>
|
|
||||||
<SelectTrigger>
|
|
||||||
<SelectValue placeholder="Select a category" />
|
|
||||||
</SelectTrigger>
|
|
||||||
<SelectContent>
|
|
||||||
{categories.map((category) => (
|
|
||||||
<SelectItem key={category.id} value={category.id.toString()}>
|
|
||||||
{category.name}
|
|
||||||
</SelectItem>
|
|
||||||
))}
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
<div
|
|
||||||
className={cn(
|
|
||||||
"flex flex-wrap gap-2",
|
|
||||||
script.categories.length !== 0 && "mt-2",
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{script.categories.map((categoryId) => {
|
|
||||||
const category = categoryMap.get(categoryId);
|
|
||||||
return category ? (
|
|
||||||
<CategoryTag
|
|
||||||
key={categoryId}
|
|
||||||
category={category}
|
|
||||||
onRemove={() => removeCategory(categoryId)}
|
|
||||||
/>
|
|
||||||
) : null;
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default memo(Categories);
|
|
||||||
@@ -1,240 +0,0 @@
|
|||||||
import { Button } from "@/components/ui/button";
|
|
||||||
import { Input } from "@/components/ui/input";
|
|
||||||
import {
|
|
||||||
Select,
|
|
||||||
SelectContent,
|
|
||||||
SelectItem,
|
|
||||||
SelectTrigger,
|
|
||||||
SelectValue,
|
|
||||||
} from "@/components/ui/select";
|
|
||||||
import { OperatingSystems } from "@/config/siteConfig";
|
|
||||||
import { PlusCircle, Trash2 } from "lucide-react";
|
|
||||||
import { memo, useCallback, useRef } from "react";
|
|
||||||
import { z } from "zod";
|
|
||||||
import { InstallMethodSchema, ScriptSchema, type Script } from "../_schemas/schemas";
|
|
||||||
|
|
||||||
type InstallMethodProps = {
|
|
||||||
script: Script;
|
|
||||||
setScript: (value: Script | ((prevState: Script) => Script)) => void;
|
|
||||||
setIsValid: (isValid: boolean) => void;
|
|
||||||
setZodErrors: (zodErrors: z.ZodError | null) => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
function InstallMethod({
|
|
||||||
script,
|
|
||||||
setScript,
|
|
||||||
setIsValid,
|
|
||||||
setZodErrors,
|
|
||||||
}: InstallMethodProps) {
|
|
||||||
const cpuRefs = useRef<(HTMLInputElement | null)[]>([]);
|
|
||||||
const ramRefs = useRef<(HTMLInputElement | null)[]>([]);
|
|
||||||
const hddRefs = useRef<(HTMLInputElement | null)[]>([]);
|
|
||||||
|
|
||||||
const addInstallMethod = useCallback(() => {
|
|
||||||
setScript((prev) => {
|
|
||||||
const method = InstallMethodSchema.parse({
|
|
||||||
type: "default",
|
|
||||||
script: `${prev.type}/${prev.slug}.sh`,
|
|
||||||
resources: {
|
|
||||||
cpu: null,
|
|
||||||
ram: null,
|
|
||||||
hdd: null,
|
|
||||||
os: null,
|
|
||||||
version: null,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
return {
|
|
||||||
...prev,
|
|
||||||
install_methods: [...prev.install_methods, method],
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}, [setScript]);
|
|
||||||
|
|
||||||
const updateInstallMethod = useCallback(
|
|
||||||
(
|
|
||||||
index: number,
|
|
||||||
key: keyof Script["install_methods"][number],
|
|
||||||
value: Script["install_methods"][number][keyof Script["install_methods"][number]],
|
|
||||||
) => {
|
|
||||||
setScript((prev) => {
|
|
||||||
const updatedMethods = prev.install_methods.map((method, i) => {
|
|
||||||
if (i === index) {
|
|
||||||
const updatedMethod = { ...method, [key]: value };
|
|
||||||
|
|
||||||
if (key === "type") {
|
|
||||||
updatedMethod.script =
|
|
||||||
value === "alpine"
|
|
||||||
? `/${prev.type}/alpine-${prev.slug}.sh`
|
|
||||||
: `/${prev.type}/${prev.slug}.sh`;
|
|
||||||
|
|
||||||
// Set OS to Alpine and reset version if type is alpine
|
|
||||||
if (value === "alpine") {
|
|
||||||
updatedMethod.resources.os = "Alpine";
|
|
||||||
updatedMethod.resources.version = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return updatedMethod;
|
|
||||||
}
|
|
||||||
return method;
|
|
||||||
});
|
|
||||||
|
|
||||||
const updated = {
|
|
||||||
...prev,
|
|
||||||
install_methods: updatedMethods,
|
|
||||||
};
|
|
||||||
|
|
||||||
const result = ScriptSchema.safeParse(updated);
|
|
||||||
setIsValid(result.success);
|
|
||||||
if (!result.success) {
|
|
||||||
setZodErrors(result.error);
|
|
||||||
} else {
|
|
||||||
setZodErrors(null);
|
|
||||||
}
|
|
||||||
return updated;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
[setScript, setIsValid, setZodErrors],
|
|
||||||
);
|
|
||||||
|
|
||||||
const removeInstallMethod = useCallback(
|
|
||||||
(index: number) => {
|
|
||||||
setScript((prev) => ({
|
|
||||||
...prev,
|
|
||||||
install_methods: prev.install_methods.filter((_, i) => i !== index),
|
|
||||||
}));
|
|
||||||
},
|
|
||||||
[setScript],
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<h3 className="text-xl font-semibold">Install Methods</h3>
|
|
||||||
{script.install_methods.map((method, index) => (
|
|
||||||
<div key={index} className="space-y-2 border p-4 rounded">
|
|
||||||
<Select
|
|
||||||
value={method.type}
|
|
||||||
onValueChange={(value) => updateInstallMethod(index, "type", value)}
|
|
||||||
>
|
|
||||||
<SelectTrigger>
|
|
||||||
<SelectValue placeholder="Type" />
|
|
||||||
</SelectTrigger>
|
|
||||||
<SelectContent>
|
|
||||||
<SelectItem value="default">Default</SelectItem>
|
|
||||||
<SelectItem value="alpine">Alpine</SelectItem>
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
<div className="flex gap-2">
|
|
||||||
<Input
|
|
||||||
ref={(el) => {
|
|
||||||
cpuRefs.current[index] = el;
|
|
||||||
}}
|
|
||||||
placeholder="CPU in Cores"
|
|
||||||
type="number"
|
|
||||||
value={method.resources.cpu || ""}
|
|
||||||
onChange={(e) =>
|
|
||||||
updateInstallMethod(index, "resources", {
|
|
||||||
...method.resources,
|
|
||||||
cpu: e.target.value ? Number(e.target.value) : null,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<Input
|
|
||||||
ref={(el) => {
|
|
||||||
ramRefs.current[index] = el;
|
|
||||||
}}
|
|
||||||
placeholder="RAM in MB"
|
|
||||||
type="number"
|
|
||||||
value={method.resources.ram || ""}
|
|
||||||
onChange={(e) =>
|
|
||||||
updateInstallMethod(index, "resources", {
|
|
||||||
...method.resources,
|
|
||||||
ram: e.target.value ? Number(e.target.value) : null,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<Input
|
|
||||||
ref={(el) => {
|
|
||||||
hddRefs.current[index] = el;
|
|
||||||
}}
|
|
||||||
placeholder="HDD in GB"
|
|
||||||
type="number"
|
|
||||||
value={method.resources.hdd || ""}
|
|
||||||
onChange={(e) =>
|
|
||||||
updateInstallMethod(index, "resources", {
|
|
||||||
...method.resources,
|
|
||||||
hdd: e.target.value ? Number(e.target.value) : null,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="flex gap-2">
|
|
||||||
<Select
|
|
||||||
value={method.resources.os || undefined}
|
|
||||||
onValueChange={(value) =>
|
|
||||||
updateInstallMethod(index, "resources", {
|
|
||||||
...method.resources,
|
|
||||||
os: value || null,
|
|
||||||
version: null, // Reset version when OS changes
|
|
||||||
})
|
|
||||||
}
|
|
||||||
disabled={method.type === "alpine"}
|
|
||||||
>
|
|
||||||
<SelectTrigger>
|
|
||||||
<SelectValue placeholder="OS" />
|
|
||||||
</SelectTrigger>
|
|
||||||
<SelectContent>
|
|
||||||
{OperatingSystems.map((os) => (
|
|
||||||
<SelectItem key={os.name} value={os.name}>
|
|
||||||
{os.name}
|
|
||||||
</SelectItem>
|
|
||||||
))}
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
<Select
|
|
||||||
value={method.resources.version || undefined}
|
|
||||||
onValueChange={(value) =>
|
|
||||||
updateInstallMethod(index, "resources", {
|
|
||||||
...method.resources,
|
|
||||||
version: value || null,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
disabled={method.type === "alpine"}
|
|
||||||
>
|
|
||||||
<SelectTrigger>
|
|
||||||
<SelectValue placeholder="Version" />
|
|
||||||
</SelectTrigger>
|
|
||||||
<SelectContent>
|
|
||||||
{OperatingSystems.find(
|
|
||||||
(os) => os.name === method.resources.os,
|
|
||||||
)?.versions.map((version) => (
|
|
||||||
<SelectItem key={version.slug} value={version.name}>
|
|
||||||
{version.name}
|
|
||||||
</SelectItem>
|
|
||||||
))}
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
</div>
|
|
||||||
<Button
|
|
||||||
variant="destructive"
|
|
||||||
size="sm"
|
|
||||||
type="button"
|
|
||||||
onClick={() => removeInstallMethod(index)}
|
|
||||||
>
|
|
||||||
<Trash2 className="mr-2 h-4 w-4" /> Remove Install Method
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
<Button
|
|
||||||
type="button"
|
|
||||||
size="sm"
|
|
||||||
disabled={script.install_methods.length >= 2}
|
|
||||||
onClick={addInstallMethod}
|
|
||||||
>
|
|
||||||
<PlusCircle className="mr-2 h-4 w-4" /> Add Install Method
|
|
||||||
</Button>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default memo(InstallMethod);
|
|
||||||
@@ -1,130 +0,0 @@
|
|||||||
import { Button } from "@/components/ui/button";
|
|
||||||
import { Input } from "@/components/ui/input";
|
|
||||||
import {
|
|
||||||
Select,
|
|
||||||
SelectContent,
|
|
||||||
SelectItem,
|
|
||||||
SelectTrigger,
|
|
||||||
SelectValue,
|
|
||||||
} from "@/components/ui/select";
|
|
||||||
import { AlertColors } from "@/config/siteConfig";
|
|
||||||
import { cn } from "@/lib/utils";
|
|
||||||
import { PlusCircle, Trash2 } from "lucide-react";
|
|
||||||
import { z } from "zod";
|
|
||||||
import { ScriptSchema, type Script } from "../_schemas/schemas";
|
|
||||||
import { memo, useCallback, useRef } from "react";
|
|
||||||
|
|
||||||
type NoteProps = {
|
|
||||||
script: Script;
|
|
||||||
setScript: (script: Script) => void;
|
|
||||||
setIsValid: (isValid: boolean) => void;
|
|
||||||
setZodErrors: (zodErrors: z.ZodError | null) => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
function Note({
|
|
||||||
script,
|
|
||||||
setScript,
|
|
||||||
setIsValid,
|
|
||||||
setZodErrors,
|
|
||||||
}: NoteProps) {
|
|
||||||
const inputRefs = useRef<(HTMLInputElement | null)[]>([]);
|
|
||||||
|
|
||||||
const addNote = useCallback(() => {
|
|
||||||
setScript({
|
|
||||||
...script,
|
|
||||||
notes: [...script.notes, { text: "", type: "" }],
|
|
||||||
});
|
|
||||||
}, [script, setScript]);
|
|
||||||
|
|
||||||
const updateNote = useCallback((
|
|
||||||
index: number,
|
|
||||||
key: keyof Script["notes"][number],
|
|
||||||
value: string,
|
|
||||||
) => {
|
|
||||||
const updated: Script = {
|
|
||||||
...script,
|
|
||||||
notes: script.notes.map((note, i) =>
|
|
||||||
i === index ? { ...note, [key]: value } : note,
|
|
||||||
),
|
|
||||||
};
|
|
||||||
const result = ScriptSchema.safeParse(updated);
|
|
||||||
setIsValid(result.success);
|
|
||||||
setZodErrors(result.success ? null : result.error);
|
|
||||||
setScript(updated);
|
|
||||||
// Restore focus after state update
|
|
||||||
if (key === "text") {
|
|
||||||
setTimeout(() => {
|
|
||||||
inputRefs.current[index]?.focus();
|
|
||||||
}, 0);
|
|
||||||
}
|
|
||||||
}, [script, setScript, setIsValid, setZodErrors]);
|
|
||||||
|
|
||||||
const removeNote = useCallback((index: number) => {
|
|
||||||
setScript({
|
|
||||||
...script,
|
|
||||||
notes: script.notes.filter((_, i) => i !== index),
|
|
||||||
});
|
|
||||||
}, [script, setScript]);
|
|
||||||
|
|
||||||
const NoteItem = memo(
|
|
||||||
({ note, index }: { note: Script["notes"][number]; index: number }) => (
|
|
||||||
<div className="space-y-2 border p-4 rounded">
|
|
||||||
<Input
|
|
||||||
placeholder="Note Text"
|
|
||||||
value={note.text}
|
|
||||||
onChange={(e) => updateNote(index, "text", e.target.value)}
|
|
||||||
ref={(el) => {
|
|
||||||
inputRefs.current[index] = el;
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<Select
|
|
||||||
value={note.type}
|
|
||||||
onValueChange={(value) => updateNote(index, "type", value)}
|
|
||||||
>
|
|
||||||
<SelectTrigger className="flex-1">
|
|
||||||
<SelectValue placeholder="Type" />
|
|
||||||
</SelectTrigger>
|
|
||||||
<SelectContent>
|
|
||||||
{Object.keys(AlertColors).map((type) => (
|
|
||||||
<SelectItem key={type} value={type}>
|
|
||||||
<span className="flex items-center gap-2">
|
|
||||||
{type.charAt(0).toUpperCase() + type.slice(1)}{" "}
|
|
||||||
<div
|
|
||||||
className={cn(
|
|
||||||
"size-4 rounded-full border",
|
|
||||||
AlertColors[type as keyof typeof AlertColors],
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</SelectItem>
|
|
||||||
))}
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
<Button
|
|
||||||
size="sm"
|
|
||||||
variant="destructive"
|
|
||||||
type="button"
|
|
||||||
onClick={() => removeNote(index)}
|
|
||||||
>
|
|
||||||
<Trash2 className="mr-2 h-4 w-4" /> Remove Note
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
NoteItem.displayName = 'NoteItem';
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<h3 className="text-xl font-semibold">Notes</h3>
|
|
||||||
{script.notes.map((note, index) => (
|
|
||||||
<NoteItem key={index} note={note} index={index} />
|
|
||||||
))}
|
|
||||||
<Button type="button" size="sm" onClick={addNote}>
|
|
||||||
<PlusCircle className="mr-2 h-4 w-4" /> Add Note
|
|
||||||
</Button>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default memo(Note);
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
import { z } from "zod";
|
|
||||||
|
|
||||||
export const InstallMethodSchema = z.object({
|
|
||||||
type: z.enum(["default", "alpine"], {
|
|
||||||
errorMap: () => ({ message: "Type must be either 'default' or 'alpine'" })
|
|
||||||
}),
|
|
||||||
script: z.string().min(1, "Script content cannot be empty"),
|
|
||||||
resources: z.object({
|
|
||||||
cpu: z.number().nullable(),
|
|
||||||
ram: z.number().nullable(),
|
|
||||||
hdd: z.number().nullable(),
|
|
||||||
os: z.string().nullable(),
|
|
||||||
version: z.string().nullable(),
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
const NoteSchema = z.object({
|
|
||||||
text: z.string().min(1, "Note text cannot be empty"),
|
|
||||||
type: z.string().min(1, "Note type cannot be empty"),
|
|
||||||
});
|
|
||||||
|
|
||||||
export const ScriptSchema = z.object({
|
|
||||||
name: z.string().min(1, "Name is required"),
|
|
||||||
slug: z.string().min(1, "Slug is required"),
|
|
||||||
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"),
|
|
||||||
type: z.enum(["vm", "ct", "misc", "turnkey"], {
|
|
||||||
errorMap: () => ({ message: "Type must be either 'vm', 'ct', 'misc' or 'turnkey'" })
|
|
||||||
}),
|
|
||||||
updateable: z.boolean(),
|
|
||||||
privileged: z.boolean(),
|
|
||||||
interface_port: z.number().nullable(),
|
|
||||||
documentation: z.string().nullable(),
|
|
||||||
website: z.string().url().nullable(),
|
|
||||||
logo: z.string().url().nullable(),
|
|
||||||
description: z.string().min(1, "Description is required"),
|
|
||||||
install_methods: z.array(InstallMethodSchema).min(1, "At least one install method is required"),
|
|
||||||
default_credentials: z.object({
|
|
||||||
username: z.string().nullable(),
|
|
||||||
password: z.string().nullable(),
|
|
||||||
}),
|
|
||||||
notes: z.array(NoteSchema),
|
|
||||||
});
|
|
||||||
|
|
||||||
export type Script = z.infer<typeof ScriptSchema>;
|
|
||||||
@@ -1,335 +0,0 @@
|
|||||||
"use client";
|
|
||||||
|
|
||||||
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
|
||||||
import { Button } from "@/components/ui/button";
|
|
||||||
import { Calendar } from "@/components/ui/calendar";
|
|
||||||
import { Input } from "@/components/ui/input";
|
|
||||||
import { Label } from "@/components/ui/label";
|
|
||||||
import {
|
|
||||||
Popover,
|
|
||||||
PopoverContent,
|
|
||||||
PopoverTrigger,
|
|
||||||
} from "@/components/ui/popover";
|
|
||||||
import {
|
|
||||||
Select,
|
|
||||||
SelectContent,
|
|
||||||
SelectItem,
|
|
||||||
SelectTrigger,
|
|
||||||
SelectValue,
|
|
||||||
} from "@/components/ui/select";
|
|
||||||
import { Switch } from "@/components/ui/switch";
|
|
||||||
import { Textarea } from "@/components/ui/textarea";
|
|
||||||
import { fetchCategories } from "@/lib/data";
|
|
||||||
import { Category } from "@/lib/types";
|
|
||||||
import { cn } from "@/lib/utils";
|
|
||||||
import { format } from "date-fns";
|
|
||||||
import { CalendarIcon, Check, Clipboard } from "lucide-react";
|
|
||||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
||||||
import { toast } from "sonner";
|
|
||||||
import { z } from "zod";
|
|
||||||
import Categories from "./_components/Categories";
|
|
||||||
import InstallMethod from "./_components/InstallMethod";
|
|
||||||
import Note from "./_components/Note";
|
|
||||||
import { ScriptSchema, type Script } from "./_schemas/schemas";
|
|
||||||
|
|
||||||
const initialScript: Script = {
|
|
||||||
name: "",
|
|
||||||
slug: "",
|
|
||||||
categories: [],
|
|
||||||
date_created: "",
|
|
||||||
type: "ct",
|
|
||||||
updateable: false,
|
|
||||||
privileged: false,
|
|
||||||
interface_port: null,
|
|
||||||
documentation: null,
|
|
||||||
website: null,
|
|
||||||
logo: null,
|
|
||||||
description: "",
|
|
||||||
install_methods: [],
|
|
||||||
default_credentials: {
|
|
||||||
username: null,
|
|
||||||
password: null,
|
|
||||||
},
|
|
||||||
notes: [],
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function JSONGenerator() {
|
|
||||||
const [script, setScript] = useState<Script>(initialScript);
|
|
||||||
const [isCopied, setIsCopied] = useState(false);
|
|
||||||
const [isValid, setIsValid] = useState(false);
|
|
||||||
const [categories, setCategories] = useState<Category[]>([]);
|
|
||||||
const [zodErrors, setZodErrors] = useState<z.ZodError | null>(null);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
fetchCategories()
|
|
||||||
.then(setCategories)
|
|
||||||
.catch((error) => console.error("Error fetching categories:", error));
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const updateScript = useCallback(
|
|
||||||
(key: keyof Script, value: Script[keyof Script]) => {
|
|
||||||
setScript((prev) => {
|
|
||||||
const updated = { ...prev, [key]: value };
|
|
||||||
|
|
||||||
if (key === "type" || key === "slug") {
|
|
||||||
updated.install_methods = updated.install_methods.map((method) => ({
|
|
||||||
...method,
|
|
||||||
script:
|
|
||||||
method.type === "alpine"
|
|
||||||
? `/${updated.type}/alpine-${updated.slug}.sh`
|
|
||||||
: `/${updated.type}/${updated.slug}.sh`,
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = ScriptSchema.safeParse(updated);
|
|
||||||
setIsValid(result.success);
|
|
||||||
setZodErrors(result.success ? null : result.error);
|
|
||||||
return updated;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
[],
|
|
||||||
);
|
|
||||||
|
|
||||||
const handleCopy = useCallback(() => {
|
|
||||||
navigator.clipboard.writeText(JSON.stringify(script, null, 2));
|
|
||||||
setIsCopied(true);
|
|
||||||
setTimeout(() => setIsCopied(false), 2000);
|
|
||||||
toast.success("Copied metadata to clipboard");
|
|
||||||
}, [script]);
|
|
||||||
|
|
||||||
const handleDateSelect = useCallback(
|
|
||||||
(date: Date | undefined) => {
|
|
||||||
updateScript("date_created", format(date || new Date(), "yyyy-MM-dd"));
|
|
||||||
},
|
|
||||||
[updateScript],
|
|
||||||
);
|
|
||||||
|
|
||||||
const formattedDate = useMemo(
|
|
||||||
() =>
|
|
||||||
script.date_created ? format(script.date_created, "PPP") : undefined,
|
|
||||||
[script.date_created],
|
|
||||||
);
|
|
||||||
|
|
||||||
const validationAlert = useMemo(
|
|
||||||
() => (
|
|
||||||
<Alert
|
|
||||||
className={cn("text-black", isValid ? "bg-green-100" : "bg-red-100")}
|
|
||||||
>
|
|
||||||
<AlertTitle>{isValid ? "Valid JSON" : "Invalid JSON"}</AlertTitle>
|
|
||||||
<AlertDescription>
|
|
||||||
{isValid
|
|
||||||
? "The current JSON is valid according to the schema."
|
|
||||||
: "The current JSON does not match the required schema."}
|
|
||||||
</AlertDescription>
|
|
||||||
{zodErrors && (
|
|
||||||
<div className="mt-2 space-y-1">
|
|
||||||
{zodErrors.errors.map((error, index) => (
|
|
||||||
<AlertDescription key={index} className="p-1 text-red-500">
|
|
||||||
{error.path.join(".")} - {error.message}
|
|
||||||
</AlertDescription>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</Alert>
|
|
||||||
),
|
|
||||||
[isValid, zodErrors],
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="flex h-screen mt-20">
|
|
||||||
<div className="w-1/2 p-4 overflow-y-auto">
|
|
||||||
<h2 className="text-2xl font-bold mb-4">JSON Generator</h2>
|
|
||||||
<form className="space-y-4">
|
|
||||||
<div className="grid grid-cols-2 gap-4">
|
|
||||||
<div>
|
|
||||||
<Label>
|
|
||||||
Name <span className="text-red-500">*</span>
|
|
||||||
</Label>
|
|
||||||
<Input
|
|
||||||
placeholder="Example"
|
|
||||||
value={script.name}
|
|
||||||
onChange={(e) => updateScript("name", e.target.value)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<Label>
|
|
||||||
Slug <span className="text-red-500">*</span>
|
|
||||||
</Label>
|
|
||||||
<Input
|
|
||||||
placeholder="example"
|
|
||||||
value={script.slug}
|
|
||||||
onChange={(e) => updateScript("slug", e.target.value)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<Label>
|
|
||||||
Logo <span className="text-red-500">*</span>
|
|
||||||
</Label>
|
|
||||||
<Input
|
|
||||||
placeholder="Full logo URL"
|
|
||||||
value={script.logo || ""}
|
|
||||||
onChange={(e) => updateScript("logo", e.target.value || null)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<Label>
|
|
||||||
Description <span className="text-red-500">*</span>
|
|
||||||
</Label>
|
|
||||||
<Textarea
|
|
||||||
placeholder="Example"
|
|
||||||
value={script.description}
|
|
||||||
onChange={(e) => updateScript("description", e.target.value)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<Categories
|
|
||||||
script={script}
|
|
||||||
setScript={setScript}
|
|
||||||
categories={categories}
|
|
||||||
/>
|
|
||||||
<div className="flex gap-2">
|
|
||||||
<div className="flex flex-col gap-2 w-full">
|
|
||||||
<Label>Date Created</Label>
|
|
||||||
<Popover>
|
|
||||||
<PopoverTrigger asChild className="flex-1">
|
|
||||||
<Button
|
|
||||||
variant={"outline"}
|
|
||||||
className={cn(
|
|
||||||
"pl-3 text-left font-normal w-full",
|
|
||||||
!script.date_created && "text-muted-foreground",
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{formattedDate || <span>Pick a date</span>}
|
|
||||||
<CalendarIcon className="ml-auto h-4 w-4 opacity-50" />
|
|
||||||
</Button>
|
|
||||||
</PopoverTrigger>
|
|
||||||
<PopoverContent className="w-auto p-0" align="start">
|
|
||||||
<Calendar
|
|
||||||
mode="single"
|
|
||||||
selected={new Date(script.date_created)}
|
|
||||||
onSelect={handleDateSelect}
|
|
||||||
initialFocus
|
|
||||||
/>
|
|
||||||
</PopoverContent>
|
|
||||||
</Popover>
|
|
||||||
</div>
|
|
||||||
<div className="flex flex-col gap-2 w-full">
|
|
||||||
<Label>Type</Label>
|
|
||||||
<Select
|
|
||||||
value={script.type}
|
|
||||||
onValueChange={(value) => updateScript("type", value)}
|
|
||||||
>
|
|
||||||
<SelectTrigger className="flex-1">
|
|
||||||
<SelectValue placeholder="Type" />
|
|
||||||
</SelectTrigger>
|
|
||||||
<SelectContent>
|
|
||||||
<SelectItem value="ct">LXC Container</SelectItem>
|
|
||||||
<SelectItem value="vm">Virtual Machine</SelectItem>
|
|
||||||
<SelectItem value="misc">Miscellaneous</SelectItem>
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="w-full flex gap-5">
|
|
||||||
<div className="flex items-center space-x-2">
|
|
||||||
<Switch
|
|
||||||
checked={script.updateable}
|
|
||||||
onCheckedChange={(checked) =>
|
|
||||||
updateScript("updateable", checked)
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<label>Updateable</label>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center space-x-2">
|
|
||||||
<Switch
|
|
||||||
checked={script.privileged}
|
|
||||||
onCheckedChange={(checked) =>
|
|
||||||
updateScript("privileged", checked)
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<label>Privileged</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<Input
|
|
||||||
placeholder="Interface Port"
|
|
||||||
type="number"
|
|
||||||
value={script.interface_port || ""}
|
|
||||||
onChange={(e) =>
|
|
||||||
updateScript(
|
|
||||||
"interface_port",
|
|
||||||
e.target.value ? Number(e.target.value) : null,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<div className="flex gap-2">
|
|
||||||
<Input
|
|
||||||
placeholder="Website URL"
|
|
||||||
value={script.website || ""}
|
|
||||||
onChange={(e) => updateScript("website", e.target.value || null)}
|
|
||||||
/>
|
|
||||||
<Input
|
|
||||||
placeholder="Documentation URL"
|
|
||||||
value={script.documentation || ""}
|
|
||||||
onChange={(e) =>
|
|
||||||
updateScript("documentation", e.target.value || null)
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<InstallMethod
|
|
||||||
script={script}
|
|
||||||
setScript={setScript}
|
|
||||||
setIsValid={setIsValid}
|
|
||||||
setZodErrors={setZodErrors}
|
|
||||||
/>
|
|
||||||
<h3 className="text-xl font-semibold">Default Credentials</h3>
|
|
||||||
<Input
|
|
||||||
placeholder="Username"
|
|
||||||
value={script.default_credentials.username || ""}
|
|
||||||
onChange={(e) =>
|
|
||||||
updateScript("default_credentials", {
|
|
||||||
...script.default_credentials,
|
|
||||||
username: e.target.value || null,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<Input
|
|
||||||
placeholder="Password"
|
|
||||||
value={script.default_credentials.password || ""}
|
|
||||||
onChange={(e) =>
|
|
||||||
updateScript("default_credentials", {
|
|
||||||
...script.default_credentials,
|
|
||||||
password: e.target.value || null,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<Note
|
|
||||||
script={script}
|
|
||||||
setScript={setScript}
|
|
||||||
setIsValid={setIsValid}
|
|
||||||
setZodErrors={setZodErrors}
|
|
||||||
/>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<div className="w-1/2 p-4 bg-background overflow-y-auto">
|
|
||||||
{validationAlert}
|
|
||||||
<div className="relative">
|
|
||||||
<Button
|
|
||||||
className="absolute right-2 top-2"
|
|
||||||
size="icon"
|
|
||||||
variant="outline"
|
|
||||||
onClick={handleCopy}
|
|
||||||
>
|
|
||||||
{isCopied ? (
|
|
||||||
<Check className="h-4 w-4" />
|
|
||||||
) : (
|
|
||||||
<Clipboard className="h-4 w-4" />
|
|
||||||
)}
|
|
||||||
</Button>
|
|
||||||
<pre className="mt-4 p-4 bg-secondary rounded shadow overflow-x-scroll">
|
|
||||||
{JSON.stringify(script, null, 2)}
|
|
||||||
</pre>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,94 +0,0 @@
|
|||||||
import Footer from "@/components/Footer";
|
|
||||||
import Navbar from "@/components/Navbar";
|
|
||||||
import { ThemeProvider } from "@/components/theme-provider";
|
|
||||||
import { Toaster } from "@/components/ui/sonner";
|
|
||||||
import { analytics, basePath } from "@/config/siteConfig";
|
|
||||||
import "@/styles/globals.css";
|
|
||||||
import { Inter } from "next/font/google";
|
|
||||||
import { NuqsAdapter } from "nuqs/adapters/next/app";
|
|
||||||
import React from "react";
|
|
||||||
|
|
||||||
const inter = Inter({ subsets: ["latin"] });
|
|
||||||
|
|
||||||
export const metadata = {
|
|
||||||
title: "Proxmox VE Helper-Scripts",
|
|
||||||
generator: "Next.js",
|
|
||||||
applicationName: "Proxmox VE Helper-Scripts",
|
|
||||||
referrer: "origin-when-cross-origin",
|
|
||||||
keywords: [
|
|
||||||
"Proxmox VE",
|
|
||||||
"Helper-Scripts",
|
|
||||||
"tteck",
|
|
||||||
"helper",
|
|
||||||
"scripts",
|
|
||||||
"proxmox",
|
|
||||||
"VE",
|
|
||||||
],
|
|
||||||
authors: { name: "Bram Suurd" },
|
|
||||||
creator: "Bram Suurd",
|
|
||||||
publisher: "Bram Suurd",
|
|
||||||
description:
|
|
||||||
"A Front-end for the Proxmox VE Helper-Scripts (Community) Repository. Featuring over 200+ scripts to help you manage your Proxmox VE environment.",
|
|
||||||
favicon: "/app/favicon.ico",
|
|
||||||
formatDetection: {
|
|
||||||
email: false,
|
|
||||||
address: false,
|
|
||||||
telephone: false,
|
|
||||||
},
|
|
||||||
metadataBase: new URL(`https://community-scripts.github.io/${basePath}/`),
|
|
||||||
openGraph: {
|
|
||||||
title: "Proxmox VE Helper-Scripts",
|
|
||||||
description:
|
|
||||||
"A Front-end for the Proxmox VE Helper-Scripts (Community) Repository. Featuring over 200+ scripts to help you manage your Proxmox VE environment.",
|
|
||||||
url: "/defaultimg.png",
|
|
||||||
images: [
|
|
||||||
{
|
|
||||||
url: `https://community-scripts.github.io/${basePath}/defaultimg.png`,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
locale: "en_US",
|
|
||||||
type: "website",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function RootLayout({
|
|
||||||
children,
|
|
||||||
}: Readonly<{
|
|
||||||
children: React.ReactNode;
|
|
||||||
}>) {
|
|
||||||
return (
|
|
||||||
<html lang="en" suppressHydrationWarning>
|
|
||||||
<head>
|
|
||||||
<script
|
|
||||||
defer
|
|
||||||
src={`https://${analytics.url}/script.js`}
|
|
||||||
data-website-id={analytics.token}
|
|
||||||
></script>
|
|
||||||
<link rel="canonical" href={metadata.metadataBase.href} />
|
|
||||||
<link rel="manifest" href="manifest.webmanifest" />
|
|
||||||
<link rel="preconnect" href="https://api.github.com" />
|
|
||||||
</head>
|
|
||||||
<body className={inter.className}>
|
|
||||||
<ThemeProvider
|
|
||||||
attribute="class"
|
|
||||||
defaultTheme="dark"
|
|
||||||
enableSystem
|
|
||||||
disableTransitionOnChange
|
|
||||||
>
|
|
||||||
<div className="flex w-full flex-col justify-center">
|
|
||||||
<Navbar />
|
|
||||||
<div className="flex min-h-screen flex-col justify-center">
|
|
||||||
<div className="flex w-full justify-center">
|
|
||||||
<div className="w-full max-w-7xl ">
|
|
||||||
<NuqsAdapter>{children}</NuqsAdapter>
|
|
||||||
<Toaster richColors />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<Footer />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</ThemeProvider>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
import { basePath } from "@/config/siteConfig";
|
|
||||||
import type { MetadataRoute } from "next";
|
|
||||||
|
|
||||||
export const generateStaticParams = () => {
|
|
||||||
return [];
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function manifest(): MetadataRoute.Manifest {
|
|
||||||
return {
|
|
||||||
name: "Proxmox VE Helper-Scripts",
|
|
||||||
short_name: "Proxmox VE Helper-Scripts",
|
|
||||||
description:
|
|
||||||
"A Re-designed Front-end for the Proxmox VE Helper-Scripts Repository. Featuring over 200+ scripts to help you manage your Proxmox VE environment.",
|
|
||||||
theme_color: "#030712",
|
|
||||||
background_color: "#030712",
|
|
||||||
display: "standalone",
|
|
||||||
orientation: "portrait",
|
|
||||||
scope: `${basePath}`,
|
|
||||||
start_url: `${basePath}`,
|
|
||||||
icons: [
|
|
||||||
{
|
|
||||||
src: "logo.png",
|
|
||||||
sizes: "512x512",
|
|
||||||
type: "image/png",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
"use client";
|
|
||||||
import { Button } from "@/components/ui/button";
|
|
||||||
|
|
||||||
export default function NotFoundPage() {
|
|
||||||
return (
|
|
||||||
<div className="flex h-screen w-full flex-col items-center justify-center gap-5 bg-background px-4 md:px-6">
|
|
||||||
<div className="space-y-2 text-center">
|
|
||||||
<h1 className="text-4xl font-bold tracking-tighter sm:text-5xl md:text-6xl">
|
|
||||||
404
|
|
||||||
</h1>
|
|
||||||
<p className="text-muted-foreground md:text-xl">
|
|
||||||
Oops, the page you are looking for could not be found.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<Button onClick={() => window.history.back()} variant="secondary">
|
|
||||||
Go Back
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,146 +0,0 @@
|
|||||||
"use client";
|
|
||||||
import AnimatedGradientText from "@/components/ui/animated-gradient-text";
|
|
||||||
import { Button } from "@/components/ui/button";
|
|
||||||
import { CardFooter } from "@/components/ui/card";
|
|
||||||
import {
|
|
||||||
Dialog,
|
|
||||||
DialogContent,
|
|
||||||
DialogDescription,
|
|
||||||
DialogHeader,
|
|
||||||
DialogTitle,
|
|
||||||
DialogTrigger,
|
|
||||||
} from "@/components/ui/dialog";
|
|
||||||
import Particles from "@/components/ui/particles";
|
|
||||||
import { Separator } from "@/components/ui/separator";
|
|
||||||
import { basePath } from "@/config/siteConfig";
|
|
||||||
import { cn } from "@/lib/utils";
|
|
||||||
import { ArrowRightIcon, ExternalLink } from "lucide-react";
|
|
||||||
import { useTheme } from "next-themes";
|
|
||||||
import Link from "next/link";
|
|
||||||
import { useEffect, useState } from "react";
|
|
||||||
import { FaGithub } from "react-icons/fa";
|
|
||||||
|
|
||||||
function CustomArrowRightIcon() {
|
|
||||||
return <ArrowRightIcon className="h-4 w-4" width={1} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function Page() {
|
|
||||||
const { theme } = useTheme();
|
|
||||||
|
|
||||||
const [color, setColor] = useState("#000000");
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setColor(theme === "dark" ? "#ffffff" : "#000000");
|
|
||||||
}, [theme]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="w-full mt-16">
|
|
||||||
<Particles
|
|
||||||
className="absolute inset-0 -z-40"
|
|
||||||
quantity={100}
|
|
||||||
ease={80}
|
|
||||||
color={color}
|
|
||||||
refresh
|
|
||||||
/>
|
|
||||||
<div className="container mx-auto">
|
|
||||||
<div className="flex h-[80vh] flex-col items-center justify-center gap-4 py-20 lg:py-40">
|
|
||||||
<Dialog>
|
|
||||||
<DialogTrigger>
|
|
||||||
<div>
|
|
||||||
<AnimatedGradientText>
|
|
||||||
<div
|
|
||||||
className={cn(
|
|
||||||
`absolute inset-0 block size-full animate-gradient bg-gradient-to-r from-[#ffaa40]/50 via-[#9c40ff]/50 to-[#ffaa40]/50 bg-[length:var(--bg-size)_100%] [border-radius:inherit] [mask:linear-gradient(#fff_0_0)_content-box,linear-gradient(#fff_0_0)]`,
|
|
||||||
`p-px ![mask-composite:subtract]`,
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
❤️ <Separator className="mx-2 h-4" orientation="vertical" />
|
|
||||||
<span
|
|
||||||
className={cn(
|
|
||||||
`animate-gradient bg-gradient-to-r from-[#ffaa40] via-[#9c40ff] to-[#ffaa40] bg-[length:var(--bg-size)_100%] bg-clip-text text-transparent`,
|
|
||||||
`inline`,
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
Scripts by Tteck
|
|
||||||
</span>
|
|
||||||
</AnimatedGradientText>
|
|
||||||
</div>
|
|
||||||
</DialogTrigger>
|
|
||||||
<DialogContent>
|
|
||||||
<DialogHeader>
|
|
||||||
<DialogTitle>Thank You!</DialogTitle>
|
|
||||||
<DialogDescription>
|
|
||||||
A big thank you to Tteck and the many contributors who have
|
|
||||||
made this project possible. Your hard work is truly
|
|
||||||
appreciated by the entire Proxmox community!
|
|
||||||
</DialogDescription>
|
|
||||||
</DialogHeader>
|
|
||||||
<CardFooter className="flex flex-col gap-2">
|
|
||||||
<Button className="w-full" variant="outline" asChild>
|
|
||||||
<a
|
|
||||||
href="https://github.com/tteck"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
className="flex items-center justify-center"
|
|
||||||
>
|
|
||||||
<FaGithub className="mr-2 h-4 w-4" /> Tteck's GitHub
|
|
||||||
</a>
|
|
||||||
</Button>
|
|
||||||
<Button className="w-full" asChild>
|
|
||||||
<a
|
|
||||||
href={`https://github.com/community-scripts/${basePath}`}
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
className="flex items-center justify-center"
|
|
||||||
>
|
|
||||||
<ExternalLink className="mr-2 h-4 w-4" /> Proxmox Helper
|
|
||||||
Scripts
|
|
||||||
</a>
|
|
||||||
</Button>
|
|
||||||
</CardFooter>
|
|
||||||
</DialogContent>
|
|
||||||
</Dialog>
|
|
||||||
|
|
||||||
<div className="flex flex-col gap-4">
|
|
||||||
<h1 className="max-w-2xl text-center text-5xl font-semibold tracking-tighter md:text-7xl">
|
|
||||||
Make managing your Homelab a breeze
|
|
||||||
</h1>
|
|
||||||
<p className="max-w-2xl text-center text-lg leading-relaxed tracking-tight text-muted-foreground md:text-xl">
|
|
||||||
We are a community-driven initiative that simplifies the setup of
|
|
||||||
Proxmox Virtual Environment (VE).
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
Originally created by{" "}
|
|
||||||
<a href="https://github.com/tteck" target="_blank">
|
|
||||||
tteck
|
|
||||||
</a>
|
|
||||||
, these scripts automate and streamline
|
|
||||||
<br />
|
|
||||||
the process of creating and configuring Linux containers (LXC) and
|
|
||||||
virtual machines (VMs) on Proxmox VE.
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
With 200+ scripts to help you manage your{" "}
|
|
||||||
<b>Proxmox VE environment</b>.<br />
|
|
||||||
Whether you're a seasoned user or a newcomer, we've got
|
|
||||||
you covered.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div className="flex flex-row gap-3">
|
|
||||||
<Link href="/scripts">
|
|
||||||
<Button
|
|
||||||
size="lg"
|
|
||||||
variant="expandIcon"
|
|
||||||
Icon={CustomArrowRightIcon}
|
|
||||||
iconPlacement="right"
|
|
||||||
className="hover:"
|
|
||||||
>
|
|
||||||
View Scripts
|
|
||||||
</Button>
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
import { basePath } from "@/config/siteConfig";
|
|
||||||
import type { MetadataRoute } from "next";
|
|
||||||
|
|
||||||
export const dynamic = "force-static";
|
|
||||||
|
|
||||||
export default function robots(): MetadataRoute.Robots {
|
|
||||||
return {
|
|
||||||
rules: {
|
|
||||||
userAgent: "*",
|
|
||||||
allow: "/",
|
|
||||||
},
|
|
||||||
sitemap: `https://community-scripts.github.io/${basePath}/sitemap.xml`,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,132 +0,0 @@
|
|||||||
import { useCallback, useEffect, useRef } from "react";
|
|
||||||
|
|
||||||
import { formattedBadge } from "@/components/CommandMenu";
|
|
||||||
import {
|
|
||||||
Accordion,
|
|
||||||
AccordionContent,
|
|
||||||
AccordionItem,
|
|
||||||
AccordionTrigger,
|
|
||||||
} from "@/components/ui/accordion";
|
|
||||||
import { Category } from "@/lib/types";
|
|
||||||
import { cn } from "@/lib/utils";
|
|
||||||
import Image from "next/image";
|
|
||||||
import Link from "next/link";
|
|
||||||
import { useState } from "react";
|
|
||||||
import { basePath } from "@/config/siteConfig";
|
|
||||||
|
|
||||||
export default function ScriptAccordion({
|
|
||||||
items,
|
|
||||||
selectedScript,
|
|
||||||
setSelectedScript,
|
|
||||||
}: {
|
|
||||||
items: Category[];
|
|
||||||
selectedScript: string | null;
|
|
||||||
setSelectedScript: (script: string | null) => void;
|
|
||||||
}) {
|
|
||||||
const [expandedItem, setExpandedItem] = useState<string | undefined>(
|
|
||||||
undefined,
|
|
||||||
);
|
|
||||||
const linkRefs = useRef<{ [key: string]: HTMLAnchorElement | null }>({});
|
|
||||||
|
|
||||||
const handleAccordionChange = (value: string | undefined) => {
|
|
||||||
setExpandedItem(value);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleSelected = useCallback(
|
|
||||||
(slug: string) => {
|
|
||||||
setSelectedScript(slug);
|
|
||||||
},
|
|
||||||
[setSelectedScript],
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (selectedScript) {
|
|
||||||
const category = items.find((category) =>
|
|
||||||
category.scripts.some((script) => script.slug === selectedScript),
|
|
||||||
);
|
|
||||||
if (category) {
|
|
||||||
setExpandedItem(category.name);
|
|
||||||
handleSelected(selectedScript);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, [selectedScript, items, handleSelected]);
|
|
||||||
return (
|
|
||||||
<Accordion
|
|
||||||
type="single"
|
|
||||||
value={expandedItem}
|
|
||||||
onValueChange={handleAccordionChange}
|
|
||||||
collapsible
|
|
||||||
className="overflow-y-scroll max-h-[calc(100vh-220px)] overflow-x-hidden mt-3 p-2"
|
|
||||||
>
|
|
||||||
{items.map((category) => (
|
|
||||||
<AccordionItem
|
|
||||||
key={category.id + ":category"}
|
|
||||||
value={category.name}
|
|
||||||
className={cn("sm:text-md flex flex-col border-none", {
|
|
||||||
"rounded-lg bg-accent/30": expandedItem === category.name,
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
<AccordionTrigger
|
|
||||||
className={cn(
|
|
||||||
"duration-250 rounded-lg transition ease-in-out hover:-translate-y-1 hover:scale-105 hover:bg-accent",
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<div className="mr-2 flex w-full items-center justify-between">
|
|
||||||
<span className="pl-2">{category.name} </span>
|
|
||||||
<span className="rounded-full bg-gray-200 px-2 py-1 text-xs text-muted-foreground hover:no-underline dark:bg-blue-800/20">
|
|
||||||
{category.scripts.length}
|
|
||||||
</span>
|
|
||||||
</div>{" "}
|
|
||||||
</AccordionTrigger>
|
|
||||||
<AccordionContent
|
|
||||||
data-state={expandedItem === category.name ? "open" : "closed"}
|
|
||||||
className="pt-0"
|
|
||||||
>
|
|
||||||
{category.scripts
|
|
||||||
.slice()
|
|
||||||
.sort((a, b) => a.name.localeCompare(b.name))
|
|
||||||
.map((script, index) => (
|
|
||||||
<div key={index}>
|
|
||||||
<Link
|
|
||||||
href={{
|
|
||||||
pathname: "/scripts",
|
|
||||||
query: { id: script.slug },
|
|
||||||
}}
|
|
||||||
prefetch={false}
|
|
||||||
className={`flex cursor-pointer items-center justify-between gap-1 px-1 py-1 text-muted-foreground hover:rounded-lg hover:bg-accent/60 hover:dark:bg-accent/20 ${
|
|
||||||
selectedScript === script.slug
|
|
||||||
? "rounded-lg bg-accent font-semibold dark:bg-accent/30 dark:text-white"
|
|
||||||
: ""
|
|
||||||
}`}
|
|
||||||
onClick={() => handleSelected(script.slug)}
|
|
||||||
ref={(el) => {
|
|
||||||
linkRefs.current[script.slug] = el;
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div className="flex items-center">
|
|
||||||
<Image
|
|
||||||
src={script.logo || `/${basePath}/logo.png`}
|
|
||||||
height={16}
|
|
||||||
width={16}
|
|
||||||
unoptimized
|
|
||||||
onError={(e) =>
|
|
||||||
((e.currentTarget as HTMLImageElement).src =
|
|
||||||
`/${basePath}/logo.png`)
|
|
||||||
}
|
|
||||||
alt={script.name}
|
|
||||||
className="mr-1 w-4 h-4 rounded-full"
|
|
||||||
/>
|
|
||||||
<span className="flex items-center gap-2">
|
|
||||||
{script.name}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
{formattedBadge(script.type)}
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</AccordionContent>
|
|
||||||
</AccordionItem>
|
|
||||||
))}
|
|
||||||
</Accordion>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,213 +0,0 @@
|
|||||||
import { Button } from "@/components/ui/button";
|
|
||||||
import {
|
|
||||||
Card,
|
|
||||||
CardContent,
|
|
||||||
CardDescription,
|
|
||||||
CardFooter,
|
|
||||||
CardHeader,
|
|
||||||
CardTitle,
|
|
||||||
} from "@/components/ui/card";
|
|
||||||
import { basePath, mostPopularScripts } from "@/config/siteConfig";
|
|
||||||
import { extractDate } from "@/lib/time";
|
|
||||||
import { Category, Script } from "@/lib/types";
|
|
||||||
import { CalendarPlus } from "lucide-react";
|
|
||||||
import Image from "next/image";
|
|
||||||
import Link from "next/link";
|
|
||||||
import { useMemo, useState } from "react";
|
|
||||||
|
|
||||||
const ITEMS_PER_PAGE = 3;
|
|
||||||
|
|
||||||
export const getDisplayValueFromType = (type: string) => {
|
|
||||||
switch (type) {
|
|
||||||
case "ct":
|
|
||||||
return "LXC";
|
|
||||||
case "vm":
|
|
||||||
return "VM";
|
|
||||||
case "misc":
|
|
||||||
return "";
|
|
||||||
default:
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export function LatestScripts({ items }: { items: Category[] }) {
|
|
||||||
const [page, setPage] = useState(1);
|
|
||||||
|
|
||||||
const latestScripts = useMemo(() => {
|
|
||||||
if (!items) return [];
|
|
||||||
const scripts = items.flatMap((category) => category.scripts || []);
|
|
||||||
return scripts.sort(
|
|
||||||
(a, b) =>
|
|
||||||
new Date(b.date_created).getTime() - new Date(a.date_created).getTime(),
|
|
||||||
);
|
|
||||||
}, [items]);
|
|
||||||
|
|
||||||
const goToNextPage = () => {
|
|
||||||
setPage((prevPage) => prevPage + 1);
|
|
||||||
};
|
|
||||||
|
|
||||||
const goToPreviousPage = () => {
|
|
||||||
setPage((prevPage) => prevPage - 1);
|
|
||||||
};
|
|
||||||
|
|
||||||
const startIndex = (page - 1) * ITEMS_PER_PAGE;
|
|
||||||
const endIndex = page * ITEMS_PER_PAGE;
|
|
||||||
|
|
||||||
if (!items) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="">
|
|
||||||
{latestScripts.length > 0 && (
|
|
||||||
<div className="flex w-full items-center justify-between">
|
|
||||||
<h2 className="text-lg font-semibold">Newest Scripts</h2>
|
|
||||||
<div className="flex items-center justify-end gap-1">
|
|
||||||
{page > 1 && (
|
|
||||||
<div
|
|
||||||
className="cursor-pointer select-none p-2 text-sm font-semibold"
|
|
||||||
onClick={goToPreviousPage}
|
|
||||||
>
|
|
||||||
Previous
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{endIndex < latestScripts.length && (
|
|
||||||
<div
|
|
||||||
onClick={goToNextPage}
|
|
||||||
className="cursor-pointer select-none p-2 text-sm font-semibold"
|
|
||||||
>
|
|
||||||
{page === 1 ? "More.." : "Next"}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<div className="min-w flex w-full flex-row flex-wrap gap-4">
|
|
||||||
{latestScripts.slice(startIndex, endIndex).map((script) => (
|
|
||||||
<Card
|
|
||||||
key={script.slug}
|
|
||||||
className="min-w-[250px] flex-1 flex-grow bg-accent/30"
|
|
||||||
>
|
|
||||||
<CardHeader>
|
|
||||||
<CardTitle className="flex items-center gap-3">
|
|
||||||
<div className="flex h-16 w-16 items-center justify-center rounded-lg bg-accent p-1">
|
|
||||||
<Image
|
|
||||||
src={script.logo || `/${basePath}/logo.png`}
|
|
||||||
unoptimized
|
|
||||||
height={64}
|
|
||||||
width={64}
|
|
||||||
alt=""
|
|
||||||
onError={(e) =>
|
|
||||||
((e.currentTarget as HTMLImageElement).src =
|
|
||||||
`/${basePath}/logo.png`)
|
|
||||||
}
|
|
||||||
className="h-11 w-11 object-contain"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="flex flex-col">
|
|
||||||
<p className="text-lg line-clamp-1">
|
|
||||||
{script.name} {getDisplayValueFromType(script.type)}
|
|
||||||
</p>
|
|
||||||
<p className="text-sm text-muted-foreground flex items-center gap-1">
|
|
||||||
<CalendarPlus className="h-4 w-4" />
|
|
||||||
{extractDate(script.date_created)}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</CardTitle>
|
|
||||||
</CardHeader>
|
|
||||||
<CardContent>
|
|
||||||
<CardDescription className="line-clamp-3 text-card-foreground">
|
|
||||||
{script.description}
|
|
||||||
</CardDescription>
|
|
||||||
</CardContent>
|
|
||||||
<CardFooter className="">
|
|
||||||
<Button asChild variant="outline">
|
|
||||||
<Link
|
|
||||||
href={{
|
|
||||||
pathname: "/scripts",
|
|
||||||
query: { id: script.slug },
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
View Script
|
|
||||||
</Link>
|
|
||||||
</Button>
|
|
||||||
</CardFooter>
|
|
||||||
</Card>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function MostViewedScripts({ items }: { items: Category[] }) {
|
|
||||||
const mostViewedScripts = items.reduce((acc: Script[], category) => {
|
|
||||||
const foundScripts = category.scripts.filter((script) =>
|
|
||||||
mostPopularScripts.includes(script.name),
|
|
||||||
);
|
|
||||||
return acc.concat(foundScripts);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="">
|
|
||||||
{mostViewedScripts.length > 0 && (
|
|
||||||
<>
|
|
||||||
<h2 className="text-lg font-semibold">Most Viewed Scripts</h2>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
<div className="min-w flex w-full flex-row flex-wrap gap-4">
|
|
||||||
{mostViewedScripts.map((script) => (
|
|
||||||
<Card
|
|
||||||
key={script.slug}
|
|
||||||
className="min-w-[250px] flex-1 flex-grow bg-accent/30"
|
|
||||||
>
|
|
||||||
<CardHeader>
|
|
||||||
<CardTitle className="flex items-center gap-3">
|
|
||||||
<div className="flex max-h-16 min-h-16 min-w-16 max-w-16 items-center justify-center rounded-lg bg-accent p-1">
|
|
||||||
<Image
|
|
||||||
unoptimized
|
|
||||||
src={script.logo || `/${basePath}/logo.png`}
|
|
||||||
height={64}
|
|
||||||
width={64}
|
|
||||||
alt=""
|
|
||||||
onError={(e) =>
|
|
||||||
((e.currentTarget as HTMLImageElement).src =
|
|
||||||
`/${basePath}/logo.png`)
|
|
||||||
}
|
|
||||||
className="h-11 w-11 object-contain"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="flex flex-col">
|
|
||||||
<p className="line-clamp-1 text-lg">
|
|
||||||
{script.name} {getDisplayValueFromType(script.type)}
|
|
||||||
</p>
|
|
||||||
<p className="flex items-center gap-1 text-sm text-muted-foreground">
|
|
||||||
<CalendarPlus className="h-4 w-4" />
|
|
||||||
{extractDate(script.date_created)}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</CardTitle>
|
|
||||||
</CardHeader>
|
|
||||||
<CardContent>
|
|
||||||
<CardDescription className="line-clamp-3 text-card-foreground break-words">
|
|
||||||
{script.description}
|
|
||||||
</CardDescription>
|
|
||||||
</CardContent>
|
|
||||||
<CardFooter className="">
|
|
||||||
<Button asChild variant="outline">
|
|
||||||
<Link
|
|
||||||
href={{
|
|
||||||
pathname: "/scripts",
|
|
||||||
query: { id: script.slug },
|
|
||||||
}}
|
|
||||||
prefetch={false}
|
|
||||||
>
|
|
||||||
View Script
|
|
||||||
</Link>
|
|
||||||
</Button>
|
|
||||||
</CardFooter>
|
|
||||||
</Card>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,100 +0,0 @@
|
|||||||
"use client";
|
|
||||||
import { Separator } from "@/components/ui/separator";
|
|
||||||
import { extractDate } from "@/lib/time";
|
|
||||||
import { Script } from "@/lib/types";
|
|
||||||
import { X } from "lucide-react";
|
|
||||||
import Image from "next/image";
|
|
||||||
|
|
||||||
import { getDisplayValueFromType } from "./ScriptInfoBlocks";
|
|
||||||
import Alerts from "./ScriptItems/Alerts";
|
|
||||||
import Buttons from "./ScriptItems/Buttons";
|
|
||||||
import DefaultPassword from "./ScriptItems/DefaultPassword";
|
|
||||||
import DefaultSettings from "./ScriptItems/DefaultSettings";
|
|
||||||
import Description from "./ScriptItems/Description";
|
|
||||||
import InstallCommand from "./ScriptItems/InstallCommand";
|
|
||||||
import InterFaces from "./ScriptItems/InterFaces";
|
|
||||||
import Tooltips from "./ScriptItems/Tooltips";
|
|
||||||
import { basePath } from "@/config/siteConfig";
|
|
||||||
|
|
||||||
function ScriptItem({
|
|
||||||
item,
|
|
||||||
setSelectedScript,
|
|
||||||
}: {
|
|
||||||
item: Script;
|
|
||||||
setSelectedScript: (script: string | null) => void;
|
|
||||||
}) {
|
|
||||||
const closeScript = () => {
|
|
||||||
window.history.pushState({}, document.title, window.location.pathname);
|
|
||||||
setSelectedScript(null);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="mr-7 mt-0 flex w-full min-w-fit">
|
|
||||||
<div className="flex w-full min-w-fit">
|
|
||||||
<div className="flex w-full flex-col">
|
|
||||||
<div className="flex h-[36px] min-w-max items-center justify-between">
|
|
||||||
<h2 className="text-lg font-semibold">Selected Script</h2>
|
|
||||||
<X onClick={closeScript} className="cursor-pointer" />
|
|
||||||
</div>
|
|
||||||
<div className="rounded-lg border bg-accent/20 p-4">
|
|
||||||
<div className="flex justify-between">
|
|
||||||
<div className="flex">
|
|
||||||
<Image
|
|
||||||
className="h-32 w-32 rounded-lg bg-accent/60 object-contain p-3 shadow-md"
|
|
||||||
src={item.logo || `/${basePath}/logo.png`}
|
|
||||||
width={400}
|
|
||||||
onError={(e) =>
|
|
||||||
((e.currentTarget as HTMLImageElement).src =
|
|
||||||
`/${basePath}/logo.png`)
|
|
||||||
}
|
|
||||||
height={400}
|
|
||||||
alt={item.name}
|
|
||||||
unoptimized
|
|
||||||
/>
|
|
||||||
<div className="ml-4 flex flex-col justify-between">
|
|
||||||
<div className="flex h-full w-full flex-col justify-between">
|
|
||||||
<div>
|
|
||||||
<h1 className="text-lg font-semibold">
|
|
||||||
{item.name} {getDisplayValueFromType(item.type)}
|
|
||||||
</h1>
|
|
||||||
<p className="w-full text-sm text-muted-foreground">
|
|
||||||
Date added: {extractDate(item.date_created)}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div className="flex gap-5">
|
|
||||||
<DefaultSettings item={item} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="hidden flex-col justify-between gap-2 sm:flex">
|
|
||||||
<InterFaces item={item} />
|
|
||||||
<Buttons item={item} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<Separator className="mt-4" />
|
|
||||||
<div>
|
|
||||||
<div className="mt-4">
|
|
||||||
<Description item={item} />
|
|
||||||
<Alerts item={item} />
|
|
||||||
</div>
|
|
||||||
<div className="mt-4 rounded-lg border bg-accent/50">
|
|
||||||
<div className="flex gap-3 px-4 py-2">
|
|
||||||
<h2 className="text-lg font-semibold">
|
|
||||||
How to {item.type == "misc" ? "use" : "install"}
|
|
||||||
</h2>
|
|
||||||
<Tooltips item={item} />
|
|
||||||
</div>
|
|
||||||
<Separator className="w-full"></Separator>
|
|
||||||
<InstallCommand item={item} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<DefaultPassword item={item} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ScriptItem;
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
import TextCopyBlock from "@/components/TextCopyBlock";
|
|
||||||
import { AlertColors } from "@/config/siteConfig";
|
|
||||||
import { Script } from "@/lib/types";
|
|
||||||
import { cn } from "@/lib/utils";
|
|
||||||
import { AlertCircle, NotepadText } from "lucide-react";
|
|
||||||
|
|
||||||
type NoteProps = {
|
|
||||||
text: string;
|
|
||||||
type: keyof typeof AlertColors;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function Alerts({ item }: { item: Script }) {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{item?.notes?.length > 0 &&
|
|
||||||
item.notes.map((note: NoteProps, index: number) => (
|
|
||||||
<div key={index} className="mt-4 flex flex-col gap-2">
|
|
||||||
<p
|
|
||||||
className={cn(
|
|
||||||
"inline-flex items-center gap-2 rounded-lg border p-2 pl-4 text-sm",
|
|
||||||
AlertColors[note.type],
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{note.type == "info" ? (
|
|
||||||
<NotepadText className="h-4 min-h-4 w-4 min-w-4" />
|
|
||||||
) : (
|
|
||||||
<AlertCircle className="h-4 min-h-4 w-4 min-w-4" />
|
|
||||||
)}
|
|
||||||
<span>{TextCopyBlock(note.text)}</span>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
import { Button } from "@/components/ui/button";
|
|
||||||
import { basePath } from "@/config/siteConfig";
|
|
||||||
import { Script } from "@/lib/types";
|
|
||||||
import { BookOpenText, Code, Globe } from "lucide-react";
|
|
||||||
import Link from "next/link";
|
|
||||||
|
|
||||||
const generateSourceUrl = (slug: string, type: string) => {
|
|
||||||
const baseUrl = `https://raw.githubusercontent.com/community-scripts/${basePath}/main`;
|
|
||||||
return type === "ct"
|
|
||||||
? `${baseUrl}/install/${slug}-install.sh`
|
|
||||||
: `${baseUrl}/${type}/${slug}.sh`;
|
|
||||||
};
|
|
||||||
|
|
||||||
interface ButtonLinkProps {
|
|
||||||
href: string;
|
|
||||||
icon: React.ReactNode;
|
|
||||||
text: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ButtonLink = ({ href, icon, text }: ButtonLinkProps) => (
|
|
||||||
<Button variant="secondary" asChild>
|
|
||||||
<Link target="_blank" href={href}>
|
|
||||||
<span className="flex items-center gap-2">
|
|
||||||
{icon}
|
|
||||||
{text}
|
|
||||||
</span>
|
|
||||||
</Link>
|
|
||||||
</Button>
|
|
||||||
);
|
|
||||||
|
|
||||||
export default function Buttons({ item }: { item: Script }) {
|
|
||||||
const buttons = [
|
|
||||||
item.website && {
|
|
||||||
href: item.website,
|
|
||||||
icon: <Globe className="h-4 w-4" />,
|
|
||||||
text: "Website",
|
|
||||||
},
|
|
||||||
item.documentation && {
|
|
||||||
href: item.documentation,
|
|
||||||
icon: <BookOpenText className="h-4 w-4" />,
|
|
||||||
text: "Documentation",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
href: generateSourceUrl(item.slug, item.type),
|
|
||||||
icon: <Code className="h-4 w-4" />,
|
|
||||||
text: "Source Code",
|
|
||||||
},
|
|
||||||
].filter(Boolean) as ButtonLinkProps[];
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="flex flex-wrap justify-end gap-2">
|
|
||||||
{buttons.map((props, index) => (
|
|
||||||
<ButtonLink key={index} {...props} />
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
import handleCopy from "@/components/handleCopy";
|
|
||||||
import { Button } from "@/components/ui/button";
|
|
||||||
import { Separator } from "@/components/ui/separator";
|
|
||||||
import { Script } from "@/lib/types";
|
|
||||||
|
|
||||||
export default function DefaultPassword({ item }: { item: Script }) {
|
|
||||||
const { username, password } = item.default_credentials;
|
|
||||||
const hasDefaultLogin = username && password;
|
|
||||||
|
|
||||||
if (!hasDefaultLogin) return null;
|
|
||||||
|
|
||||||
const copyCredential = (type: "username" | "password") => {
|
|
||||||
handleCopy(type, item.default_credentials[type] ?? "");
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="mt-4 rounded-lg border bg-accent/50">
|
|
||||||
<div className="flex gap-3 px-4 py-2">
|
|
||||||
<h2 className="text-lg font-semibold">Default Login Credentials</h2>
|
|
||||||
</div>
|
|
||||||
<Separator className="w-full" />
|
|
||||||
<div className="flex flex-col gap-2 p-4">
|
|
||||||
<p className="mb-2 text-sm">
|
|
||||||
You can use the following credentials to login to the {item.name}{" "}
|
|
||||||
{item.type}.
|
|
||||||
</p>
|
|
||||||
{["username", "password"].map((type) => (
|
|
||||||
<div key={type} className="text-sm">
|
|
||||||
{type.charAt(0).toUpperCase() + type.slice(1)}:{" "}
|
|
||||||
<Button
|
|
||||||
variant="secondary"
|
|
||||||
size="null"
|
|
||||||
onClick={() => copyCredential(type as "username" | "password")}
|
|
||||||
>
|
|
||||||
{item.default_credentials[type as "username" | "password"]}
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
import { Script } from "@/lib/types";
|
|
||||||
|
|
||||||
export default function DefaultSettings({ item }: { item: Script }) {
|
|
||||||
const getDisplayValueFromRAM = (ram: number) =>
|
|
||||||
ram >= 1024 ? `${Math.floor(ram / 1024)}GB` : `${ram}MB`;
|
|
||||||
|
|
||||||
const ResourceDisplay = ({
|
|
||||||
settings,
|
|
||||||
title,
|
|
||||||
}: {
|
|
||||||
settings: (typeof item.install_methods)[0];
|
|
||||||
title: string;
|
|
||||||
}) => {
|
|
||||||
const { cpu, ram, hdd } = settings.resources;
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<h2 className="text-md font-semibold">{title}</h2>
|
|
||||||
<p className="text-sm text-muted-foreground">CPU: {cpu}vCPU</p>
|
|
||||||
<p className="text-sm text-muted-foreground">
|
|
||||||
RAM: {getDisplayValueFromRAM(ram ?? 0)}
|
|
||||||
</p>
|
|
||||||
<p className="text-sm text-muted-foreground">HDD: {hdd}GB</p>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const defaultSettings = item.install_methods.find(
|
|
||||||
(method) => method.type === "default",
|
|
||||||
);
|
|
||||||
const defaultAlpineSettings = item.install_methods.find(
|
|
||||||
(method) => method.type === "alpine",
|
|
||||||
);
|
|
||||||
|
|
||||||
const hasDefaultSettings =
|
|
||||||
defaultSettings?.resources &&
|
|
||||||
Object.values(defaultSettings.resources).some(Boolean);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{hasDefaultSettings && (
|
|
||||||
<ResourceDisplay settings={defaultSettings} title="Default settings" />
|
|
||||||
)}
|
|
||||||
{defaultAlpineSettings && (
|
|
||||||
<ResourceDisplay
|
|
||||||
settings={defaultAlpineSettings}
|
|
||||||
title="Default Alpine settings"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
import TextCopyBlock from "@/components/TextCopyBlock";
|
|
||||||
import { Script } from "@/lib/types";
|
|
||||||
|
|
||||||
export default function Description({ item }: { item: Script }) {
|
|
||||||
return (
|
|
||||||
<div className="p-2">
|
|
||||||
<h2 className="mb-2 max-w-prose text-lg font-semibold">Description</h2>
|
|
||||||
<p className="text-sm text-muted-foreground">
|
|
||||||
{TextCopyBlock(item.description)}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user