mirror of
https://github.com/community-scripts/ProxmoxVE
synced 2025-04-23 01:55:13 +00:00
Compare commits
No commits in common. "main" and "2025-04-18" have entirely different histories.
main
...
2025-04-18
51
.github/workflows/close-ttek-issues.yaml
vendored
51
.github/workflows/close-ttek-issues.yaml
vendored
@ -1,51 +0,0 @@
|
||||
name: Auto-Close tteck Issues
|
||||
on:
|
||||
issues:
|
||||
types: [opened]
|
||||
|
||||
jobs:
|
||||
close_tteck_issues:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Auto-close if tteck script detected
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const issue = context.payload.issue;
|
||||
const content = `${issue.title}\n${issue.body}`;
|
||||
const issueNumber = issue.number;
|
||||
|
||||
// Check for tteck script mention
|
||||
if (content.includes("tteck") || content.includes("tteck/Proxmox")) {
|
||||
const message = `Hello, it looks like you are referencing the **old tteck repo**.
|
||||
|
||||
This repository is no longer used for active scripts.
|
||||
**Please update your bookmarks** and use: [https://helper-scripts.com](https://helper-scripts.com)
|
||||
|
||||
Also make sure your Bash command starts with:
|
||||
\`\`\`bash
|
||||
bash <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/...)
|
||||
\`\`\`
|
||||
|
||||
This issue is being closed automatically.`;
|
||||
|
||||
await github.rest.issues.createComment({
|
||||
...context.repo,
|
||||
issue_number: issueNumber,
|
||||
body: message
|
||||
});
|
||||
|
||||
// Optionally apply a label like "not planned"
|
||||
await github.rest.issues.addLabels({
|
||||
...context.repo,
|
||||
issue_number: issueNumber,
|
||||
labels: ["not planned"]
|
||||
});
|
||||
|
||||
// Close the issue
|
||||
await github.rest.issues.update({
|
||||
...context.repo,
|
||||
issue_number: issueNumber,
|
||||
state: "closed"
|
||||
});
|
||||
}
|
46
CHANGELOG.md
46
CHANGELOG.md
@ -14,52 +14,6 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
||||
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.
|
||||
|
||||
|
||||
## 2025-04-22
|
||||
|
||||
### 🆕 New Scripts
|
||||
|
||||
- reactive-resume ([#3980](https://github.com/community-scripts/ProxmoxVE/pull/3980))
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- wger: Fix a bug in update procedure and general code maintenance [@tremor021](https://github.com/tremor021) ([#3974](https://github.com/community-scripts/ProxmoxVE/pull/3974))
|
||||
|
||||
### 🧰 Maintenance
|
||||
|
||||
- #### 📂 Github
|
||||
|
||||
- Add workflow to close ttek Repo relatate issues [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#3981](https://github.com/community-scripts/ProxmoxVE/pull/3981))
|
||||
|
||||
### 🌐 Website
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- Fix Turnkey Source Link in Button Component [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#3978](https://github.com/community-scripts/ProxmoxVE/pull/3978))
|
||||
|
||||
- #### 📝 Script Information
|
||||
|
||||
- qBittorrent: Update web page [@tremor021](https://github.com/tremor021) ([#3969](https://github.com/community-scripts/ProxmoxVE/pull/3969))
|
||||
|
||||
## 2025-04-19
|
||||
|
||||
### 🆕 New Scripts
|
||||
|
||||
- LXC Iptag [@DesertGamer](https://github.com/DesertGamer) ([#3531](https://github.com/community-scripts/ProxmoxVE/pull/3531))
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- seelf: Add missing gpg dependency [@tremor021](https://github.com/tremor021) ([#3953](https://github.com/community-scripts/ProxmoxVE/pull/3953))
|
||||
|
||||
### 🌐 Website
|
||||
|
||||
- #### 📝 Script Information
|
||||
|
||||
- Tailscale: Clarify tailscale script instruction on website [@tremor021](https://github.com/tremor021) ([#3952](https://github.com/community-scripts/ProxmoxVE/pull/3952))
|
||||
|
||||
## 2025-04-18
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
@ -1,6 +0,0 @@
|
||||
____ __ _ ____
|
||||
/ __ \___ ____ ______/ /_(_) _____ / __ \___ _______ ______ ___ ___
|
||||
/ /_/ / _ \/ __ `/ ___/ __/ / | / / _ \______/ /_/ / _ \/ ___/ / / / __ `__ \/ _ \
|
||||
/ _, _/ __/ /_/ / /__/ /_/ /| |/ / __/_____/ _, _/ __(__ ) /_/ / / / / / / __/
|
||||
/_/ |_|\___/\__,_/\___/\__/_/ |___/\___/ /_/ |_|\___/____/\__,_/_/ /_/ /_/\___/
|
||||
|
@ -1,106 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
||||
# Copyright (c) 2021-2025 community-scripts ORG
|
||||
# Author: vhsdream
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://rxresu.me
|
||||
|
||||
APP="Reactive-Resume"
|
||||
var_tags="${var_tags:-documents}"
|
||||
var_cpu="${var_cpu:-2}"
|
||||
var_ram="${var_ram:-3072}"
|
||||
var_disk="${var_disk:-8}"
|
||||
var_os="${var_os:-debian}"
|
||||
var_version="${var_version:-12}"
|
||||
var_unprivileged="${var_unprivileged:-1}"
|
||||
|
||||
header_info "$APP"
|
||||
variables
|
||||
color
|
||||
catch_errors
|
||||
|
||||
function update_script() {
|
||||
header_info
|
||||
check_container_storage
|
||||
check_container_resources
|
||||
|
||||
if [[ ! -f /etc/systemd/system/Reactive-Resume.service ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
RELEASE=$(curl -fsSL https://api.github.com/repos/AmruthPillai/Reactive-Resume/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
|
||||
if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then
|
||||
msg_info "Stopping services"
|
||||
systemctl stop Reactive-Resume
|
||||
msg_ok "Stopped services"
|
||||
|
||||
msg_info "Updating $APP to v${RELEASE}"
|
||||
cp /opt/${APP}/.env /opt/rxresume.env
|
||||
res_tmp=$(mktemp)
|
||||
rm -rf /opt/${APP}
|
||||
curl -fsSL "https://github.com/AmruthPillai/Reactive-Resume/archive/refs/tags/v${RELEASE}.zip" -O $res_tmp
|
||||
unzip -q $res_tmp
|
||||
mv ${APP}-${RELEASE}/ /opt/${APP}
|
||||
cd /opt/${APP}
|
||||
export PUPPETEER_SKIP_DOWNLOAD="true"
|
||||
export NEXT_TELEMETRY_DISABLED=1
|
||||
export CI="true"
|
||||
export NODE_ENV="production"
|
||||
$STD pnpm install --frozen-lockfile
|
||||
$STD pnpm run build
|
||||
$STD pnpm run prisma:generate
|
||||
mv /opt/rxresume.env /opt/${APP}/.env
|
||||
msg_ok "Updated $APP to v${RELEASE}"
|
||||
|
||||
msg_info "Updating Minio"
|
||||
systemctl stop minio
|
||||
cd /tmp
|
||||
curl -fsSL https://dl.min.io/server/minio/release/linux-amd64/minio.deb -o minio.deb
|
||||
$STD dpkg -i minio.deb
|
||||
msg_ok "Updated Minio"
|
||||
|
||||
msg_info "Updating Browserless (Patience)"
|
||||
systemctl stop browserless
|
||||
cp /opt/browserless/.env /opt/browserless.env
|
||||
rm -rf browserless
|
||||
brwsr_tmp=$(mktemp)
|
||||
TAG=$(curl -fsSL https://api.github.com/repos/browserless/browserless/tags?per_page=1 | grep "name" | awk '{print substr($2, 3, length($2)-4) }')
|
||||
curl -fsSL https://github.com/browserless/browserless/archive/refs/tags/v${TAG}.zip -O $brwsr_tmp
|
||||
unzip -q $brwsr_tmp
|
||||
mv browserless-${TAG}/ /opt/browserless
|
||||
cd /opt/browserless
|
||||
$STD npm install
|
||||
rm -rf src/routes/{chrome,edge,firefox,webkit}
|
||||
$STD node_modules/playwright-core/cli.js install --with-deps chromium
|
||||
$STD npm run build
|
||||
$STD npm run build:function
|
||||
$STD npm prune production
|
||||
mv /opt/browserless.env /opt/browserless/.env
|
||||
msg_ok "Updated Browserless"
|
||||
|
||||
msg_info "Restarting services"
|
||||
systemctl start minio Reactive-Resume browserless
|
||||
msg_ok "Restarted services"
|
||||
|
||||
msg_info "Cleaning Up"
|
||||
rm -f /tmp/minio.deb
|
||||
rm -f $brwsr_tmp
|
||||
rm -f $res_tmp
|
||||
msg_ok "Cleanup Completed"
|
||||
|
||||
echo "${RELEASE}" >/opt/${APP}_version.txt
|
||||
msg_ok "Update Successful"
|
||||
else
|
||||
msg_ok "No update required. ${APP} is already at v${RELEASE}"
|
||||
fi
|
||||
exit
|
||||
}
|
||||
|
||||
start
|
||||
build_container
|
||||
description
|
||||
|
||||
msg_ok "Completed Successfully!\n"
|
||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}"
|
@ -35,9 +35,10 @@ function update_script() {
|
||||
|
||||
msg_info "Updating $APP to v${RELEASE}"
|
||||
temp_file=$(mktemp)
|
||||
cd $temp_file
|
||||
curl -fsSL "https://github.com/wger-project/wger/archive/refs/tags/$RELEASE.tar.gz" -o "$temp_file"
|
||||
tar xzf "$temp_file"
|
||||
cp -rf wger-"$RELEASE"/* /home/wger/src
|
||||
tar xzf $temp_file
|
||||
cp -rf wger-$RELEASE/* /home/wger/src
|
||||
cd /home/wger/src
|
||||
python3 manage.py migrate &>/dev/null
|
||||
yarn install &>/dev/null
|
||||
@ -51,7 +52,7 @@ function update_script() {
|
||||
msg_ok "Started $APP"
|
||||
|
||||
msg_info "Cleaning Up"
|
||||
rm -rf "$temp_file"
|
||||
rm -rf $temp_file
|
||||
msg_ok "Cleanup Completed"
|
||||
|
||||
msg_ok "Update Successful"
|
||||
|
@ -1,9 +1,7 @@
|
||||
{
|
||||
"name": "Tailscale",
|
||||
"slug": "add-tailscale-lxc",
|
||||
"categories": [
|
||||
1
|
||||
],
|
||||
"categories": [1],
|
||||
"date_created": "2024-05-02",
|
||||
"type": "addon",
|
||||
"updateable": false,
|
||||
@ -40,7 +38,7 @@
|
||||
"type": "info"
|
||||
},
|
||||
{
|
||||
"text": "Execute within the Proxmox host shell",
|
||||
"text": "Execute within the Proxmox shell",
|
||||
"type": "info"
|
||||
}
|
||||
]
|
||||
|
@ -6,10 +6,10 @@
|
||||
],
|
||||
"date_created": "2024-05-02",
|
||||
"type": "ct",
|
||||
"updateable": true,
|
||||
"updateable": false,
|
||||
"privileged": false,
|
||||
"interface_port": 8090,
|
||||
"documentation": "https://github.com/qbittorrent/qBittorrent/wiki/",
|
||||
"documentation": null,
|
||||
"website": "https://www.qbittorrent.org/",
|
||||
"logo": "https://raw.githubusercontent.com/selfhst/icons/refs/heads/main/svg/qbittorrent.svg",
|
||||
"description": "qBittorrent offers a user-friendly interface that allows users to search for and download torrent files easily. It also supports magnet links, which allow users to start downloading files without the need for a torrent file.",
|
||||
|
@ -1,34 +0,0 @@
|
||||
{
|
||||
"name": "Reactive Resume",
|
||||
"slug": "reactive-resume",
|
||||
"categories": [
|
||||
12
|
||||
],
|
||||
"date_created": "2025-04-22",
|
||||
"type": "ct",
|
||||
"updateable": true,
|
||||
"privileged": false,
|
||||
"interface_port": 3000,
|
||||
"documentation": "https://docs.rxresu.me/",
|
||||
"website": "https://rxresu.me",
|
||||
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/png/reactive-resume-light.png",
|
||||
"description": "A one-of-a-kind resume builder that keeps your privacy in mind. Completely secure, customizable, portable, open-source and free forever.",
|
||||
"install_methods": [
|
||||
{
|
||||
"type": "default",
|
||||
"script": "ct/reactive-resume.sh",
|
||||
"resources": {
|
||||
"cpu": 2,
|
||||
"ram": 3072,
|
||||
"hdd": 8,
|
||||
"os": "Debian",
|
||||
"version": "12"
|
||||
}
|
||||
}
|
||||
],
|
||||
"default_credentials": {
|
||||
"username": null,
|
||||
"password": null
|
||||
},
|
||||
"notes": []
|
||||
}
|
@ -1,314 +1,114 @@
|
||||
[
|
||||
{
|
||||
"name": "fhem/fhem-mirror",
|
||||
"version": "6.2",
|
||||
"date": "2025-04-22T10:34:10Z"
|
||||
},
|
||||
{
|
||||
"name": "OctoPrint/OctoPrint",
|
||||
"version": "1.11.0",
|
||||
"date": "2025-04-22T09:33:46Z"
|
||||
},
|
||||
{
|
||||
"name": "n8n-io/n8n",
|
||||
"version": "n8n@1.86.1",
|
||||
"date": "2025-04-09T09:20:55Z"
|
||||
},
|
||||
{
|
||||
"name": "zabbix/zabbix",
|
||||
"version": "6.0.40",
|
||||
"date": "2025-04-22T08:43:35Z"
|
||||
},
|
||||
{
|
||||
"name": "Checkmk/checkmk",
|
||||
"version": "v2.4.0b6-rc1",
|
||||
"date": "2025-04-22T08:12:24Z"
|
||||
},
|
||||
{
|
||||
"name": "nzbgetcom/nzbget",
|
||||
"version": "v24.8",
|
||||
"date": "2025-03-18T07:33:51Z"
|
||||
},
|
||||
{
|
||||
"name": "openobserve/openobserve",
|
||||
"version": "v0.14.6-rc5",
|
||||
"date": "2025-04-22T06:50:13Z"
|
||||
},
|
||||
{
|
||||
"name": "mattermost/mattermost",
|
||||
"version": "v10.6.2",
|
||||
"date": "2025-04-15T08:14:23Z"
|
||||
},
|
||||
{
|
||||
"name": "morpheus65535/bazarr",
|
||||
"version": "v1.5.1",
|
||||
"date": "2025-01-01T16:15:52Z"
|
||||
},
|
||||
{
|
||||
"name": "firefly-iii/firefly-iii",
|
||||
"version": "v6.2.12",
|
||||
"date": "2025-04-20T19:22:17Z"
|
||||
},
|
||||
{
|
||||
"name": "Jackett/Jackett",
|
||||
"version": "v0.22.1809",
|
||||
"date": "2025-04-22T05:55:35Z"
|
||||
},
|
||||
{
|
||||
"name": "monicahq/monica",
|
||||
"version": "v4.1.2",
|
||||
"date": "2024-05-04T08:06:50Z"
|
||||
},
|
||||
{
|
||||
"name": "OliveTin/OliveTin",
|
||||
"version": "2025.4.21",
|
||||
"date": "2025-04-21T19:16:09Z"
|
||||
},
|
||||
{
|
||||
"name": "Suwayomi/Suwayomi-Server",
|
||||
"version": "v2.0.1727",
|
||||
"date": "2025-04-21T17:53:05Z"
|
||||
},
|
||||
{
|
||||
"name": "TasmoAdmin/TasmoAdmin",
|
||||
"version": "v4.3.0",
|
||||
"date": "2025-04-21T17:44:40Z"
|
||||
},
|
||||
{
|
||||
"name": "emqx/emqx",
|
||||
"version": "e5.9.0-beta.4",
|
||||
"date": "2025-04-21T17:08:59Z"
|
||||
},
|
||||
{
|
||||
"name": "runtipi/runtipi",
|
||||
"version": "v3.10.0-beta.9",
|
||||
"date": "2025-04-17T11:46:08Z"
|
||||
},
|
||||
{
|
||||
"name": "AdguardTeam/AdGuardHome",
|
||||
"version": "v0.107.60",
|
||||
"date": "2025-04-14T11:46:19Z"
|
||||
},
|
||||
{
|
||||
"name": "keycloak/keycloak",
|
||||
"version": "26.2.0",
|
||||
"date": "2025-04-11T12:48:27Z"
|
||||
},
|
||||
{
|
||||
"name": "cross-seed/cross-seed",
|
||||
"version": "v6.11.2",
|
||||
"date": "2025-02-26T14:54:49Z"
|
||||
},
|
||||
{
|
||||
"name": "Prowlarr/Prowlarr",
|
||||
"version": "v1.34.1.5021",
|
||||
"date": "2025-04-20T19:29:50Z"
|
||||
},
|
||||
{
|
||||
"name": "semaphoreui/semaphore",
|
||||
"version": "v2.13.14",
|
||||
"date": "2025-04-19T20:39:23Z"
|
||||
},
|
||||
{
|
||||
"name": "pocket-id/pocket-id",
|
||||
"version": "v0.49.0",
|
||||
"date": "2025-04-20T18:03:03Z"
|
||||
},
|
||||
{
|
||||
"name": "YunoHost/yunohost",
|
||||
"version": "debian/12.0.14",
|
||||
"date": "2025-04-09T10:09:00Z"
|
||||
},
|
||||
{
|
||||
"name": "Kareadita/Kavita",
|
||||
"version": "v0.8.6.2",
|
||||
"date": "2025-04-20T16:55:38Z"
|
||||
},
|
||||
{
|
||||
"name": "openhab/openhab-core",
|
||||
"version": "5.0.0.M2",
|
||||
"date": "2025-04-20T13:16:29Z"
|
||||
},
|
||||
{
|
||||
"name": "pocketbase/pocketbase",
|
||||
"version": "v0.27.1",
|
||||
"date": "2025-04-20T11:26:50Z"
|
||||
},
|
||||
{
|
||||
"name": "karakeep-app/karakeep",
|
||||
"version": "extension/v1.2.5",
|
||||
"date": "2025-04-20T10:19:06Z"
|
||||
},
|
||||
{
|
||||
"name": "MediaBrowser/Emby.Releases",
|
||||
"version": "4.8.11.0",
|
||||
"date": "2025-03-10T06:39:11Z"
|
||||
},
|
||||
{
|
||||
"name": "Readarr/Readarr",
|
||||
"version": "v2.0.0.4645",
|
||||
"date": "2017-03-07T18:56:06Z"
|
||||
},
|
||||
{
|
||||
"name": "Radarr/Radarr",
|
||||
"version": "v5.21.1.9799",
|
||||
"date": "2025-03-24T15:52:12Z"
|
||||
},
|
||||
{
|
||||
"name": "paperless-ngx/paperless-ngx",
|
||||
"version": "v2.15.3",
|
||||
"date": "2025-04-19T23:02:17Z"
|
||||
},
|
||||
{
|
||||
"name": "ellite/Wallos",
|
||||
"version": "v2.52.0",
|
||||
"date": "2025-04-19T20:36:50Z"
|
||||
},
|
||||
{
|
||||
"name": "msgbyte/tianji",
|
||||
"version": "v1.20.7",
|
||||
"date": "2025-04-19T20:35:09Z"
|
||||
},
|
||||
{
|
||||
"name": "theonedev/onedev",
|
||||
"version": "v11.8.7",
|
||||
"date": "2025-04-19T11:19:29Z"
|
||||
},
|
||||
{
|
||||
"name": "home-assistant/core",
|
||||
"version": "2025.4.3",
|
||||
"date": "2025-04-19T10:23:38Z"
|
||||
},
|
||||
{
|
||||
"name": "moghtech/komodo",
|
||||
"version": "v1.17.2",
|
||||
"date": "2025-04-19T06:56:25Z"
|
||||
},
|
||||
{
|
||||
"name": "ollama/ollama",
|
||||
"version": "v0.6.6-rc1",
|
||||
"date": "2025-04-17T01:56:29Z"
|
||||
},
|
||||
{
|
||||
"name": "caddyserver/caddy",
|
||||
"version": "v2.10.0",
|
||||
"date": "2025-04-18T20:46:28Z"
|
||||
},
|
||||
{
|
||||
"name": "homarr-labs/homarr",
|
||||
"version": "v1.17.0",
|
||||
"date": "2025-04-18T19:14:57Z"
|
||||
},
|
||||
{
|
||||
"name": "Paymenter/Paymenter",
|
||||
"version": "v1.0.4",
|
||||
"date": "2025-04-18T16:08:02Z"
|
||||
},
|
||||
{
|
||||
"name": "prometheus/prometheus",
|
||||
"version": "v3.3.0",
|
||||
"date": "2025-04-18T13:46:38Z"
|
||||
},
|
||||
{
|
||||
"name": "dgtlmoon/changedetection.io",
|
||||
"version": "0.49.15",
|
||||
"date": "2025-04-18T12:58:26Z"
|
||||
},
|
||||
{
|
||||
"name": "traefik/traefik",
|
||||
"version": "v3.3.6",
|
||||
"date": "2025-04-18T09:28:22Z"
|
||||
},
|
||||
{
|
||||
"name": "TandoorRecipes/recipes",
|
||||
"version": "1.5.34",
|
||||
"date": "2025-03-27T16:17:38Z"
|
||||
},
|
||||
{
|
||||
"name": "Luligu/matterbridge",
|
||||
"version": "2.2.9",
|
||||
"date": "2025-04-18T10:05:52Z"
|
||||
},
|
||||
{
|
||||
"name": "HabitRPG/habitica",
|
||||
"version": "v5.35.4",
|
||||
"date": "2025-04-17T21:18:55Z"
|
||||
},
|
||||
{
|
||||
"name": "tailscale/tailscale",
|
||||
"version": "v1.82.5",
|
||||
"date": "2025-04-17T20:59:15Z"
|
||||
},
|
||||
{
|
||||
"name": "TriliumNext/Notes",
|
||||
"version": "v0.93.0",
|
||||
"date": "2025-04-17T20:05:25Z"
|
||||
},
|
||||
{
|
||||
"name": "coder/code-server",
|
||||
"version": "v4.99.3",
|
||||
"date": "2025-04-17T18:33:11Z"
|
||||
},
|
||||
{
|
||||
"name": "VictoriaMetrics/VictoriaMetrics",
|
||||
"version": "v1.19.0-victorialogs",
|
||||
"date": "2025-04-17T18:26:31Z"
|
||||
},
|
||||
{
|
||||
"name": "duplicati/duplicati",
|
||||
"version": "v2.1.0.116-2.1.0.116_canary_2025-04-17",
|
||||
"date": "2025-04-17T17:52:31Z"
|
||||
},
|
||||
{
|
||||
"name": "benzino77/tasmocompiler",
|
||||
"version": "v12.6.1",
|
||||
"date": "2025-04-17T17:35:02Z"
|
||||
},
|
||||
{
|
||||
"name": "docker/compose",
|
||||
"version": "v2.35.1",
|
||||
"date": "2025-04-17T14:29:11Z"
|
||||
},
|
||||
{
|
||||
"name": "influxdata/influxdb",
|
||||
"version": "v3.0.1",
|
||||
"date": "2025-04-17T14:06:09Z"
|
||||
},
|
||||
{
|
||||
"name": "documenso/documenso",
|
||||
"version": "v1.10.0-rc.5",
|
||||
"date": "2025-04-17T13:01:43Z"
|
||||
},
|
||||
{
|
||||
"name": "prometheus-pve/prometheus-pve-exporter",
|
||||
"version": "v3.5.3",
|
||||
"date": "2025-04-17T10:40:47Z"
|
||||
},
|
||||
{
|
||||
"name": "fhem/fhem-mirror",
|
||||
"version": "6.2",
|
||||
"date": "2025-04-17T10:34:25Z"
|
||||
},
|
||||
{
|
||||
"name": "karakeep-app/karakeep",
|
||||
"version": "mcp/v0.23.6",
|
||||
"date": "2025-04-17T10:33:10Z"
|
||||
},
|
||||
{
|
||||
"name": "traefik/traefik",
|
||||
"version": "v2.11.23",
|
||||
"date": "2025-04-17T10:14:21Z"
|
||||
},
|
||||
{
|
||||
"name": "IceWhaleTech/CasaOS",
|
||||
"version": "v0.4.15",
|
||||
"date": "2024-12-19T03:19:49Z"
|
||||
},
|
||||
{
|
||||
"name": "morpheus65535/bazarr",
|
||||
"version": "v1.5.1",
|
||||
"date": "2025-01-01T16:15:52Z"
|
||||
},
|
||||
{
|
||||
"name": "Jackett/Jackett",
|
||||
"version": "v0.22.1788",
|
||||
"date": "2025-04-17T05:53:12Z"
|
||||
},
|
||||
{
|
||||
"name": "ollama/ollama",
|
||||
"version": "v0.6.6-rc1",
|
||||
"date": "2025-04-17T01:56:29Z"
|
||||
},
|
||||
{
|
||||
"name": "esphome/esphome",
|
||||
"version": "2025.4.0",
|
||||
"date": "2025-04-17T00:55:34Z"
|
||||
},
|
||||
{
|
||||
"name": "dgtlmoon/changedetection.io",
|
||||
"version": "0.49.14",
|
||||
"date": "2025-04-16T21:32:22Z"
|
||||
},
|
||||
{
|
||||
"name": "influxdata/influxdb",
|
||||
"version": "v3.0.0",
|
||||
"date": "2025-04-16T21:21:04Z"
|
||||
},
|
||||
{
|
||||
"name": "moghtech/komodo",
|
||||
"version": "v1.17.1",
|
||||
"date": "2025-04-14T22:35:13Z"
|
||||
},
|
||||
{
|
||||
"name": "docmost/docmost",
|
||||
"version": "v0.10.2",
|
||||
"date": "2025-04-16T20:43:40Z"
|
||||
},
|
||||
{
|
||||
"name": "keycloak/keycloak",
|
||||
"version": "26.2.0",
|
||||
"date": "2025-04-11T12:48:27Z"
|
||||
},
|
||||
{
|
||||
"name": "ellite/Wallos",
|
||||
"version": "v2.50.1",
|
||||
"date": "2025-04-16T19:31:56Z"
|
||||
},
|
||||
{
|
||||
"name": "forgejo/forgejo",
|
||||
"version": "v11.0.0",
|
||||
"date": "2025-04-16T19:25:53Z"
|
||||
},
|
||||
{
|
||||
"name": "openobserve/openobserve",
|
||||
"version": "v0.14.6-rc4",
|
||||
"date": "2025-04-16T18:28:51Z"
|
||||
},
|
||||
{
|
||||
"name": "element-hq/synapse",
|
||||
"version": "v1.129.0rc1",
|
||||
"date": "2025-04-16T15:18:13Z"
|
||||
},
|
||||
{
|
||||
"name": "nzbgetcom/nzbget",
|
||||
"version": "v24.8",
|
||||
"date": "2025-03-18T07:33:51Z"
|
||||
},
|
||||
{
|
||||
"name": "pocket-id/pocket-id",
|
||||
"version": "v0.47.0",
|
||||
"date": "2025-04-16T14:32:31Z"
|
||||
},
|
||||
{
|
||||
"name": "n8n-io/n8n",
|
||||
"version": "n8n@1.86.1",
|
||||
"date": "2025-04-09T09:20:55Z"
|
||||
},
|
||||
{
|
||||
"name": "jenkinsci/jenkins",
|
||||
"version": "jenkins-2.506",
|
||||
@ -316,14 +116,34 @@
|
||||
},
|
||||
{
|
||||
"name": "wazuh/wazuh",
|
||||
"version": "coverity-w17-4.12.0",
|
||||
"date": "2025-04-16T11:20:57Z"
|
||||
"version": "coverity-w16-4.12.0",
|
||||
"date": "2025-04-15T08:25:08Z"
|
||||
},
|
||||
{
|
||||
"name": "pocketbase/pocketbase",
|
||||
"version": "v0.27.0",
|
||||
"date": "2025-04-16T04:54:37Z"
|
||||
},
|
||||
{
|
||||
"name": "icereed/paperless-gpt",
|
||||
"version": "v0.15.0",
|
||||
"date": "2025-04-16T03:58:02Z"
|
||||
},
|
||||
{
|
||||
"name": "HabitRPG/habitica",
|
||||
"version": "v5.35.3",
|
||||
"date": "2025-04-15T19:32:17Z"
|
||||
},
|
||||
{
|
||||
"name": "Checkmk/checkmk",
|
||||
"version": "v2.4.0b5",
|
||||
"date": "2025-04-15T17:59:06Z"
|
||||
},
|
||||
{
|
||||
"name": "MediaBrowser/Emby.Releases",
|
||||
"version": "4.8.11.0",
|
||||
"date": "2025-03-10T06:39:11Z"
|
||||
},
|
||||
{
|
||||
"name": "rabbitmq/rabbitmq-server",
|
||||
"version": "v4.1.0",
|
||||
@ -344,6 +164,21 @@
|
||||
"version": "v0.45.6",
|
||||
"date": "2025-04-15T14:16:52Z"
|
||||
},
|
||||
{
|
||||
"name": "prometheus/prometheus",
|
||||
"version": "v0.303.0",
|
||||
"date": "2025-04-15T13:30:05Z"
|
||||
},
|
||||
{
|
||||
"name": "mattermost/mattermost",
|
||||
"version": "v10.6.2",
|
||||
"date": "2025-04-15T08:14:23Z"
|
||||
},
|
||||
{
|
||||
"name": "zabbix/zabbix",
|
||||
"version": "7.0.12rc1",
|
||||
"date": "2025-04-15T08:00:11Z"
|
||||
},
|
||||
{
|
||||
"name": "slskd/slskd",
|
||||
"version": "0.22.5",
|
||||
@ -354,11 +189,41 @@
|
||||
"version": "v0.14.1",
|
||||
"date": "2024-08-29T22:32:51Z"
|
||||
},
|
||||
{
|
||||
"name": "Kareadita/Kavita",
|
||||
"version": "v0.8.6",
|
||||
"date": "2025-04-14T22:09:30Z"
|
||||
},
|
||||
{
|
||||
"name": "paperless-ngx/paperless-ngx",
|
||||
"version": "v2.15.2",
|
||||
"date": "2025-04-14T20:48:52Z"
|
||||
},
|
||||
{
|
||||
"name": "semaphoreui/semaphore",
|
||||
"version": "v2.13.13",
|
||||
"date": "2025-04-11T10:15:13Z"
|
||||
},
|
||||
{
|
||||
"name": "netbox-community/netbox",
|
||||
"version": "v4.2.7",
|
||||
"date": "2025-04-10T20:08:13Z"
|
||||
},
|
||||
{
|
||||
"name": "duplicati/duplicati",
|
||||
"version": "v2.1.0.115-2.1.0.115_canary_2025-04-14",
|
||||
"date": "2025-04-14T18:03:36Z"
|
||||
},
|
||||
{
|
||||
"name": "OliveTin/OliveTin",
|
||||
"version": "2025.4.14",
|
||||
"date": "2025-04-14T16:53:53Z"
|
||||
},
|
||||
{
|
||||
"name": "msgbyte/tianji",
|
||||
"version": "v1.20.0",
|
||||
"date": "2025-04-14T16:19:23Z"
|
||||
},
|
||||
{
|
||||
"name": "home-assistant/operating-system",
|
||||
"version": "15.2",
|
||||
@ -369,6 +234,11 @@
|
||||
"version": "v0.0.7-hf1",
|
||||
"date": "2025-03-10T20:49:39Z"
|
||||
},
|
||||
{
|
||||
"name": "AdguardTeam/AdGuardHome",
|
||||
"version": "v0.107.60",
|
||||
"date": "2025-04-14T11:46:19Z"
|
||||
},
|
||||
{
|
||||
"name": "Graylog2/graylog2-server",
|
||||
"version": "6.2.0-rc.1",
|
||||
@ -394,6 +264,11 @@
|
||||
"version": "0.203.1",
|
||||
"date": "2025-04-14T07:23:02Z"
|
||||
},
|
||||
{
|
||||
"name": "firefly-iii/firefly-iii",
|
||||
"version": "v6.2.10",
|
||||
"date": "2025-03-22T13:02:26Z"
|
||||
},
|
||||
{
|
||||
"name": "glanceapp/glance",
|
||||
"version": "v0.7.12",
|
||||
@ -429,6 +304,21 @@
|
||||
"version": "v2.10.3.4602",
|
||||
"date": "2025-03-23T11:00:37Z"
|
||||
},
|
||||
{
|
||||
"name": "Readarr/Readarr",
|
||||
"version": "v2.0.0.4645",
|
||||
"date": "2017-03-07T18:56:06Z"
|
||||
},
|
||||
{
|
||||
"name": "Prowlarr/Prowlarr",
|
||||
"version": "v1.33.3.5008",
|
||||
"date": "2025-04-09T17:58:37Z"
|
||||
},
|
||||
{
|
||||
"name": "Radarr/Radarr",
|
||||
"version": "v5.21.1.9799",
|
||||
"date": "2025-03-24T15:52:12Z"
|
||||
},
|
||||
{
|
||||
"name": "Tautulli/Tautulli",
|
||||
"version": "v2.15.2",
|
||||
@ -439,6 +329,11 @@
|
||||
"version": "v0.2.11",
|
||||
"date": "2025-04-12T21:13:08Z"
|
||||
},
|
||||
{
|
||||
"name": "home-assistant/core",
|
||||
"version": "2025.4.2",
|
||||
"date": "2025-04-12T09:46:22Z"
|
||||
},
|
||||
{
|
||||
"name": "readeck/readeck",
|
||||
"version": "0.18.0",
|
||||
@ -449,6 +344,31 @@
|
||||
"version": "v5.5.2",
|
||||
"date": "2025-04-11T22:00:06Z"
|
||||
},
|
||||
{
|
||||
"name": "homarr-labs/homarr",
|
||||
"version": "v1.16.0",
|
||||
"date": "2025-04-11T19:15:24Z"
|
||||
},
|
||||
{
|
||||
"name": "tailscale/tailscale",
|
||||
"version": "v1.82.4",
|
||||
"date": "2025-04-11T17:58:09Z"
|
||||
},
|
||||
{
|
||||
"name": "coder/code-server",
|
||||
"version": "v4.99.2",
|
||||
"date": "2025-04-11T17:57:47Z"
|
||||
},
|
||||
{
|
||||
"name": "TriliumNext/Notes",
|
||||
"version": "v0.0.0",
|
||||
"date": "2025-04-11T14:18:00Z"
|
||||
},
|
||||
{
|
||||
"name": "emqx/emqx",
|
||||
"version": "e5.9.0-beta.3",
|
||||
"date": "2025-04-11T14:17:53Z"
|
||||
},
|
||||
{
|
||||
"name": "NLnetLabs/unbound",
|
||||
"version": "release-1.23.0rc2",
|
||||
@ -464,6 +384,11 @@
|
||||
"version": "v0.83.0",
|
||||
"date": "2025-04-11T03:53:10Z"
|
||||
},
|
||||
{
|
||||
"name": "Luligu/matterbridge",
|
||||
"version": "2.2.8",
|
||||
"date": "2025-04-10T20:30:49Z"
|
||||
},
|
||||
{
|
||||
"name": "gristlabs/grist-core",
|
||||
"version": "v1.5.1",
|
||||
@ -474,11 +399,26 @@
|
||||
"version": "cassandra-5.0.4",
|
||||
"date": "2025-04-10T16:32:00Z"
|
||||
},
|
||||
{
|
||||
"name": "VictoriaMetrics/VictoriaMetrics",
|
||||
"version": "v1.18.0-victorialogs",
|
||||
"date": "2025-04-10T15:05:20Z"
|
||||
},
|
||||
{
|
||||
"name": "NodeBB/NodeBB",
|
||||
"version": "v4.2.1",
|
||||
"date": "2025-04-10T14:03:47Z"
|
||||
},
|
||||
{
|
||||
"name": "Paymenter/Paymenter",
|
||||
"version": "v1.0.3",
|
||||
"date": "2025-04-10T13:57:39Z"
|
||||
},
|
||||
{
|
||||
"name": "docker/compose",
|
||||
"version": "v2.35.0",
|
||||
"date": "2025-04-10T13:45:22Z"
|
||||
},
|
||||
{
|
||||
"name": "mongodb/mongo",
|
||||
"version": "r8.0.5-rc2",
|
||||
@ -499,6 +439,11 @@
|
||||
"version": "v2.69.10",
|
||||
"date": "2025-04-09T12:16:51Z"
|
||||
},
|
||||
{
|
||||
"name": "YunoHost/yunohost",
|
||||
"version": "debian/12.0.14",
|
||||
"date": "2025-04-09T10:09:00Z"
|
||||
},
|
||||
{
|
||||
"name": "minio/minio",
|
||||
"version": "RELEASE.2025-04-08T15-41-24Z",
|
||||
@ -564,6 +509,11 @@
|
||||
"version": "2.0.3",
|
||||
"date": "2025-04-06T17:35:41Z"
|
||||
},
|
||||
{
|
||||
"name": "TandoorRecipes/recipes",
|
||||
"version": "1.5.34",
|
||||
"date": "2025-03-27T16:17:38Z"
|
||||
},
|
||||
{
|
||||
"name": "TechnitiumSoftware/DnsServer",
|
||||
"version": "v13.5.0",
|
||||
@ -629,6 +579,11 @@
|
||||
"version": "9.0.104",
|
||||
"date": "2025-04-04T12:58:11Z"
|
||||
},
|
||||
{
|
||||
"name": "OctoPrint/OctoPrint",
|
||||
"version": "1.10.3",
|
||||
"date": "2024-11-05T09:20:50Z"
|
||||
},
|
||||
{
|
||||
"name": "BookStackApp/BookStack",
|
||||
"version": "v25.02.2",
|
||||
@ -654,6 +609,11 @@
|
||||
"version": "v2.31.0",
|
||||
"date": "2025-04-01T18:12:45Z"
|
||||
},
|
||||
{
|
||||
"name": "theonedev/onedev",
|
||||
"version": "v11.8.6",
|
||||
"date": "2025-04-01T13:52:03Z"
|
||||
},
|
||||
{
|
||||
"name": "neo4j/neo4j",
|
||||
"version": "5.26.5",
|
||||
@ -669,6 +629,11 @@
|
||||
"version": "v2.2.0",
|
||||
"date": "2025-03-31T21:31:48Z"
|
||||
},
|
||||
{
|
||||
"name": "documenso/documenso",
|
||||
"version": "v1.10.0-rc.4",
|
||||
"date": "2025-03-31T09:02:22Z"
|
||||
},
|
||||
{
|
||||
"name": "mysql/mysql-server",
|
||||
"version": "mysql-cluster-9.3.0",
|
||||
@ -689,6 +654,11 @@
|
||||
"version": "v1.17.0",
|
||||
"date": "2025-03-30T14:21:53Z"
|
||||
},
|
||||
{
|
||||
"name": "openhab/openhab-core",
|
||||
"version": "4.3.4",
|
||||
"date": "2025-03-30T13:32:38Z"
|
||||
},
|
||||
{
|
||||
"name": "aceberg/WatchYourLAN",
|
||||
"version": "2.1.2-alpine",
|
||||
@ -709,6 +679,11 @@
|
||||
"version": "v1.6.1",
|
||||
"date": "2025-03-15T17:29:17Z"
|
||||
},
|
||||
{
|
||||
"name": "TasmoAdmin/TasmoAdmin",
|
||||
"version": "v4.2.3",
|
||||
"date": "2025-02-09T23:07:48Z"
|
||||
},
|
||||
{
|
||||
"name": "grocy/grocy",
|
||||
"version": "v4.5.0",
|
||||
@ -769,6 +744,11 @@
|
||||
"version": "v1.6.8",
|
||||
"date": "2025-03-25T13:33:10Z"
|
||||
},
|
||||
{
|
||||
"name": "caddyserver/caddy",
|
||||
"version": "v2.9.1",
|
||||
"date": "2025-01-08T15:22:53Z"
|
||||
},
|
||||
{
|
||||
"name": "ZoeyVid/NPMplus",
|
||||
"version": "2025-03-24-r2",
|
||||
@ -949,6 +929,11 @@
|
||||
"version": "v1.5.7",
|
||||
"date": "2025-02-27T20:04:08Z"
|
||||
},
|
||||
{
|
||||
"name": "cross-seed/cross-seed",
|
||||
"version": "v6.11.2",
|
||||
"date": "2025-02-26T14:54:49Z"
|
||||
},
|
||||
{
|
||||
"name": "silverbulletmd/silverbullet",
|
||||
"version": "0.10.4",
|
||||
@ -959,6 +944,11 @@
|
||||
"version": "v0.25.1",
|
||||
"date": "2025-02-25T17:30:48Z"
|
||||
},
|
||||
{
|
||||
"name": "benzino77/tasmocompiler",
|
||||
"version": "v12.5.0",
|
||||
"date": "2025-02-25T14:55:50Z"
|
||||
},
|
||||
{
|
||||
"name": "schlagmichdoch/PairDrop",
|
||||
"version": "v1.11.2",
|
||||
@ -1194,6 +1184,11 @@
|
||||
"version": "v3.3.21",
|
||||
"date": "2024-06-26T01:14:46Z"
|
||||
},
|
||||
{
|
||||
"name": "Suwayomi/Suwayomi-Server",
|
||||
"version": "v1.1.1",
|
||||
"date": "2024-06-15T17:23:48Z"
|
||||
},
|
||||
{
|
||||
"name": "Forceu/barcodebuddy",
|
||||
"version": "v1.8.1.8",
|
||||
@ -1229,6 +1224,11 @@
|
||||
"version": "1.0.0",
|
||||
"date": "2024-05-05T02:01:51Z"
|
||||
},
|
||||
{
|
||||
"name": "monicahq/monica",
|
||||
"version": "v4.1.2",
|
||||
"date": "2024-05-04T08:06:50Z"
|
||||
},
|
||||
{
|
||||
"name": "thelounge/thelounge-deb",
|
||||
"version": "v4.4.3",
|
||||
|
@ -24,8 +24,6 @@ const generateSourceUrl = (slug: string, type: string) => {
|
||||
return `${baseUrl}/tools/pve/${slug}.sh`;
|
||||
case "addon":
|
||||
return `${baseUrl}/tools/addon/${slug}.sh`;
|
||||
case "turnkey":
|
||||
return `${baseUrl}/turnkey/${slug}.sh`;
|
||||
default:
|
||||
return `${baseUrl}/ct/${slug}.sh`; // fallback for "ct"
|
||||
}
|
||||
|
@ -1,190 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright (c) 2021-2025 community-scripts ORG
|
||||
# Author: vhsdream
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://rxresu.me
|
||||
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
color
|
||||
verb_ip6
|
||||
catch_errors
|
||||
setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
|
||||
msg_info "Installing Dependencies"
|
||||
$STD apt-get install -y \
|
||||
gnupg \
|
||||
unzip \
|
||||
postgresql-common
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
msg_info "Installing Additional Dependencies"
|
||||
mkdir -p /etc/apt/keyrings
|
||||
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
|
||||
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_22.x nodistro main" >/etc/apt/sources.list.d/nodesource.list
|
||||
echo "YES" | /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh &>/dev/null
|
||||
$STD apt-get install -y postgresql-16 nodejs
|
||||
cd /tmp
|
||||
curl -fsSL https://dl.min.io/server/minio/release/linux-amd64/minio.deb -o minio.deb
|
||||
$STD dpkg -i minio.deb
|
||||
|
||||
msg_info "Setting up Database"
|
||||
DB_USER="rxresume"
|
||||
DB_NAME="rxresume"
|
||||
DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
|
||||
$STD sudo -u postgres psql -c "CREATE USER $DB_USER WITH ENCRYPTED PASSWORD '$DB_PASS';"
|
||||
$STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER ENCODING 'UTF8' TEMPLATE template0;"
|
||||
$STD sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE $DB_NAME to $DB_USER;"
|
||||
$STD sudo -u postgres psql -c "ALTER USER $DB_USER WITH SUPERUSER;"
|
||||
msg_ok "Set up Database"
|
||||
|
||||
msg_info "Installing ${APPLICATION}"
|
||||
MINIO_PASS=$(openssl rand -base64 48)
|
||||
ACCESS_TOKEN=$(openssl rand -base64 48)
|
||||
REFRESH_TOKEN=$(openssl rand -base64 48)
|
||||
CHROME_TOKEN=$(openssl rand -hex 32)
|
||||
LOCAL_IP=$(hostname -I | awk '{print $1}')
|
||||
TAG=$(curl -fsSL https://api.github.com/repos/browserless/browserless/tags?per_page=1 | grep "name" | awk '{print substr($2, 3, length($2)-4) }')
|
||||
RELEASE=$(curl -fsSL https://api.github.com/repos/AmruthPillai/Reactive-Resume/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
|
||||
curl -fsSL "https://github.com/AmruthPillai/Reactive-Resume/archive/refs/tags/v${RELEASE}.zip" -o v${RELEASE}.zip
|
||||
unzip -q v${RELEASE}.zip
|
||||
mv ${APPLICATION}-${RELEASE}/ /opt/${APPLICATION}
|
||||
cd /opt/${APPLICATION}
|
||||
corepack enable
|
||||
export CI="true"
|
||||
export PUPPETEER_SKIP_DOWNLOAD="true"
|
||||
export NODE_ENV="production"
|
||||
export NEXT_TELEMETRY_DISABLED=1
|
||||
$STD pnpm install --frozen-lockfile
|
||||
$STD pnpm run build
|
||||
$STD pnpm install --prod --frozen-lockfile
|
||||
$STD pnpm run prisma:generate
|
||||
msg_ok "Installed ${APPLICATION}"
|
||||
|
||||
msg_info "Installing Browserless (Patience)"
|
||||
cd /tmp
|
||||
curl -fsSL https://github.com/browserless/browserless/archive/refs/tags/v${TAG}.zip -o v${TAG}.zip
|
||||
unzip -q v${TAG}.zip
|
||||
mv browserless-${TAG} /opt/browserless
|
||||
cd /opt/browserless
|
||||
$STD npm install
|
||||
rm -rf src/routes/{chrome,edge,firefox,webkit}
|
||||
$STD node_modules/playwright-core/cli.js install --with-deps chromium
|
||||
$STD npm run build
|
||||
$STD npm run build:function
|
||||
$STD npm prune production
|
||||
msg_ok "Installed Browserless"
|
||||
|
||||
msg_info "Configuring applications"
|
||||
mkdir -p /opt/minio
|
||||
cat <<EOF >/opt/minio/.env
|
||||
MINIO_ROOT_USER="storageadmin"
|
||||
MINIO_ROOT_PASSWORD="${MINIO_PASS}"
|
||||
MINIO_VOLUMES=/opt/minio
|
||||
MINIO_OPTS="--address :9000 --console-address 127.0.0.1:9001"
|
||||
EOF
|
||||
cat <<EOF >/opt/${APPLICATION}/.env
|
||||
NODE_ENV=production
|
||||
PORT=3000
|
||||
PUBLIC_URL=http://${LOCAL_IP}:3000
|
||||
STORAGE_URL=http://${LOCAL_IP}:9000/rxresume
|
||||
DATABASE_URL=postgresql://${DB_USER}:${DB_PASS}@localhost:5432/${DB_NAME}?schema=public
|
||||
ACCESS_TOKEN_SECRET=${ACCESS_TOKEN}
|
||||
REFRESH_TOKEN_SECRET=${REFRESH_TOKEN}
|
||||
CHROME_PORT=8080
|
||||
CHROME_TOKEN=${CHROME_TOKEN}
|
||||
CHROME_URL=ws://localhost:8080
|
||||
CHROME_IGNORE_HTTPS_ERRORS=true
|
||||
MAIL_FROM=noreply@locahost
|
||||
# SMTP_URL=smtp://username:password@smtp.server.mail:587 #
|
||||
STORAGE_ENDPOINT=localhost
|
||||
STORAGE_PORT=9000
|
||||
STORAGE_REGION=us-east-1
|
||||
STORAGE_BUCKET=rxresume
|
||||
STORAGE_ACCESS_KEY=storageadmin
|
||||
STORAGE_SECRET_KEY=${MINIO_PASS}
|
||||
STORAGE_USE_SSL=false
|
||||
STORAGE_SKIP_BUCKET_CHECK=false
|
||||
|
||||
# GitHub (OAuth, Optional)
|
||||
# GITHUB_CLIENT_ID=
|
||||
# GITHUB_CLIENT_SECRET=
|
||||
# GITHUB_CALLBACK_URL=http://localhost:5173/api/auth/github/callback
|
||||
|
||||
# Google (OAuth, Optional)
|
||||
# GOOGLE_CLIENT_ID=
|
||||
# GOOGLE_CLIENT_SECRET=
|
||||
# GOOGLE_CALLBACK_URL=http://localhost:5173/api/auth/google/callback
|
||||
EOF
|
||||
cat <<EOF >/opt/browserless/.env
|
||||
DEBUG=browserless*,-**:verbose
|
||||
HOST=localhost
|
||||
PORT=8080
|
||||
TOKEN=${CHROME_TOKEN}
|
||||
EOF
|
||||
echo "${RELEASE}" >/opt/${APPLICATION}_version.txt
|
||||
{
|
||||
echo "${APPLICATION} Credentials"
|
||||
echo "Database User: $DB_USER"
|
||||
echo "Database Password: $DB_PASS"
|
||||
echo "Database Name: $DB_NAME"
|
||||
echo "Minio Root Password: ${MINIO_PASS}"
|
||||
} >>~/${APPLICATION}.creds
|
||||
msg_ok "Configured applications"
|
||||
|
||||
msg_info "Creating Services"
|
||||
mkdir -p /etc/systemd/system/minio.service.d/
|
||||
cat <<EOF >/etc/systemd/system/minio.service.d/override.conf
|
||||
[Service]
|
||||
User=root
|
||||
Group=root
|
||||
WorkingDirectory=/usr/local/bin
|
||||
EnvironmentFile=/opt/minio/.env
|
||||
EOF
|
||||
|
||||
cat <<EOF >/etc/systemd/system/${APPLICATION}.service
|
||||
[Unit]
|
||||
Description=${APPLICATION} Service
|
||||
After=network.target postgresql.service minio.service
|
||||
Wants=postgresql.service minio.service
|
||||
|
||||
[Service]
|
||||
WorkingDirectory=/opt/${APPLICATION}
|
||||
EnvironmentFile=/opt/${APPLICATION}/.env
|
||||
ExecStart=/usr/bin/pnpm run start
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
cat <<EOF >/etc/systemd/system/browserless.service
|
||||
[Unit]
|
||||
Description=Browserless service
|
||||
After=network.target ${APPLICATION}.service
|
||||
|
||||
[Service]
|
||||
WorkingDirectory=/opt/browserless
|
||||
EnvironmentFile=/opt/browserless/.env
|
||||
ExecStart=/usr/bin/npm run start
|
||||
Restart=unless-stopped
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
systemctl daemon-reload
|
||||
systemctl enable -q --now minio.service ${APPLICATION}.service browserless.service
|
||||
msg_ok "Created Services"
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
|
||||
msg_info "Cleaning up"
|
||||
rm -f /tmp/v${RELEASE}.zip
|
||||
rm -f /tmp/v${TAG}.zip
|
||||
rm -f /tmp/minio.deb
|
||||
$STD apt-get -y autoremove
|
||||
$STD apt-get -y autoclean
|
||||
msg_ok "Cleaned"
|
@ -16,8 +16,7 @@ update_os
|
||||
msg_info "Installing Dependencies"
|
||||
$STD apt-get install -y \
|
||||
make \
|
||||
gcc \
|
||||
gpg
|
||||
gcc
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
msg_info "Installing Golang"
|
||||
@ -44,8 +43,8 @@ msg_ok "Installed Node.js"
|
||||
msg_info "Setting up seelf. Patience"
|
||||
RELEASE=$(curl -fsSL https://api.github.com/repos/YuukanOO/seelf/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
|
||||
curl -fsSL "https://github.com/YuukanOO/seelf/archive/refs/tags/v${RELEASE}.tar.gz" -o $(basename "https://github.com/YuukanOO/seelf/archive/refs/tags/v${RELEASE}.tar.gz")
|
||||
tar -xzf v"${RELEASE}".tar.gz
|
||||
mv seelf-"${RELEASE}"/ /opt/seelf
|
||||
tar -xzf v${RELEASE}.tar.gz
|
||||
mv seelf-${RELEASE}/ /opt/seelf
|
||||
cd /opt/seelf
|
||||
$STD make build
|
||||
PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
|
||||
@ -85,8 +84,8 @@ customize
|
||||
|
||||
# Cleanup
|
||||
msg_info "Cleaning up"
|
||||
rm -f ~/v"${RELEASE}".tar.gz
|
||||
rm -f "$temp_file"
|
||||
rm -f ~/v${RELEASE}.tar.gz
|
||||
rm -f $temp_file
|
||||
$STD apt-get -y autoremove
|
||||
$STD apt-get -y autoclean
|
||||
msg_ok "Cleaned"
|
||||
|
@ -1,867 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright (c) 2021-2025 community-scripts ORG
|
||||
# Author: MickLesk (Canbiz) && Desert_Gamer
|
||||
# License: MIT
|
||||
# Source: https://github.com/gitsang/iptag
|
||||
|
||||
function header_info {
|
||||
clear
|
||||
cat <<"EOF"
|
||||
___ ____ _____
|
||||
|_ _| _ \ _ |_ _|_ _ __ _
|
||||
| || |_) (_) | |/ _` |/ _` |
|
||||
| || __/ _ | | (_| | (_| |
|
||||
|___|_| (_) |_|\__,_|\__, |
|
||||
|___/
|
||||
EOF
|
||||
}
|
||||
|
||||
clear
|
||||
header_info
|
||||
APP="IP-Tag"
|
||||
hostname=$(hostname)
|
||||
|
||||
# Farbvariablen
|
||||
YW=$(echo "\033[33m")
|
||||
GN=$(echo "\033[1;92m")
|
||||
RD=$(echo "\033[01;31m")
|
||||
CL=$(echo "\033[m")
|
||||
BFR="\\r\\033[K"
|
||||
HOLD=" "
|
||||
CM=" ✔️ ${CL}"
|
||||
CROSS=" ✖️ ${CL}"
|
||||
|
||||
# This function enables error handling in the script by setting options and defining a trap for the ERR signal.
|
||||
catch_errors() {
|
||||
set -Eeuo pipefail
|
||||
trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
|
||||
}
|
||||
|
||||
# This function is called when an error occurs. It receives the exit code, line number, and command that caused the error, and displays an error message.
|
||||
error_handler() {
|
||||
if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID >/dev/null; then
|
||||
kill $SPINNER_PID >/dev/null
|
||||
fi
|
||||
printf "\e[?25h"
|
||||
local exit_code="$?"
|
||||
local line_number="$1"
|
||||
local command="$2"
|
||||
local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}"
|
||||
echo -e "\n$error_message\n"
|
||||
}
|
||||
|
||||
# This function displays a spinner.
|
||||
spinner() {
|
||||
local frames=('⠋' '⠙' '⠹' '⠸' '⠼' '⠴' '⠦' '⠧' '⠇' '⠏')
|
||||
local spin_i=0
|
||||
local interval=0.1
|
||||
printf "\e[?25l"
|
||||
|
||||
local color="${YWB}"
|
||||
|
||||
while true; do
|
||||
printf "\r ${color}%s${CL}" "${frames[spin_i]}"
|
||||
spin_i=$(((spin_i + 1) % ${#frames[@]}))
|
||||
sleep "$interval"
|
||||
done
|
||||
}
|
||||
|
||||
# This function displays an informational message with a yellow color.
|
||||
msg_info() {
|
||||
local msg="$1"
|
||||
echo -ne "${TAB}${YW}${HOLD}${msg}${HOLD}"
|
||||
spinner &
|
||||
SPINNER_PID=$!
|
||||
}
|
||||
|
||||
# This function displays a success message with a green color.
|
||||
msg_ok() {
|
||||
if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID >/dev/null; then
|
||||
kill $SPINNER_PID >/dev/null
|
||||
fi
|
||||
printf "\e[?25h"
|
||||
local msg="$1"
|
||||
echo -e "${BFR}${CM}${GN}${msg}${CL}"
|
||||
}
|
||||
|
||||
# This function displays a error message with a red color.
|
||||
msg_error() {
|
||||
if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID >/dev/null; then
|
||||
kill $SPINNER_PID >/dev/null
|
||||
fi
|
||||
printf "\e[?25h"
|
||||
local msg="$1"
|
||||
echo -e "${BFR}${CROSS}${RD}${msg}${CL}"
|
||||
}
|
||||
|
||||
# Check if service exists
|
||||
check_service_exists() {
|
||||
if systemctl is-active --quiet iptag.service; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Migrate configuration from old path to new
|
||||
migrate_config() {
|
||||
local old_config="/opt/lxc-iptag"
|
||||
local new_config="/opt/iptag/iptag.conf"
|
||||
|
||||
if [[ -f "$old_config" ]]; then
|
||||
msg_info "Migrating configuration from old path"
|
||||
if cp "$old_config" "$new_config" &>/dev/null; then
|
||||
rm -rf "$old_config" &>/dev/null
|
||||
msg_ok "Configuration migrated and old config removed"
|
||||
else
|
||||
msg_error "Failed to migrate configuration"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Update existing installation
|
||||
update_installation() {
|
||||
msg_info "Updating IP-Tag Scripts"
|
||||
systemctl stop iptag.service &>/dev/null
|
||||
|
||||
# Create directory if it doesn't exist
|
||||
if [[ ! -d "/opt/iptag" ]]; then
|
||||
mkdir -p /opt/iptag
|
||||
fi
|
||||
|
||||
# Migrate config if needed
|
||||
migrate_config
|
||||
|
||||
# Update main script
|
||||
cat <<'EOF' >/opt/iptag/iptag
|
||||
#!/bin/bash
|
||||
# =============== CONFIGURATION =============== #
|
||||
readonly CONFIG_FILE="/opt/iptag/iptag.conf"
|
||||
readonly DEFAULT_TAG_FORMAT="full"
|
||||
readonly DEFAULT_CHECK_INTERVAL=60
|
||||
|
||||
# Load the configuration file if it exists
|
||||
if [ -f "$CONFIG_FILE" ]; then
|
||||
# shellcheck source=./iptag.conf
|
||||
source "$CONFIG_FILE"
|
||||
fi
|
||||
|
||||
# Convert IP to integer for comparison
|
||||
ip_to_int() {
|
||||
local ip="$1"
|
||||
local a b c d
|
||||
IFS=. read -r a b c d <<< "${ip}"
|
||||
echo "$((a << 24 | b << 16 | c << 8 | d))"
|
||||
}
|
||||
|
||||
# Check if IP is in CIDR
|
||||
ip_in_cidr() {
|
||||
local ip="$1" cidr="$2"
|
||||
ipcalc -c "$ip" "$cidr" >/dev/null 2>&1 || return 1
|
||||
|
||||
local network prefix ip_parts net_parts
|
||||
network=$(echo "$cidr" | cut -d/ -f1)
|
||||
prefix=$(echo "$cidr" | cut -d/ -f2)
|
||||
IFS=. read -r -a ip_parts <<< "$ip"
|
||||
IFS=. read -r -a net_parts <<< "$network"
|
||||
|
||||
case $prefix in
|
||||
8) [[ "${ip_parts[0]}" == "${net_parts[0]}" ]] ;;
|
||||
16) [[ "${ip_parts[0]}.${ip_parts[1]}" == "${net_parts[0]}.${net_parts[1]}" ]] ;;
|
||||
24) [[ "${ip_parts[0]}.${ip_parts[1]}.${ip_parts[2]}" == "${net_parts[0]}.${net_parts[1]}.${net_parts[2]}" ]] ;;
|
||||
32) [[ "$ip" == "$network" ]] ;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Format IP address according to the configuration
|
||||
format_ip_tag() {
|
||||
local ip="$1"
|
||||
local format="${TAG_FORMAT:-$DEFAULT_TAG_FORMAT}"
|
||||
|
||||
case "$format" in
|
||||
"last_octet") echo "${ip##*.}" ;;
|
||||
"last_two_octets") echo "${ip#*.*.}" ;;
|
||||
*) echo "$ip" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Check if IP is in any CIDRs
|
||||
ip_in_cidrs() {
|
||||
local ip="$1" cidrs="$2"
|
||||
[[ -z "$cidrs" ]] && return 1
|
||||
local IFS=' '
|
||||
for cidr in $cidrs; do ip_in_cidr "$ip" "$cidr" && return 0; done
|
||||
return 1
|
||||
}
|
||||
|
||||
# Check if IP is valid
|
||||
is_valid_ipv4() {
|
||||
local ip="$1"
|
||||
[[ "$ip" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]] || return 1
|
||||
|
||||
local IFS='.' parts
|
||||
read -ra parts <<< "$ip"
|
||||
for part in "${parts[@]}"; do
|
||||
(( part >= 0 && part <= 255 )) || return 1
|
||||
done
|
||||
return 0
|
||||
}
|
||||
|
||||
lxc_status_changed() {
|
||||
current_lxc_status=$(pct list 2>/dev/null)
|
||||
if [ "${last_lxc_status}" == "${current_lxc_status}" ]; then
|
||||
return 1
|
||||
else
|
||||
last_lxc_status="${current_lxc_status}"
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
vm_status_changed() {
|
||||
current_vm_status=$(qm list 2>/dev/null)
|
||||
if [ "${last_vm_status}" == "${current_vm_status}" ]; then
|
||||
return 1
|
||||
else
|
||||
last_vm_status="${current_vm_status}"
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
fw_net_interface_changed() {
|
||||
current_net_interface=$(ifconfig | grep "^fw")
|
||||
if [ "${last_net_interface}" == "${current_net_interface}" ]; then
|
||||
return 1
|
||||
else
|
||||
last_net_interface="${current_net_interface}"
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
# Get VM IPs using MAC addresses and ARP table
|
||||
get_vm_ips() {
|
||||
local vmid=$1 ips="" macs found_ip=false
|
||||
qm status "$vmid" 2>/dev/null | grep -q "status: running" || return
|
||||
|
||||
macs=$(qm config "$vmid" 2>/dev/null | grep -E 'net[0-9]+' | grep -oE '[a-fA-F0-9]{2}(:[a-fA-F0-9]{2}){5}')
|
||||
[[ -z "$macs" ]] && return
|
||||
|
||||
for mac in $macs; do
|
||||
local ip
|
||||
ip=$(arp -an 2>/dev/null | grep -i "$mac" | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}')
|
||||
[[ -n "$ip" ]] && { ips+="$ip "; found_ip=true; }
|
||||
done
|
||||
|
||||
if ! $found_ip; then
|
||||
local agent_ip
|
||||
agent_ip=$(qm agent "$vmid" network-get-interfaces 2>/dev/null | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' || true)
|
||||
[[ -n "$agent_ip" ]] && ips+="$agent_ip "
|
||||
fi
|
||||
|
||||
echo "${ips% }"
|
||||
}
|
||||
|
||||
# Update tags
|
||||
update_tags() {
|
||||
local type="$1" vmid="$2" config_cmd="pct"
|
||||
[[ "$type" == "vm" ]] && config_cmd="qm"
|
||||
|
||||
local current_ips_full
|
||||
if [[ "$type" == "lxc" ]]; then
|
||||
current_ips_full=$(lxc-info -n "${vmid}" -i 2>/dev/null | grep -E "^IP:" | awk '{print $2}')
|
||||
else
|
||||
current_ips_full=$(get_vm_ips "${vmid}")
|
||||
fi
|
||||
[[ -z "$current_ips_full" ]] && return
|
||||
|
||||
local current_tags=() next_tags=() current_ip_tags=()
|
||||
mapfile -t current_tags < <($config_cmd config "${vmid}" 2>/dev/null | grep tags | awk '{print $2}' | sed 's/;/\n/g')
|
||||
|
||||
# Separate IP and non-IP tags
|
||||
for tag in "${current_tags[@]}"; do
|
||||
if is_valid_ipv4 "${tag}" || [[ "$tag" =~ ^[0-9]+(\.[0-9]+)*$ ]]; then
|
||||
current_ip_tags+=("${tag}")
|
||||
else
|
||||
next_tags+=("${tag}")
|
||||
fi
|
||||
done
|
||||
|
||||
local formatted_ips=() needs_update=false added_ips=()
|
||||
for ip in ${current_ips_full}; do
|
||||
if is_valid_ipv4 "$ip" && ip_in_cidrs "$ip" "${CIDR_LIST[*]}"; then
|
||||
local formatted_ip=$(format_ip_tag "$ip")
|
||||
formatted_ips+=("$formatted_ip")
|
||||
if [[ ! " ${current_ip_tags[*]} " =~ " ${formatted_ip} " ]]; then
|
||||
needs_update=true
|
||||
added_ips+=("$formatted_ip")
|
||||
next_tags+=("$formatted_ip")
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
[[ ${#formatted_ips[@]} -eq 0 ]] && return
|
||||
|
||||
# Add existing IP tags that are still valid
|
||||
for tag in "${current_ip_tags[@]}"; do
|
||||
if [[ " ${formatted_ips[*]} " =~ " ${tag} " ]]; then
|
||||
if [[ ! " ${next_tags[*]} " =~ " ${tag} " ]]; then
|
||||
next_tags+=("$tag")
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ "$needs_update" == true ]]; then
|
||||
echo "${type^} ${vmid}: adding IP tags: ${added_ips[*]}"
|
||||
$config_cmd set "${vmid}" -tags "$(IFS=';'; echo "${next_tags[*]}")" &>/dev/null
|
||||
elif [[ ${#current_ip_tags[@]} -gt 0 ]]; then
|
||||
echo "${type^} ${vmid}: IP tags already set: ${current_ip_tags[*]}"
|
||||
else
|
||||
echo "${type^} ${vmid}: setting initial IP tags: ${formatted_ips[*]}"
|
||||
$config_cmd set "${vmid}" -tags "$(IFS=';'; echo "${formatted_ips[*]}")" &>/dev/null
|
||||
fi
|
||||
}
|
||||
|
||||
# Check if status changed
|
||||
check_status() {
|
||||
local type="$1" current
|
||||
case "$type" in
|
||||
"lxc") current=$(pct list 2>/dev/null | grep -v VMID) ;;
|
||||
"vm") current=$(qm list 2>/dev/null | grep -v VMID) ;;
|
||||
"fw") current=$(ifconfig 2>/dev/null | grep "^fw") ;;
|
||||
esac
|
||||
local last_var="last_${type}_status"
|
||||
[[ "${!last_var}" == "$current" ]] && return 1
|
||||
eval "$last_var='$current'"
|
||||
return 0
|
||||
}
|
||||
|
||||
# Update all instances
|
||||
update_all() {
|
||||
local type="$1" list_cmd="pct" vmids count=0
|
||||
[[ "$type" == "vm" ]] && list_cmd="qm"
|
||||
|
||||
vmids=$($list_cmd list 2>/dev/null | grep -v VMID | awk '{print $1}')
|
||||
for vmid in $vmids; do ((count++)); done
|
||||
|
||||
echo "Found ${count} running ${type}s"
|
||||
[[ $count -eq 0 ]] && return
|
||||
|
||||
for vmid in $vmids; do
|
||||
update_tags "$type" "$vmid"
|
||||
done
|
||||
}
|
||||
|
||||
# Main check function
|
||||
check() {
|
||||
local current_time changes_detected=false
|
||||
current_time=$(date +%s)
|
||||
|
||||
for type in "lxc" "vm"; do
|
||||
local interval_var="${type^^}_STATUS_CHECK_INTERVAL"
|
||||
local last_check_var="last_${type}_check_time"
|
||||
local last_update_var="last_update_${type}_time"
|
||||
|
||||
if [[ "${!interval_var}" -gt 0 ]] && (( current_time - ${!last_check_var} >= ${!interval_var} )); then
|
||||
echo "Checking ${type^^} status..."
|
||||
eval "${last_check_var}=\$current_time"
|
||||
if check_status "$type"; then
|
||||
changes_detected=true
|
||||
update_all "$type"
|
||||
eval "${last_update_var}=\$current_time"
|
||||
fi
|
||||
fi
|
||||
|
||||
if (( current_time - ${!last_update_var} >= FORCE_UPDATE_INTERVAL )); then
|
||||
echo "Force updating ${type} tags..."
|
||||
changes_detected=true
|
||||
update_all "$type"
|
||||
eval "${last_update_var}=\$current_time"
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ "${FW_NET_INTERFACE_CHECK_INTERVAL}" -gt 0 ]] && \
|
||||
(( current_time - last_fw_check_time >= FW_NET_INTERFACE_CHECK_INTERVAL )); then
|
||||
echo "Checking network interfaces..."
|
||||
last_fw_check_time=$current_time
|
||||
if check_status "fw"; then
|
||||
changes_detected=true
|
||||
update_all "lxc"
|
||||
update_all "vm"
|
||||
last_update_lxc_time=$current_time
|
||||
last_update_vm_time=$current_time
|
||||
fi
|
||||
fi
|
||||
|
||||
$changes_detected || echo "No changes detected in system status"
|
||||
}
|
||||
|
||||
# Initialize time variables
|
||||
declare -g last_lxc_status="" last_vm_status="" last_fw_status=""
|
||||
declare -g last_lxc_check_time=0 last_vm_check_time=0 last_fw_check_time=0
|
||||
declare -g last_update_lxc_time=0 last_update_vm_time=0
|
||||
|
||||
# Main loop
|
||||
main() {
|
||||
while true; do
|
||||
check
|
||||
sleep "${LOOP_INTERVAL:-$DEFAULT_CHECK_INTERVAL}"
|
||||
done
|
||||
}
|
||||
|
||||
main
|
||||
EOF
|
||||
chmod +x /opt/iptag/iptag
|
||||
|
||||
# Update service file
|
||||
cat <<EOF >/lib/systemd/system/iptag.service
|
||||
[Unit]
|
||||
Description=IP-Tag service
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/opt/iptag/iptag
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
systemctl daemon-reload &>/dev/null
|
||||
systemctl enable -q --now iptag.service &>/dev/null
|
||||
msg_ok "Updated IP-Tag Scripts"
|
||||
}
|
||||
|
||||
# Main installation process
|
||||
if check_service_exists; then
|
||||
while true; do
|
||||
read -p "IP-Tag service is already installed. Do you want to update it? (y/n): " yn
|
||||
case $yn in
|
||||
[Yy]*)
|
||||
update_installation
|
||||
exit 0
|
||||
;;
|
||||
[Nn]*)
|
||||
msg_error "Installation cancelled."
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
msg_error "Please answer yes or no."
|
||||
;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
|
||||
while true; do
|
||||
read -p "This will install ${APP} on ${hostname}. Proceed? (y/n): " yn
|
||||
case $yn in
|
||||
[Yy]*)
|
||||
break
|
||||
;;
|
||||
[Nn]*)
|
||||
msg_error "Installation cancelled."
|
||||
exit
|
||||
;;
|
||||
*)
|
||||
msg_error "Please answer yes or no."
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if ! pveversion | grep -Eq "pve-manager/8\.[0-4](\.[0-9]+)*"; then
|
||||
msg_error "This version of Proxmox Virtual Environment is not supported"
|
||||
msg_error "⚠️ Requires Proxmox Virtual Environment Version 8.0 or later."
|
||||
msg_error "Exiting..."
|
||||
sleep 2
|
||||
exit
|
||||
fi
|
||||
|
||||
FILE_PATH="/usr/local/bin/iptag"
|
||||
if [[ -f "$FILE_PATH" ]]; then
|
||||
msg_info "The file already exists: '$FILE_PATH'. Skipping installation."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
msg_info "Installing Dependencies"
|
||||
apt-get update &>/dev/null
|
||||
apt-get install -y ipcalc net-tools &>/dev/null
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
msg_info "Setting up IP-Tag Scripts"
|
||||
mkdir -p /opt/iptag
|
||||
msg_ok "Setup IP-Tag Scripts"
|
||||
|
||||
# Migrate config if needed
|
||||
migrate_config
|
||||
|
||||
msg_info "Setup Default Config"
|
||||
if [[ ! -f /opt/iptag/iptag.conf ]]; then
|
||||
cat <<EOF >/opt/iptag/iptag.conf
|
||||
# Configuration file for LXC IP tagging
|
||||
|
||||
# List of allowed CIDRs
|
||||
CIDR_LIST=(
|
||||
192.168.0.0/16
|
||||
172.16.0.0/12
|
||||
10.0.0.0/8
|
||||
100.64.0.0/10
|
||||
)
|
||||
|
||||
# Tag format options:
|
||||
# - "full": full IP address (e.g., 192.168.0.100)
|
||||
# - "last_octet": only the last octet (e.g., 100)
|
||||
# - "last_two_octets": last two octets (e.g., 0.100)
|
||||
TAG_FORMAT="full"
|
||||
|
||||
# Interval settings (in seconds)
|
||||
LOOP_INTERVAL=60
|
||||
VM_STATUS_CHECK_INTERVAL=60
|
||||
FW_NET_INTERFACE_CHECK_INTERVAL=60
|
||||
LXC_STATUS_CHECK_INTERVAL=60
|
||||
FORCE_UPDATE_INTERVAL=1800
|
||||
EOF
|
||||
msg_ok "Setup default config"
|
||||
else
|
||||
msg_ok "Default config already exists"
|
||||
fi
|
||||
|
||||
msg_info "Setup Main Function"
|
||||
if [[ ! -f /opt/iptag/iptag ]]; then
|
||||
cat <<'EOF' >/opt/iptag/iptag
|
||||
#!/bin/bash
|
||||
# =============== CONFIGURATION =============== #
|
||||
CONFIG_FILE="/opt/iptag/iptag.conf"
|
||||
|
||||
# Load the configuration file if it exists
|
||||
if [ -f "$CONFIG_FILE" ]; then
|
||||
# shellcheck source=./iptag.conf
|
||||
source "$CONFIG_FILE"
|
||||
fi
|
||||
|
||||
# Convert IP to integer for comparison
|
||||
ip_to_int() {
|
||||
local ip="$1"
|
||||
local a b c d
|
||||
IFS=. read -r a b c d <<< "${ip}"
|
||||
echo "$((a << 24 | b << 16 | c << 8 | d))"
|
||||
}
|
||||
|
||||
# Check if IP is in CIDR
|
||||
ip_in_cidr() {
|
||||
local ip="$1"
|
||||
local cidr="$2"
|
||||
|
||||
# Use ipcalc with the -c option (check), which returns 0 if the IP is in the network
|
||||
if ipcalc -c "$ip" "$cidr" >/dev/null 2>&1; then
|
||||
# Get network address and mask from CIDR
|
||||
local network prefix
|
||||
network=$(echo "$cidr" | cut -d/ -f1)
|
||||
prefix=$(echo "$cidr" | cut -d/ -f2)
|
||||
|
||||
# Check if IP is in the network
|
||||
local ip_a ip_b ip_c ip_d net_a net_b net_c net_d
|
||||
IFS=. read -r ip_a ip_b ip_c ip_d <<< "$ip"
|
||||
IFS=. read -r net_a net_b net_c net_d <<< "$network"
|
||||
|
||||
# Check octets match based on prefix length
|
||||
local result=0
|
||||
if (( prefix >= 8 )); then
|
||||
[[ "$ip_a" != "$net_a" ]] && result=1
|
||||
fi
|
||||
if (( prefix >= 16 )); then
|
||||
[[ "$ip_b" != "$net_b" ]] && result=1
|
||||
fi
|
||||
if (( prefix >= 24 )); then
|
||||
[[ "$ip_c" != "$net_c" ]] && result=1
|
||||
fi
|
||||
|
||||
return $result
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
# Format IP address according to the configuration
|
||||
format_ip_tag() {
|
||||
local ip="$1"
|
||||
local format="${TAG_FORMAT:-full}"
|
||||
|
||||
case "$format" in
|
||||
"last_octet")
|
||||
echo "${ip##*.}"
|
||||
;;
|
||||
"last_two_octets")
|
||||
echo "${ip#*.*.}"
|
||||
;;
|
||||
*)
|
||||
echo "$ip"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Check if IP is in any CIDRs
|
||||
ip_in_cidrs() {
|
||||
local ip="$1"
|
||||
local cidrs="$2"
|
||||
|
||||
# Check that cidrs is not empty
|
||||
[[ -z "$cidrs" ]] && return 1
|
||||
|
||||
local IFS=' '
|
||||
for cidr in $cidrs; do
|
||||
ip_in_cidr "$ip" "$cidr" && return 0
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
# Check if IP is valid
|
||||
is_valid_ipv4() {
|
||||
local ip="$1"
|
||||
[[ "$ip" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]] || return 1
|
||||
local IFS='.'
|
||||
read -ra parts <<< "$ip"
|
||||
for part in "${parts[@]}"; do
|
||||
[[ "$part" =~ ^[0-9]+$ ]] && ((part >= 0 && part <= 255)) || return 1
|
||||
done
|
||||
return 0
|
||||
}
|
||||
|
||||
lxc_status_changed() {
|
||||
current_lxc_status=$(pct list 2>/dev/null)
|
||||
if [ "${last_lxc_status}" == "${current_lxc_status}" ]; then
|
||||
return 1
|
||||
else
|
||||
last_lxc_status="${current_lxc_status}"
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
vm_status_changed() {
|
||||
current_vm_status=$(qm list 2>/dev/null)
|
||||
if [ "${last_vm_status}" == "${current_vm_status}" ]; then
|
||||
return 1
|
||||
else
|
||||
last_vm_status="${current_vm_status}"
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
fw_net_interface_changed() {
|
||||
current_net_interface=$(ifconfig | grep "^fw")
|
||||
if [ "${last_net_interface}" == "${current_net_interface}" ]; then
|
||||
return 1
|
||||
else
|
||||
last_net_interface="${current_net_interface}"
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
# Get VM IPs using MAC addresses and ARP table
|
||||
get_vm_ips() {
|
||||
local vmid=$1
|
||||
local ips=""
|
||||
|
||||
# Check if VM is running
|
||||
qm status "$vmid" 2>/dev/null | grep -q "status: running" || return
|
||||
|
||||
# Get MAC addresses from VM configuration
|
||||
local macs
|
||||
macs=$(qm config "$vmid" 2>/dev/null | grep -E 'net[0-9]+' | grep -o -E '[a-fA-F0-9]{2}(:[a-fA-F0-9]{2}){5}')
|
||||
|
||||
# Look up IPs from ARP table using MAC addresses
|
||||
for mac in $macs; do
|
||||
local ip
|
||||
ip=$(arp -an 2>/dev/null | grep -i "$mac" | grep -o -E '([0-9]{1,3}\.){3}[0-9]{1,3}')
|
||||
if [ -n "$ip" ]; then
|
||||
ips+="$ip "
|
||||
fi
|
||||
done
|
||||
|
||||
echo "$ips"
|
||||
}
|
||||
|
||||
# Update tags for container or VM
|
||||
update_tags() {
|
||||
local type="$1"
|
||||
local vmid="$2"
|
||||
local config_cmd="pct"
|
||||
[[ "$type" == "vm" ]] && config_cmd="qm"
|
||||
|
||||
# Get current IPs
|
||||
local current_ips_full
|
||||
if [[ "$type" == "lxc" ]]; then
|
||||
# Redirect error output to suppress AppArmor warnings
|
||||
current_ips_full=$(lxc-info -n "${vmid}" -i 2>/dev/null | grep -E "^IP:" | awk '{print $2}')
|
||||
else
|
||||
current_ips_full=$(get_vm_ips "${vmid}")
|
||||
fi
|
||||
|
||||
# Parse current tags and get valid IPs
|
||||
local current_tags=()
|
||||
local next_tags=()
|
||||
mapfile -t current_tags < <($config_cmd config "${vmid}" 2>/dev/null | grep tags | awk '{print $2}' | sed 's/;/\n/g')
|
||||
|
||||
for tag in "${current_tags[@]}"; do
|
||||
# Skip tag if it looks like an IP (full or partial)
|
||||
if ! is_valid_ipv4 "${tag}" && ! [[ "$tag" =~ ^[0-9]+(\.[0-9]+)*$ ]]; then
|
||||
next_tags+=("${tag}")
|
||||
fi
|
||||
done
|
||||
|
||||
# Add valid IPs to tags
|
||||
local added_ips=()
|
||||
local skipped_ips=()
|
||||
|
||||
for ip in ${current_ips_full}; do
|
||||
if is_valid_ipv4 "${ip}"; then
|
||||
if ip_in_cidrs "${ip}" "${CIDR_LIST[*]}"; then
|
||||
local formatted_ip=$(format_ip_tag "$ip")
|
||||
next_tags+=("${formatted_ip}")
|
||||
added_ips+=("${formatted_ip}")
|
||||
else
|
||||
skipped_ips+=("${ip}")
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# Log only if there are changes
|
||||
if [ ${#added_ips[@]} -gt 0 ]; then
|
||||
echo "${type^} ${vmid}: added IP tags: ${added_ips[*]}"
|
||||
fi
|
||||
|
||||
# Update if changed
|
||||
if [[ "$(IFS=';'; echo "${current_tags[*]}")" != "$(IFS=';'; echo "${next_tags[*]}")" ]]; then
|
||||
$config_cmd set "${vmid}" -tags "$(IFS=';'; echo "${next_tags[*]}")" &>/dev/null
|
||||
fi
|
||||
}
|
||||
|
||||
# Check if status changed
|
||||
check_status_changed() {
|
||||
local type="$1"
|
||||
local current_status
|
||||
|
||||
case "$type" in
|
||||
"lxc")
|
||||
current_status=$(pct list 2>/dev/null | grep -v VMID)
|
||||
[[ "${last_lxc_status}" == "${current_status}" ]] && return 1
|
||||
last_lxc_status="${current_status}"
|
||||
;;
|
||||
"vm")
|
||||
current_status=$(qm list 2>/dev/null | grep -v VMID)
|
||||
[[ "${last_vm_status}" == "${current_status}" ]] && return 1
|
||||
last_vm_status="${current_status}"
|
||||
;;
|
||||
"fw")
|
||||
current_status=$(ifconfig 2>/dev/null | grep "^fw")
|
||||
[[ "${last_net_interface}" == "${current_status}" ]] && return 1
|
||||
last_net_interface="${current_status}"
|
||||
;;
|
||||
esac
|
||||
return 0
|
||||
}
|
||||
|
||||
check() {
|
||||
current_time=$(date +%s)
|
||||
|
||||
# Check LXC status
|
||||
time_since_last_lxc_status_check=$((current_time - last_lxc_status_check_time))
|
||||
if [[ "${LXC_STATUS_CHECK_INTERVAL}" -gt 0 ]] \
|
||||
&& [[ "${time_since_last_lxc_status_check}" -ge "${LXC_STATUS_CHECK_INTERVAL}" ]]; then
|
||||
echo "Checking LXC status..."
|
||||
last_lxc_status_check_time=${current_time}
|
||||
if check_status_changed "lxc"; then
|
||||
update_all_tags "lxc"
|
||||
last_update_lxc_time=${current_time}
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check VM status
|
||||
time_since_last_vm_status_check=$((current_time - last_vm_status_check_time))
|
||||
if [[ "${VM_STATUS_CHECK_INTERVAL}" -gt 0 ]] \
|
||||
&& [[ "${time_since_last_vm_status_check}" -ge "${VM_STATUS_CHECK_INTERVAL}" ]]; then
|
||||
echo "Checking VM status..."
|
||||
last_vm_status_check_time=${current_time}
|
||||
if check_status_changed "vm"; then
|
||||
update_all_tags "vm"
|
||||
last_update_vm_time=${current_time}
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check network interface changes
|
||||
time_since_last_fw_net_interface_check=$((current_time - last_fw_net_interface_check_time))
|
||||
if [[ "${FW_NET_INTERFACE_CHECK_INTERVAL}" -gt 0 ]] \
|
||||
&& [[ "${time_since_last_fw_net_interface_check}" -ge "${FW_NET_INTERFACE_CHECK_INTERVAL}" ]]; then
|
||||
echo "Checking network interfaces..."
|
||||
last_fw_net_interface_check_time=${current_time}
|
||||
if check_status_changed "fw"; then
|
||||
update_all_tags "lxc"
|
||||
update_all_tags "vm"
|
||||
last_update_lxc_time=${current_time}
|
||||
last_update_vm_time=${current_time}
|
||||
fi
|
||||
fi
|
||||
|
||||
# Force update if needed
|
||||
for type in "lxc" "vm"; do
|
||||
local last_update_var="last_update_${type}_time"
|
||||
local time_since_last_update=$((current_time - ${!last_update_var}))
|
||||
if [ ${time_since_last_update} -ge ${FORCE_UPDATE_INTERVAL} ]; then
|
||||
echo "Force updating ${type} tags..."
|
||||
update_all_tags "$type"
|
||||
eval "${last_update_var}=${current_time}"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# Initialize time variables
|
||||
last_lxc_status_check_time=0
|
||||
last_vm_status_check_time=0
|
||||
last_fw_net_interface_check_time=0
|
||||
last_update_lxc_time=0
|
||||
last_update_vm_time=0
|
||||
|
||||
# main: Set the IP tags for all LXC containers and VMs
|
||||
main() {
|
||||
while true; do
|
||||
check
|
||||
sleep "${LOOP_INTERVAL}"
|
||||
done
|
||||
}
|
||||
|
||||
main
|
||||
EOF
|
||||
msg_ok "Setup Main Function"
|
||||
else
|
||||
msg_ok "Main Function already exists"
|
||||
fi
|
||||
chmod +x /opt/iptag/iptag
|
||||
|
||||
msg_info "Creating Service"
|
||||
if [[ ! -f /lib/systemd/system/iptag.service ]]; then
|
||||
cat <<EOF >/lib/systemd/system/iptag.service
|
||||
[Unit]
|
||||
Description=IP-Tag service
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/opt/iptag/iptag
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
msg_ok "Created Service"
|
||||
else
|
||||
msg_ok "Service already exists."
|
||||
fi
|
||||
|
||||
msg_ok "Setup IP-Tag Scripts"
|
||||
|
||||
msg_info "Starting Service"
|
||||
systemctl daemon-reload &>/dev/null
|
||||
systemctl enable -q --now iptag.service &>/dev/null
|
||||
msg_ok "Started Service"
|
||||
SPINNER_PID=""
|
||||
echo -e "\n${APP} installation completed successfully! ${CL}\n"
|
Loading…
x
Reference in New Issue
Block a user