mirror of
https://github.com/community-scripts/ProxmoxVE.git
synced 2026-03-03 17:35:55 +01:00
Compare commits
2 Commits
add-script
...
exit_code_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ee74c8f158 | ||
|
|
7dbb0a75ef |
173
.github/workflows/push-json-to-pocketbase.yml
generated
vendored
173
.github/workflows/push-json-to-pocketbase.yml
generated
vendored
@@ -1,173 +0,0 @@
|
|||||||
name: Push JSON changes to PocketBase
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
paths:
|
|
||||||
- "frontend/public/json/**"
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
push-json:
|
|
||||||
runs-on: self-hosted
|
|
||||||
steps:
|
|
||||||
- name: Checkout Repository
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Get changed JSON files with slug
|
|
||||||
id: changed
|
|
||||||
run: |
|
|
||||||
changed=$(git diff --name-only "${{ github.event.before }}" "${{ github.event.after }}" -- frontend/public/json/ | grep '\.json$' || true)
|
|
||||||
with_slug=""
|
|
||||||
for f in $changed; do
|
|
||||||
[[ -f "$f" ]] || continue
|
|
||||||
jq -e '.slug' "$f" >/dev/null 2>&1 && with_slug="$with_slug $f"
|
|
||||||
done
|
|
||||||
with_slug=$(echo $with_slug | xargs -n1)
|
|
||||||
if [[ -z "$with_slug" ]]; then
|
|
||||||
echo "No app JSON files changed (or no files with slug)."
|
|
||||||
echo "count=0" >> "$GITHUB_OUTPUT"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
echo "$with_slug" > changed_app_jsons.txt
|
|
||||||
echo "count=$(echo "$with_slug" | wc -w)" >> "$GITHUB_OUTPUT"
|
|
||||||
|
|
||||||
- name: Push to PocketBase
|
|
||||||
if: steps.changed.outputs.count != '0'
|
|
||||||
env:
|
|
||||||
POCKETBASE_URL: ${{ secrets.POCKETBASE_URL }}
|
|
||||||
POCKETBASE_COLLECTION: ${{ secrets.POCKETBASE_COLLECTION }}
|
|
||||||
POCKETBASE_ADMIN_EMAIL: ${{ secrets.POCKETBASE_ADMIN_EMAIL }}
|
|
||||||
POCKETBASE_ADMIN_PASSWORD: ${{ secrets.POCKETBASE_ADMIN_PASSWORD }}
|
|
||||||
run: |
|
|
||||||
node << 'ENDSCRIPT'
|
|
||||||
(async function() {
|
|
||||||
const fs = require('fs');
|
|
||||||
const https = require('https');
|
|
||||||
const http = require('http');
|
|
||||||
const url = require('url');
|
|
||||||
function request(fullUrl, opts) {
|
|
||||||
return new Promise(function(resolve, reject) {
|
|
||||||
const u = url.parse(fullUrl);
|
|
||||||
const isHttps = u.protocol === 'https:';
|
|
||||||
const body = opts.body;
|
|
||||||
const options = {
|
|
||||||
hostname: u.hostname,
|
|
||||||
port: u.port || (isHttps ? 443 : 80),
|
|
||||||
path: u.path,
|
|
||||||
method: opts.method || 'GET',
|
|
||||||
headers: opts.headers || {}
|
|
||||||
};
|
|
||||||
if (body) options.headers['Content-Length'] = Buffer.byteLength(body);
|
|
||||||
const lib = isHttps ? https : http;
|
|
||||||
const req = lib.request(options, function(res) {
|
|
||||||
let data = '';
|
|
||||||
res.on('data', function(chunk) { data += chunk; });
|
|
||||||
res.on('end', function() {
|
|
||||||
resolve({ ok: res.statusCode >= 200 && res.statusCode < 300, statusCode: res.statusCode, body: data });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
req.on('error', reject);
|
|
||||||
if (body) req.write(body);
|
|
||||||
req.end();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
const raw = process.env.POCKETBASE_URL.replace(/\/$/, '');
|
|
||||||
const apiBase = /\/api$/i.test(raw) ? raw : raw + '/api';
|
|
||||||
const coll = process.env.POCKETBASE_COLLECTION;
|
|
||||||
const files = fs.readFileSync('changed_app_jsons.txt', 'utf8').trim().split(/\s+/).filter(Boolean);
|
|
||||||
const authUrl = apiBase + '/collections/users/auth-with-password';
|
|
||||||
console.log('Auth URL: ' + authUrl);
|
|
||||||
const authBody = JSON.stringify({
|
|
||||||
identity: process.env.POCKETBASE_ADMIN_EMAIL,
|
|
||||||
password: process.env.POCKETBASE_ADMIN_PASSWORD
|
|
||||||
});
|
|
||||||
const authRes = await request(authUrl, {
|
|
||||||
method: 'POST',
|
|
||||||
headers: { 'Content-Type': 'application/json' },
|
|
||||||
body: authBody
|
|
||||||
});
|
|
||||||
if (!authRes.ok) {
|
|
||||||
throw new Error('Auth failed. Tried: ' + authUrl + ' - Verify POST to that URL with body {"identity":"...","password":"..."} works. Response: ' + authRes.body);
|
|
||||||
}
|
|
||||||
const token = JSON.parse(authRes.body).token;
|
|
||||||
const recordsUrl = apiBase + '/collections/' + encodeURIComponent(coll) + '/records';
|
|
||||||
let categoryIdToName = {};
|
|
||||||
try {
|
|
||||||
const metadata = JSON.parse(fs.readFileSync('frontend/public/json/metadata.json', 'utf8'));
|
|
||||||
(metadata.categories || []).forEach(function(cat) { categoryIdToName[cat.id] = cat.name; });
|
|
||||||
} catch (e) { console.warn('Could not load metadata.json:', e.message); }
|
|
||||||
let typeValueToId = {};
|
|
||||||
let categoryNameToPbId = {};
|
|
||||||
try {
|
|
||||||
const typesRes = await request(apiBase + '/collections/z_ref_script_types/records?perPage=500', { headers: { 'Authorization': token } });
|
|
||||||
if (typesRes.ok) {
|
|
||||||
const typesData = JSON.parse(typesRes.body);
|
|
||||||
(typesData.items || []).forEach(function(item) { if (item.type) typeValueToId[item.type] = item.id; });
|
|
||||||
}
|
|
||||||
} catch (e) { console.warn('Could not fetch z_ref_script_types:', e.message); }
|
|
||||||
try {
|
|
||||||
const catRes = await request(apiBase + '/collections/script_categories/records?perPage=500', { headers: { 'Authorization': token } });
|
|
||||||
if (catRes.ok) {
|
|
||||||
const catData = JSON.parse(catRes.body);
|
|
||||||
(catData.items || []).forEach(function(item) { if (item.name) categoryNameToPbId[item.name] = item.id; });
|
|
||||||
}
|
|
||||||
} catch (e) { console.warn('Could not fetch script_categories:', e.message); }
|
|
||||||
for (const file of files) {
|
|
||||||
if (!fs.existsSync(file)) continue;
|
|
||||||
const data = JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
||||||
if (!data.slug) { console.log('Skipping', file, '(no slug)'); continue; }
|
|
||||||
var payload = {
|
|
||||||
name: data.name,
|
|
||||||
slug: data.slug,
|
|
||||||
script_created: data.date_created || data.script_created,
|
|
||||||
script_updated: data.date_created || data.script_updated,
|
|
||||||
updateable: data.updateable,
|
|
||||||
privileged: data.privileged,
|
|
||||||
port: data.interface_port != null ? data.interface_port : data.port,
|
|
||||||
documentation: data.documentation,
|
|
||||||
website: data.website,
|
|
||||||
logo: data.logo,
|
|
||||||
description: data.description,
|
|
||||||
config_path: data.config_path,
|
|
||||||
default_user: (data.default_credentials && data.default_credentials.username) || data.default_user,
|
|
||||||
default_passwd: (data.default_credentials && data.default_credentials.password) || data.default_passwd,
|
|
||||||
is_dev: false
|
|
||||||
};
|
|
||||||
var resolvedType = typeValueToId[data.type];
|
|
||||||
if (resolvedType) payload.type = resolvedType;
|
|
||||||
var resolvedCats = (data.categories || []).map(function(n) { return categoryNameToPbId[categoryIdToName[n]]; }).filter(Boolean);
|
|
||||||
if (resolvedCats.length) payload.categories = resolvedCats;
|
|
||||||
if (data.version !== undefined) payload.version = data.version;
|
|
||||||
if (data.changelog !== undefined) payload.changelog = data.changelog;
|
|
||||||
if (data.screenshots !== undefined) payload.screenshots = data.screenshots;
|
|
||||||
const filter = "(slug='" + data.slug + "')";
|
|
||||||
const listRes = await request(recordsUrl + '?filter=' + encodeURIComponent(filter) + '&perPage=1', {
|
|
||||||
headers: { 'Authorization': token }
|
|
||||||
});
|
|
||||||
const list = JSON.parse(listRes.body);
|
|
||||||
const existingId = list.items && list.items[0] && list.items[0].id;
|
|
||||||
if (existingId) {
|
|
||||||
console.log('Updating', file, '(slug=' + data.slug + ')');
|
|
||||||
const r = await request(recordsUrl + '/' + existingId, {
|
|
||||||
method: 'PATCH',
|
|
||||||
headers: { 'Authorization': token, 'Content-Type': 'application/json' },
|
|
||||||
body: JSON.stringify(payload)
|
|
||||||
});
|
|
||||||
if (!r.ok) throw new Error('PATCH failed: ' + r.body);
|
|
||||||
} else {
|
|
||||||
console.log('Creating', file, '(slug=' + data.slug + ')');
|
|
||||||
const r = await request(recordsUrl, {
|
|
||||||
method: 'POST',
|
|
||||||
headers: { 'Authorization': token, 'Content-Type': 'application/json' },
|
|
||||||
body: JSON.stringify(payload)
|
|
||||||
});
|
|
||||||
if (!r.ok) throw new Error('POST failed: ' + r.body);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
console.log('Done.');
|
|
||||||
})().catch(e => { console.error(e); process.exit(1); });
|
|
||||||
ENDSCRIPT
|
|
||||||
shell: bash
|
|
||||||
12
CHANGELOG.md
12
CHANGELOG.md
@@ -418,22 +418,10 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
|||||||
|
|
||||||
### 🚀 Updated Scripts
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- Tracearr: prepare for imminent v1.4.19 release [@durzo](https://github.com/durzo) ([#12413](https://github.com/community-scripts/ProxmoxVE/pull/12413))
|
|
||||||
|
|
||||||
- #### ✨ New Features
|
|
||||||
|
|
||||||
- Frigate: Bump to v0.17 [@MickLesk](https://github.com/MickLesk) ([#12474](https://github.com/community-scripts/ProxmoxVE/pull/12474))
|
|
||||||
|
|
||||||
- #### 💥 Breaking Changes
|
- #### 💥 Breaking Changes
|
||||||
|
|
||||||
- Migrate: DokPloy, Komodo, Coolify, Dockge, Runtipi to Addons [@MickLesk](https://github.com/MickLesk) ([#12275](https://github.com/community-scripts/ProxmoxVE/pull/12275))
|
- Migrate: DokPloy, Komodo, Coolify, Dockge, Runtipi to Addons [@MickLesk](https://github.com/MickLesk) ([#12275](https://github.com/community-scripts/ProxmoxVE/pull/12275))
|
||||||
|
|
||||||
- #### 🔧 Refactor
|
|
||||||
|
|
||||||
- ref: replace generic exit 1 with specific exit codes in ct & install [@MickLesk](https://github.com/MickLesk) ([#12475](https://github.com/community-scripts/ProxmoxVE/pull/12475))
|
|
||||||
|
|
||||||
### 💾 Core
|
### 💾 Core
|
||||||
|
|
||||||
- #### ✨ New Features
|
- #### ✨ New Features
|
||||||
|
|||||||
@@ -1,68 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
|
||||||
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
|
||||||
# Author: Slaviša Arežina (tremor021)
|
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
|
||||||
# Source: https://www.powerdns.com/
|
|
||||||
|
|
||||||
APP="PowerDNS"
|
|
||||||
var_tags="${var_tags:-dns}"
|
|
||||||
var_cpu="${var_cpu:-1}"
|
|
||||||
var_ram="${var_ram:-1024}"
|
|
||||||
var_disk="${var_disk:-4}"
|
|
||||||
var_os="${var_os:-debian}"
|
|
||||||
var_version="${var_version:-13}"
|
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
|
||||||
|
|
||||||
header_info "$APP"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
check_container_storage
|
|
||||||
check_container_resources
|
|
||||||
if [[ ! -d /opt/poweradmin ]]; then
|
|
||||||
msg_error "No ${APP} Installation Found!"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
msg_info "Updating PowerDNS"
|
|
||||||
$STD apt update
|
|
||||||
$STD apt install -y --only-upgrade pdns-server pdns-backend-sqlite3
|
|
||||||
msg_ok "Updated PowerDNS"
|
|
||||||
|
|
||||||
if check_for_gh_release "poweradmin" "poweradmin/poweradmin"; then
|
|
||||||
msg_info "Backing up Configuration"
|
|
||||||
cp /opt/poweradmin/config/settings.php /opt/poweradmin_settings.php.bak
|
|
||||||
cp /opt/poweradmin/powerdns.db /opt/poweradmin_powerdns.db.bak
|
|
||||||
msg_ok "Backed up Configuration"
|
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "poweradmin" "poweradmin/poweradmin" "tarball"
|
|
||||||
|
|
||||||
msg_info "Updating Poweradmin"
|
|
||||||
cp /opt/poweradmin_settings.php.bak /opt/poweradmin/config/settings.php
|
|
||||||
cp /opt/poweradmin_powerdns.db.bak /opt/poweradmin/powerdns.db
|
|
||||||
rm -rf /opt/poweradmin/install
|
|
||||||
rm -f /opt/poweradmin_settings.php.bak /opt/poweradmin_powerdns.db.bak
|
|
||||||
chown -R www-data:www-data /opt/poweradmin
|
|
||||||
msg_ok "Updated Poweradmin"
|
|
||||||
|
|
||||||
msg_info "Restarting Services"
|
|
||||||
systemctl restart pdns apache2
|
|
||||||
msg_ok "Restarted Services"
|
|
||||||
msg_ok "Updated successfully!"
|
|
||||||
fi
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed Successfully!\n"
|
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
|
||||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"
|
|
||||||
@@ -75,31 +75,10 @@ if [ -f \$pg_config_file ]; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
systemctl restart postgresql
|
systemctl restart postgresql
|
||||||
sudo -u postgres psql -c "ALTER USER tracearr WITH SUPERUSER;"
|
|
||||||
EOF
|
EOF
|
||||||
chmod +x /data/tracearr/prestart.sh
|
chmod +x /data/tracearr/prestart.sh
|
||||||
msg_ok "Updated prestart script"
|
msg_ok "Updated prestart script"
|
||||||
|
|
||||||
# check if tailscale is installed
|
|
||||||
if command -v tailscale >/dev/null 2>&1; then
|
|
||||||
# Tracearr runs tailscaled in user mode, disable the service.
|
|
||||||
$STD systemctl disable --now tailscaled
|
|
||||||
$STD systemctl stop tailscaled
|
|
||||||
msg_ok "Tailscale already installed"
|
|
||||||
else
|
|
||||||
msg_info "Installing tailscale"
|
|
||||||
setup_deb822_repo \
|
|
||||||
"tailscale" \
|
|
||||||
"https://pkgs.tailscale.com/stable/$(get_os_info id)/$(get_os_info codename).noarmor.gpg" \
|
|
||||||
"https://pkgs.tailscale.com/stable/$(get_os_info id)/" \
|
|
||||||
"$(get_os_info codename)"
|
|
||||||
$STD apt install -y tailscale
|
|
||||||
# Tracearr runs tailscaled in user mode, disable the service.
|
|
||||||
$STD systemctl disable --now tailscaled
|
|
||||||
$STD systemctl stop tailscaled
|
|
||||||
msg_ok "Installed tailscale"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if check_for_gh_release "tracearr" "connorgallopo/Tracearr"; then
|
if check_for_gh_release "tracearr" "connorgallopo/Tracearr"; then
|
||||||
msg_info "Stopping Services"
|
msg_info "Stopping Services"
|
||||||
systemctl stop tracearr postgresql redis
|
systemctl stop tracearr postgresql redis
|
||||||
@@ -143,8 +122,6 @@ EOF
|
|||||||
sed -i "s/^APP_VERSION=.*/APP_VERSION=$(cat /root/.tracearr)/" /data/tracearr/.env
|
sed -i "s/^APP_VERSION=.*/APP_VERSION=$(cat /root/.tracearr)/" /data/tracearr/.env
|
||||||
chmod 600 /data/tracearr/.env
|
chmod 600 /data/tracearr/.env
|
||||||
chown -R tracearr:tracearr /data/tracearr
|
chown -R tracearr:tracearr /data/tracearr
|
||||||
mkdir -p /data/backup
|
|
||||||
chown -R tracearr:tracearr /data/backup
|
|
||||||
msg_ok "Configured Tracearr"
|
msg_ok "Configured Tracearr"
|
||||||
|
|
||||||
msg_info "Starting services"
|
msg_info "Starting services"
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
"website": "https://2fauth.app/",
|
"website": "https://2fauth.app/",
|
||||||
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/2fauth.webp",
|
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/2fauth.webp",
|
||||||
"config_path": "cat /opt/2fauth/.env",
|
"config_path": "cat /opt/2fauth/.env",
|
||||||
"description": "2FAuth is a web based self-hosted alternative to One Time Passcode (OTP) generators like Google Authenticator, designed for both mobile and desktop. It aims to ease you perform your 2FA authentication steps whatever the device you handle, with a clean and suitable interface. - Workflow - Test",
|
"description": "2FAuth is a web based self-hosted alternative to One Time Passcode (OTP) generators like Google Authenticator, designed for both mobile and desktop. It aims to ease you perform your 2FA authentication steps whatever the device you handle, with a clean and suitable interface.",
|
||||||
"install_methods": [
|
"install_methods": [
|
||||||
{
|
{
|
||||||
"type": "default",
|
"type": "default",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"generated": "2026-03-02T13:48:26Z",
|
"generated": "2026-03-02T12:12:21Z",
|
||||||
"versions": [
|
"versions": [
|
||||||
{
|
{
|
||||||
"slug": "2fauth",
|
"slug": "2fauth",
|
||||||
@@ -200,9 +200,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "cleanuparr",
|
"slug": "cleanuparr",
|
||||||
"repo": "Cleanuparr/Cleanuparr",
|
"repo": "Cleanuparr/Cleanuparr",
|
||||||
"version": "v2.7.7",
|
"version": "v2.7.6",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-03-02T13:08:32Z"
|
"date": "2026-02-27T19:32:02Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "cloudreve",
|
"slug": "cloudreve",
|
||||||
@@ -424,9 +424,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "frigate",
|
"slug": "frigate",
|
||||||
"repo": "blakeblackshear/frigate",
|
"repo": "blakeblackshear/frigate",
|
||||||
"version": "v0.17.0",
|
"version": "v0.16.4",
|
||||||
"pinned": true,
|
"pinned": true,
|
||||||
"date": "2026-02-27T03:03:01Z"
|
"date": "2026-01-29T00:42:14Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "gatus",
|
"slug": "gatus",
|
||||||
|
|||||||
@@ -1,40 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "PowerDNS",
|
|
||||||
"slug": "powerdns",
|
|
||||||
"categories": [
|
|
||||||
5
|
|
||||||
],
|
|
||||||
"date_created": "2026-02-11",
|
|
||||||
"type": "ct",
|
|
||||||
"updateable": true,
|
|
||||||
"privileged": false,
|
|
||||||
"interface_port": 80,
|
|
||||||
"documentation": "https://doc.powerdns.com/index.html",
|
|
||||||
"config_path": "/opt/poweradmin/config/settings.php",
|
|
||||||
"website": "https://www.powerdns.com/",
|
|
||||||
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/powerdns.webp",
|
|
||||||
"description": "The PowerDNS Authoritative Server is a versatile nameserver which supports a large number of backends. These backends can either be plain zone files or be more dynamic in nature. PowerDNS has the concepts of ‘backends’. A backend is a datastore that the server will consult that contains DNS records (and some metadata). The backends range from database backends (MySQL, PostgreSQL) and BIND zone files to co-processes and JSON API’s.",
|
|
||||||
"install_methods": [
|
|
||||||
{
|
|
||||||
"type": "default",
|
|
||||||
"script": "ct/powerdns.sh",
|
|
||||||
"resources": {
|
|
||||||
"cpu": 1,
|
|
||||||
"ram": 1024,
|
|
||||||
"hdd": 4,
|
|
||||||
"os": "Debian",
|
|
||||||
"version": "13"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"default_credentials": {
|
|
||||||
"username": null,
|
|
||||||
"password": null
|
|
||||||
},
|
|
||||||
"notes": [
|
|
||||||
{
|
|
||||||
"text": "For administrator credentials type: `cat ~/poweradmin.creds` inside LXC.",
|
|
||||||
"type": "info"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
# Authors: MickLesk (CanbiZ) | Co-Authors: remz1337
|
# Authors: MickLesk (CanbiZ)
|
||||||
|
# Co-Authors: remz1337
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
# Source: https://frigate.video/ | Github: https://github.com/blakeblackshear/frigate
|
# Source: https://frigate.video/ | Github: https://github.com/blakeblackshear/frigate
|
||||||
|
|
||||||
@@ -84,7 +85,6 @@ $STD apt install -y \
|
|||||||
tclsh \
|
tclsh \
|
||||||
libopenblas-dev \
|
libopenblas-dev \
|
||||||
liblapack-dev \
|
liblapack-dev \
|
||||||
libgomp1 \
|
|
||||||
make \
|
make \
|
||||||
moreutils
|
moreutils
|
||||||
msg_ok "Installed Dependencies"
|
msg_ok "Installed Dependencies"
|
||||||
@@ -101,16 +101,9 @@ export NVIDIA_DRIVER_CAPABILITIES="compute,video,utility"
|
|||||||
export TOKENIZERS_PARALLELISM=true
|
export TOKENIZERS_PARALLELISM=true
|
||||||
export TRANSFORMERS_NO_ADVISORY_WARNINGS=1
|
export TRANSFORMERS_NO_ADVISORY_WARNINGS=1
|
||||||
export OPENCV_FFMPEG_LOGLEVEL=8
|
export OPENCV_FFMPEG_LOGLEVEL=8
|
||||||
export PYTHONWARNINGS="ignore:::numpy.core.getlimits"
|
|
||||||
export HAILORT_LOGGER_PATH=NONE
|
export HAILORT_LOGGER_PATH=NONE
|
||||||
export TF_CPP_MIN_LOG_LEVEL=3
|
|
||||||
export TF_CPP_MIN_VLOG_LEVEL=3
|
|
||||||
export TF_ENABLE_ONEDNN_OPTS=0
|
|
||||||
export AUTOGRAPH_VERBOSITY=0
|
|
||||||
export GLOG_minloglevel=3
|
|
||||||
export GLOG_logtostderr=0
|
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "frigate" "blakeblackshear/frigate" "tarball" "v0.17.0" "/opt/frigate"
|
fetch_and_deploy_gh_release "frigate" "blakeblackshear/frigate" "tarball" "v0.16.4" "/opt/frigate"
|
||||||
|
|
||||||
msg_info "Building Nginx"
|
msg_info "Building Nginx"
|
||||||
$STD bash /opt/frigate/docker/main/build_nginx.sh
|
$STD bash /opt/frigate/docker/main/build_nginx.sh
|
||||||
@@ -145,19 +138,13 @@ install -c -m 644 libusb-1.0.pc /usr/local/lib/pkgconfig
|
|||||||
ldconfig
|
ldconfig
|
||||||
msg_ok "Built libUSB"
|
msg_ok "Built libUSB"
|
||||||
|
|
||||||
msg_info "Bootstrapping pip"
|
|
||||||
wget -q https://bootstrap.pypa.io/get-pip.py -O /tmp/get-pip.py
|
|
||||||
sed -i 's/args.append("setuptools")/args.append("setuptools==77.0.3")/' /tmp/get-pip.py
|
|
||||||
$STD python3 /tmp/get-pip.py "pip"
|
|
||||||
rm -f /tmp/get-pip.py
|
|
||||||
msg_ok "Bootstrapped pip"
|
|
||||||
|
|
||||||
msg_info "Installing Python Dependencies"
|
msg_info "Installing Python Dependencies"
|
||||||
$STD pip3 install -r /opt/frigate/docker/main/requirements.txt
|
$STD pip3 install -r /opt/frigate/docker/main/requirements.txt
|
||||||
msg_ok "Installed Python Dependencies"
|
msg_ok "Installed Python Dependencies"
|
||||||
|
|
||||||
msg_info "Building Python Wheels (Patience)"
|
msg_info "Building Python Wheels (Patience)"
|
||||||
mkdir -p /wheels
|
mkdir -p /wheels
|
||||||
|
sed -i 's|^SQLITE3_VERSION=.*|SQLITE3_VERSION="version-3.46.0"|g' /opt/frigate/docker/main/build_pysqlite3.sh
|
||||||
$STD bash /opt/frigate/docker/main/build_pysqlite3.sh
|
$STD bash /opt/frigate/docker/main/build_pysqlite3.sh
|
||||||
for i in {1..3}; do
|
for i in {1..3}; do
|
||||||
$STD pip3 wheel --wheel-dir=/wheels -r /opt/frigate/docker/main/requirements-wheels.txt --default-timeout=300 --retries=3 && break
|
$STD pip3 wheel --wheel-dir=/wheels -r /opt/frigate/docker/main/requirements-wheels.txt --default-timeout=300 --retries=3 && break
|
||||||
@@ -165,7 +152,7 @@ for i in {1..3}; do
|
|||||||
done
|
done
|
||||||
msg_ok "Built Python Wheels"
|
msg_ok "Built Python Wheels"
|
||||||
|
|
||||||
NODE_VERSION="20" setup_nodejs
|
NODE_VERSION="22" NODE_MODULE="yarn" setup_nodejs
|
||||||
|
|
||||||
msg_info "Downloading Inference Models"
|
msg_info "Downloading Inference Models"
|
||||||
mkdir -p /models /openvino-model
|
mkdir -p /models /openvino-model
|
||||||
@@ -196,10 +183,6 @@ $STD pip3 install -U /wheels/*.whl
|
|||||||
ldconfig
|
ldconfig
|
||||||
msg_ok "Installed HailoRT Runtime"
|
msg_ok "Installed HailoRT Runtime"
|
||||||
|
|
||||||
msg_info "Installing MemryX Runtime"
|
|
||||||
$STD bash /opt/frigate/docker/main/install_memryx.sh
|
|
||||||
msg_ok "Installed MemryX Runtime"
|
|
||||||
|
|
||||||
msg_info "Installing OpenVino"
|
msg_info "Installing OpenVino"
|
||||||
$STD pip3 install -r /opt/frigate/docker/main/requirements-ov.txt
|
$STD pip3 install -r /opt/frigate/docker/main/requirements-ov.txt
|
||||||
msg_ok "Installed OpenVino"
|
msg_ok "Installed OpenVino"
|
||||||
@@ -226,8 +209,6 @@ $STD make version
|
|||||||
cd /opt/frigate/web
|
cd /opt/frigate/web
|
||||||
$STD npm install
|
$STD npm install
|
||||||
$STD npm run build
|
$STD npm run build
|
||||||
mv /opt/frigate/web/dist/BASE_PATH/monacoeditorwork/* /opt/frigate/web/dist/assets/
|
|
||||||
rm -rf /opt/frigate/web/dist/BASE_PATH
|
|
||||||
cp -r /opt/frigate/web/dist/* /opt/frigate/web/
|
cp -r /opt/frigate/web/dist/* /opt/frigate/web/
|
||||||
sed -i '/^s6-svc -O \.$/s/^/#/' /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/frigate/run
|
sed -i '/^s6-svc -O \.$/s/^/#/' /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/frigate/run
|
||||||
msg_ok "Built Frigate Application"
|
msg_ok "Built Frigate Application"
|
||||||
@@ -243,19 +224,6 @@ echo "tmpfs /tmp/cache tmpfs defaults 0 0" >>/etc/fstab
|
|||||||
cat <<EOF >/etc/frigate.env
|
cat <<EOF >/etc/frigate.env
|
||||||
DEFAULT_FFMPEG_VERSION="7.0"
|
DEFAULT_FFMPEG_VERSION="7.0"
|
||||||
INCLUDED_FFMPEG_VERSIONS="7.0:5.0"
|
INCLUDED_FFMPEG_VERSIONS="7.0:5.0"
|
||||||
NVIDIA_VISIBLE_DEVICES=all
|
|
||||||
NVIDIA_DRIVER_CAPABILITIES="compute,video,utility"
|
|
||||||
TOKENIZERS_PARALLELISM=true
|
|
||||||
TRANSFORMERS_NO_ADVISORY_WARNINGS=1
|
|
||||||
OPENCV_FFMPEG_LOGLEVEL=8
|
|
||||||
PYTHONWARNINGS="ignore:::numpy.core.getlimits"
|
|
||||||
HAILORT_LOGGER_PATH=NONE
|
|
||||||
TF_CPP_MIN_LOG_LEVEL=3
|
|
||||||
TF_CPP_MIN_VLOG_LEVEL=3
|
|
||||||
TF_ENABLE_ONEDNN_OPTS=0
|
|
||||||
AUTOGRAPH_VERBOSITY=0
|
|
||||||
GLOG_minloglevel=3
|
|
||||||
GLOG_logtostderr=0
|
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
cat <<EOF >/config/config.yml
|
cat <<EOF >/config/config.yml
|
||||||
@@ -269,6 +237,7 @@ cameras:
|
|||||||
input_args: -re -stream_loop -1 -fflags +genpts
|
input_args: -re -stream_loop -1 -fflags +genpts
|
||||||
roles:
|
roles:
|
||||||
- detect
|
- detect
|
||||||
|
- rtmp
|
||||||
detect:
|
detect:
|
||||||
height: 1080
|
height: 1080
|
||||||
width: 1920
|
width: 1920
|
||||||
@@ -286,7 +255,6 @@ ffmpeg:
|
|||||||
detectors:
|
detectors:
|
||||||
detector01:
|
detector01:
|
||||||
type: openvino
|
type: openvino
|
||||||
device: AUTO
|
|
||||||
model:
|
model:
|
||||||
width: 300
|
width: 300
|
||||||
height: 300
|
height: 300
|
||||||
|
|||||||
@@ -1,134 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
|
||||||
# Author: Slaviša Arežina (tremor021)
|
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
|
||||||
# Source: https://www.powerdns.com/
|
|
||||||
|
|
||||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
|
||||||
color
|
|
||||||
verb_ip6
|
|
||||||
catch_errors
|
|
||||||
setting_up_container
|
|
||||||
network_check
|
|
||||||
update_os
|
|
||||||
|
|
||||||
msg_info "Installing Dependencies"
|
|
||||||
$STD apt install -y sqlite3
|
|
||||||
msg_ok "Installed Dependencies"
|
|
||||||
|
|
||||||
PHP_VERSION="8.3" PHP_APACHE="YES" PHP_FPM="YES" PHP_MODULE="gettext,tokenizer,sqlite3,ldap" setup_php
|
|
||||||
setup_deb822_repo \
|
|
||||||
"pdns" \
|
|
||||||
"https://repo.powerdns.com/FD380FBB-pub.asc" \
|
|
||||||
"http://repo.powerdns.com/debian" \
|
|
||||||
"trixie-auth-50"
|
|
||||||
|
|
||||||
cat <<EOF >/etc/apt/preferences.d/auth-50
|
|
||||||
Package: pdns-*
|
|
||||||
Pin: origin repo.powerdns.com
|
|
||||||
Pin-Priority: 600
|
|
||||||
EOF
|
|
||||||
|
|
||||||
escape_sql() {
|
|
||||||
printf '%s' "$1" | sed "s/'/''/g"
|
|
||||||
}
|
|
||||||
|
|
||||||
msg_info "Setting up PowerDNS"
|
|
||||||
$STD apt install -y \
|
|
||||||
pdns-server \
|
|
||||||
pdns-backend-sqlite3
|
|
||||||
msg_ok "Setup PowerDNS"
|
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "poweradmin" "poweradmin/poweradmin" "tarball"
|
|
||||||
|
|
||||||
msg_info "Setting up Poweradmin"
|
|
||||||
sqlite3 /opt/poweradmin/powerdns.db </opt/poweradmin/sql/poweradmin-sqlite-db-structure.sql
|
|
||||||
sqlite3 /opt/poweradmin/powerdns.db </opt/poweradmin/sql/pdns/49/schema.sqlite3.sql
|
|
||||||
PA_ADMIN_USERNAME="admin"
|
|
||||||
PA_ADMIN_EMAIL="admin@example.com"
|
|
||||||
PA_ADMIN_FULLNAME="Administrator"
|
|
||||||
PA_ADMIN_PASSWORD=$(openssl rand -base64 16 | tr -d "=+/" | cut -c1-16)
|
|
||||||
PA_SESSION_KEY=$(openssl rand -base64 75 | tr -dc 'A-Za-z0-9^@#!(){}[]%_\-+=~' | head -c 50)
|
|
||||||
PASSWORD_HASH=$(php -r "echo password_hash(\$argv[1], PASSWORD_DEFAULT);" -- "${PA_ADMIN_PASSWORD}" 2>/dev/null)
|
|
||||||
sqlite3 /opt/poweradmin/powerdns.db "INSERT INTO users (username, password, fullname, email, description, perm_templ, active, use_ldap) \
|
|
||||||
VALUES ('$(escape_sql "${PA_ADMIN_USERNAME}")', '$(escape_sql "${PASSWORD_HASH}")', '$(escape_sql "${PA_ADMIN_FULLNAME}")', \
|
|
||||||
'$(escape_sql "${PA_ADMIN_EMAIL}")', 'System Administrator', 1, 1, 0);"
|
|
||||||
|
|
||||||
cat <<EOF >~/poweradmin.creds
|
|
||||||
Admin Username: ${PA_ADMIN_USERNAME}
|
|
||||||
Admin Password: ${PA_ADMIN_PASSWORD}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
cat <<EOF >/opt/poweradmin/config/settings.php
|
|
||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Poweradmin Settings Configuration File
|
|
||||||
*
|
|
||||||
* Generated by the installer on 2026-02-02 21:01:40
|
|
||||||
*/
|
|
||||||
|
|
||||||
return [
|
|
||||||
/**
|
|
||||||
* Database Settings
|
|
||||||
*/
|
|
||||||
'database' => [
|
|
||||||
'type' => 'sqlite',
|
|
||||||
'file' => '/opt/poweradmin/powerdns.db',
|
|
||||||
],
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Security Settings
|
|
||||||
*/
|
|
||||||
'security' => [
|
|
||||||
'session_key' => '${PA_SESSION_KEY}',
|
|
||||||
],
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface Settings
|
|
||||||
*/
|
|
||||||
'interface' => [
|
|
||||||
'language' => 'en_EN',
|
|
||||||
],
|
|
||||||
|
|
||||||
/**
|
|
||||||
* DNS Settings
|
|
||||||
*/
|
|
||||||
'dns' => [
|
|
||||||
'hostmaster' => 'localhost.lan',
|
|
||||||
'ns1' => '8.8.8.8',
|
|
||||||
'ns2' => '9.9.9.9',
|
|
||||||
]
|
|
||||||
];
|
|
||||||
EOF
|
|
||||||
rm -rf /opt/poweradmin/install
|
|
||||||
msg_ok "Setup Poweradmin"
|
|
||||||
|
|
||||||
msg_info "Creating Service"
|
|
||||||
rm /etc/apache2/sites-enabled/000-default.conf
|
|
||||||
cat <<EOF >/etc/apache2/sites-enabled/poweradmin.conf
|
|
||||||
<VirtualHost *:80>
|
|
||||||
ServerName localhost
|
|
||||||
DocumentRoot /opt/poweradmin
|
|
||||||
|
|
||||||
<Directory /opt/poweradmin>
|
|
||||||
Options -Indexes +FollowSymLinks
|
|
||||||
AllowOverride All
|
|
||||||
Require all granted
|
|
||||||
</Directory>
|
|
||||||
|
|
||||||
# For DDNS update functionality
|
|
||||||
RewriteEngine On
|
|
||||||
RewriteRule ^/update(.*)\$ /dynamic_update.php [L]
|
|
||||||
RewriteRule ^/nic/update(.*)\$ /dynamic_update.php [L]
|
|
||||||
</VirtualHost>
|
|
||||||
EOF
|
|
||||||
$STD a2enmod rewrite headers
|
|
||||||
chown -R www-data:www-data /opt/poweradmin
|
|
||||||
$STD systemctl restart apache2
|
|
||||||
msg_info "Created Service"
|
|
||||||
|
|
||||||
motd_ssh
|
|
||||||
customize
|
|
||||||
cleanup_lxc
|
|
||||||
@@ -44,20 +44,7 @@ $STD timescaledb-tune -yes -memory "$ram_for_tsdb"MB
|
|||||||
$STD systemctl restart postgresql
|
$STD systemctl restart postgresql
|
||||||
msg_ok "Installed TimescaleDB"
|
msg_ok "Installed TimescaleDB"
|
||||||
|
|
||||||
PG_DB_NAME="tracearr_db" PG_DB_USER="tracearr" PG_DB_EXTENSIONS="timescaledb,timescaledb_toolkit" PG_DB_GRANT_SUPERUSER="true" setup_postgresql_db
|
PG_DB_NAME="tracearr_db" PG_DB_USER="tracearr" PG_DB_EXTENSIONS="timescaledb,timescaledb_toolkit" setup_postgresql_db
|
||||||
|
|
||||||
msg_info "Installing tailscale"
|
|
||||||
setup_deb822_repo \
|
|
||||||
"tailscale" \
|
|
||||||
"https://pkgs.tailscale.com/stable/$(get_os_info id)/$(get_os_info codename).noarmor.gpg" \
|
|
||||||
"https://pkgs.tailscale.com/stable/$(get_os_info id)/" \
|
|
||||||
"$(get_os_info codename)"
|
|
||||||
$STD apt install -y tailscale
|
|
||||||
# Tracearr runs tailscaled in user mode, disable the service.
|
|
||||||
$STD systemctl disable --now tailscaled
|
|
||||||
$STD systemctl stop tailscaled
|
|
||||||
msg_ok "Installed tailscale"
|
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "tracearr" "connorgallopo/Tracearr" "tarball" "latest" "/opt/tracearr.build"
|
fetch_and_deploy_gh_release "tracearr" "connorgallopo/Tracearr" "tarball" "latest" "/opt/tracearr.build"
|
||||||
|
|
||||||
msg_info "Building Tracearr"
|
msg_info "Building Tracearr"
|
||||||
@@ -88,7 +75,6 @@ msg_info "Configuring Tracearr"
|
|||||||
$STD useradd -r -s /bin/false -U tracearr
|
$STD useradd -r -s /bin/false -U tracearr
|
||||||
$STD chown -R tracearr:tracearr /opt/tracearr
|
$STD chown -R tracearr:tracearr /opt/tracearr
|
||||||
install -d -m 750 -o tracearr -g tracearr /data/tracearr
|
install -d -m 750 -o tracearr -g tracearr /data/tracearr
|
||||||
install -d -m 750 -o tracearr -g tracearr /data/backup
|
|
||||||
export JWT_SECRET=$(openssl rand -hex 32)
|
export JWT_SECRET=$(openssl rand -hex 32)
|
||||||
export COOKIE_SECRET=$(openssl rand -hex 32)
|
export COOKIE_SECRET=$(openssl rand -hex 32)
|
||||||
cat <<EOF >/data/tracearr/.env
|
cat <<EOF >/data/tracearr/.env
|
||||||
@@ -103,6 +89,7 @@ JWT_SECRET=$JWT_SECRET
|
|||||||
COOKIE_SECRET=$COOKIE_SECRET
|
COOKIE_SECRET=$COOKIE_SECRET
|
||||||
APP_VERSION=$(cat /root/.tracearr)
|
APP_VERSION=$(cat /root/.tracearr)
|
||||||
#CORS_ORIGIN=http://localhost:5173
|
#CORS_ORIGIN=http://localhost:5173
|
||||||
|
#MOBILE_BETA_MODE=true
|
||||||
EOF
|
EOF
|
||||||
chmod 600 /data/tracearr/.env
|
chmod 600 /data/tracearr/.env
|
||||||
chown -R tracearr:tracearr /data/tracearr
|
chown -R tracearr:tracearr /data/tracearr
|
||||||
@@ -153,7 +140,6 @@ if [ -f \$pg_config_file ]; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
systemctl restart postgresql
|
systemctl restart postgresql
|
||||||
sudo -u postgres psql -c "ALTER USER tracearr WITH SUPERUSER;"
|
|
||||||
EOF
|
EOF
|
||||||
chmod +x /data/tracearr/prestart.sh
|
chmod +x /data/tracearr/prestart.sh
|
||||||
cat <<EOF >/lib/systemd/system/tracearr.service
|
cat <<EOF >/lib/systemd/system/tracearr.service
|
||||||
|
|||||||
@@ -687,23 +687,18 @@ EOF
|
|||||||
[[ "${DEV_MODE:-}" == "true" ]] && echo "[DEBUG] Sending to: $TELEMETRY_URL" >&2
|
[[ "${DEV_MODE:-}" == "true" ]] && echo "[DEBUG] Sending to: $TELEMETRY_URL" >&2
|
||||||
[[ "${DEV_MODE:-}" == "true" ]] && echo "[DEBUG] Payload: $JSON_PAYLOAD" >&2
|
[[ "${DEV_MODE:-}" == "true" ]] && echo "[DEBUG] Payload: $JSON_PAYLOAD" >&2
|
||||||
|
|
||||||
# Send initial "installing" record with retry.
|
# Fire-and-forget: never block, never fail
|
||||||
# This record MUST exist for all subsequent updates to succeed.
|
local http_code
|
||||||
local http_code="" attempt
|
if [[ "${DEV_MODE:-}" == "true" ]]; then
|
||||||
for attempt in 1 2 3; do
|
http_code=$(curl -sS -w "%{http_code}" -m "${TELEMETRY_TIMEOUT}" -X POST "${TELEMETRY_URL}" \
|
||||||
if [[ "${DEV_MODE:-}" == "true" ]]; then
|
-H "Content-Type: application/json" \
|
||||||
http_code=$(curl -sS -w "%{http_code}" -m "${TELEMETRY_TIMEOUT}" -X POST "${TELEMETRY_URL}" \
|
-d "$JSON_PAYLOAD" -o /dev/stderr 2>&1) || true
|
||||||
-H "Content-Type: application/json" \
|
echo "[DEBUG] HTTP response code: $http_code" >&2
|
||||||
-d "$JSON_PAYLOAD" -o /dev/stderr 2>&1) || http_code="000"
|
else
|
||||||
echo "[DEBUG] post_to_api attempt $attempt HTTP=$http_code" >&2
|
curl -fsS -m "${TELEMETRY_TIMEOUT}" -X POST "${TELEMETRY_URL}" \
|
||||||
else
|
-H "Content-Type: application/json" \
|
||||||
http_code=$(curl -sS -w "%{http_code}" -m "${TELEMETRY_TIMEOUT}" -X POST "${TELEMETRY_URL}" \
|
-d "$JSON_PAYLOAD" &>/dev/null || true
|
||||||
-H "Content-Type: application/json" \
|
fi
|
||||||
-d "$JSON_PAYLOAD" -o /dev/null 2>/dev/null) || http_code="000"
|
|
||||||
fi
|
|
||||||
[[ "$http_code" =~ ^2[0-9]{2}$ ]] && break
|
|
||||||
[[ "$attempt" -lt 3 ]] && sleep 1
|
|
||||||
done
|
|
||||||
|
|
||||||
POST_TO_API_DONE=true
|
POST_TO_API_DONE=true
|
||||||
}
|
}
|
||||||
@@ -794,15 +789,10 @@ post_to_api_vm() {
|
|||||||
EOF
|
EOF
|
||||||
)
|
)
|
||||||
|
|
||||||
# Send initial "installing" record with retry (must succeed for updates to work)
|
# Fire-and-forget: never block, never fail
|
||||||
local http_code="" attempt
|
curl -fsS -m "${TELEMETRY_TIMEOUT}" -X POST "${TELEMETRY_URL}" \
|
||||||
for attempt in 1 2 3; do
|
-H "Content-Type: application/json" \
|
||||||
http_code=$(curl -sS -w "%{http_code}" -m "${TELEMETRY_TIMEOUT}" -X POST "${TELEMETRY_URL}" \
|
-d "$JSON_PAYLOAD" &>/dev/null || true
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d "$JSON_PAYLOAD" -o /dev/null 2>/dev/null) || http_code="000"
|
|
||||||
[[ "$http_code" =~ ^2[0-9]{2}$ ]] && break
|
|
||||||
[[ "$attempt" -lt 3 ]] && sleep 1
|
|
||||||
done
|
|
||||||
|
|
||||||
POST_TO_API_DONE=true
|
POST_TO_API_DONE=true
|
||||||
}
|
}
|
||||||
@@ -946,11 +936,6 @@ post_update_to_api() {
|
|||||||
|
|
||||||
local http_code=""
|
local http_code=""
|
||||||
|
|
||||||
# Strip 'G' suffix from disk size (VMs set DISK_SIZE=32G)
|
|
||||||
local DISK_SIZE_API="${DISK_SIZE:-0}"
|
|
||||||
DISK_SIZE_API="${DISK_SIZE_API%G}"
|
|
||||||
[[ ! "$DISK_SIZE_API" =~ ^[0-9]+$ ]] && DISK_SIZE_API=0
|
|
||||||
|
|
||||||
# ── Attempt 1: Full payload with complete error text (includes full log) ──
|
# ── Attempt 1: Full payload with complete error text (includes full log) ──
|
||||||
local JSON_PAYLOAD
|
local JSON_PAYLOAD
|
||||||
JSON_PAYLOAD=$(
|
JSON_PAYLOAD=$(
|
||||||
@@ -962,7 +947,7 @@ post_update_to_api() {
|
|||||||
"nsapp": "${NSAPP:-unknown}",
|
"nsapp": "${NSAPP:-unknown}",
|
||||||
"status": "${pb_status}",
|
"status": "${pb_status}",
|
||||||
"ct_type": ${CT_TYPE:-1},
|
"ct_type": ${CT_TYPE:-1},
|
||||||
"disk_size": ${DISK_SIZE_API},
|
"disk_size": ${DISK_SIZE:-0},
|
||||||
"core_count": ${CORE_COUNT:-0},
|
"core_count": ${CORE_COUNT:-0},
|
||||||
"ram_size": ${RAM_SIZE:-0},
|
"ram_size": ${RAM_SIZE:-0},
|
||||||
"os_type": "${var_os:-}",
|
"os_type": "${var_os:-}",
|
||||||
@@ -1005,7 +990,7 @@ EOF
|
|||||||
"nsapp": "${NSAPP:-unknown}",
|
"nsapp": "${NSAPP:-unknown}",
|
||||||
"status": "${pb_status}",
|
"status": "${pb_status}",
|
||||||
"ct_type": ${CT_TYPE:-1},
|
"ct_type": ${CT_TYPE:-1},
|
||||||
"disk_size": ${DISK_SIZE_API},
|
"disk_size": ${DISK_SIZE:-0},
|
||||||
"core_count": ${CORE_COUNT:-0},
|
"core_count": ${CORE_COUNT:-0},
|
||||||
"ram_size": ${RAM_SIZE:-0},
|
"ram_size": ${RAM_SIZE:-0},
|
||||||
"os_type": "${var_os:-}",
|
"os_type": "${var_os:-}",
|
||||||
|
|||||||
Reference in New Issue
Block a user