Compare commits

..

19 Commits

Author SHA1 Message Date
MickLesk
a0d99cfbde pocketbase-bot: label the sync PR as a bugfix
The sync corrects CT defaults that no longer match the PocketBase
record, so bugfix describes it better than website update, which is
meant for metadata changes on the site itself.
2026-09-16 13:26:33 +02:00
MickLesk
b26cf24b1f ci: stop the .app header PR being closed as a new script
allowedBots carried "community-scripts-pr-app" but not the
"[bot]"-suffixed name GitHub actually reports, and the check is an exact
match, so the exemption never applied to it. push-app-to-main is listed
both ways; this one was not. PR #17304 was closed as an untested new
script submission because of it.

generate-app-headers.sh empties ct/headers, tools/headers and
vm/headers and writes them again, so every run reports those files as
added. That is what the autolabeler's new-script rule looks for, and
the vm rule matched vm/headers too. Exclude the header directories from
both, and skip them in the close workflow's own added-file fallback, so
the label cannot come back by another route.

Checked against minimatch with the shipped config: header files get
neither label, ct/*.sh, install/*.sh and vm/*.sh still get theirs.
2026-09-16 13:19:17 +02:00
MickLesk
1acc5241a3 pocketbase-bot: write the sync PR against the PR template
The sync PR body had its own Summary and Source headings, so the
autolabeler found none of the template checkboxes it looks for and the
PR came out with nothing but "needs triage". It also never referenced
the issue the command came from.

Write the body the way the template expects, with the Website update
box ticked, which is what a PocketBase sync is. Tested thoroughly stays
unticked and Tested on says not tested, because nothing here was run;
close-invalid-pr-template skips bot authors, so that costs nothing.

Reference the triggering number as Fixes when the command came from an
issue and as a plain mention when it came from a PR comment, where
Fixes would point the PR at itself. issue_comment carries both under
github.event.issue, so the new IS_PR_COMMENT tells them apart.
2026-09-16 13:16:20 +02:00
MickLesk
a73d54f911 pocketbase-bot: accept the var_ names and two missing fields
cpu, ram, hdd, os and version were already reachable, but only under
the PocketBase names. People type what the ct scripts call them, so
"/pocketbase <slug> var_ram=4096" was rejected as an unknown field
while "ram=4096" worked. The bot already carried the mapping as
RESOURCE_TO_CT_VAR, for display only.

Normalise the keys in parseKVPairs, so both the field=value path and
the method path accept them, along with disk and memory as the other
two names people reach for. Matching is case-insensitive.

pin_reason and last_update_commit exist on the record and are worth
editing, but were not in ALLOWED_FIELDS. slug, script_created and
script_updated stay out: the first is the key the command looks the
record up by, the other two belong to the timestamp workflow. notes and
install_methods keep their own subcommands.
2026-09-16 13:12:37 +02:00
community-scripts-pr-app[bot]
0921c030b5 Update CHANGELOG.md (#17300)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-09-16 10:26:54 +00:00
community-scripts-pr-app[bot]
2de3a25789 Update CHANGELOG.md (#17299)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-09-16 10:08:13 +00:00
community-scripts-pr-app[bot]
135ba7bb61 Update CHANGELOG.md (#17297)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-09-16 10:02:26 +00:00
community-scripts-pr-app[bot]
22cf7cc8d0 Update CHANGELOG.md (#17295)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-09-16 10:02:00 +00:00
CanbiZ (MickLesk)
b4684b2faf Frigate: Bump to 0.18.0 (#17273)
* frigate: move to 0.18.0

Bump the pinned release and follow the four build changes that matter
outside of Docker.

ffmpeg: 0.18 ships 8.0 as the default and keeps 7.0 and 5.0 alongside
it, so /etc/frigate.env has to name all three or the s6 run script
resolves a version that install_deps.sh never downloaded.

go2rtc: pin to v1.9.14, the version the Dockerfile fetches. "latest"
happened to work but shipped whatever AlexxIT had tagged that day
rather than the build Frigate was tested against.

OpenVINO: requirements-ov.txt dropped tensorflow and openvino-dev, and
build_ov_model.py no longer uses the Model Optimizer. omz_tools is
therefore gone, which left the first two branches of the labelmap
lookup dead; download coco_91cl_bkgr.txt the way the Dockerfile does.

Intel media driver: 0.18 builds intel-media-va-driver-non-free from
source for Battlemage, because the prebuilt noble/trixie packages need
a glibc that bookworm does not have. Run it before install_deps.sh, as
the deps-rootfs stage does, and drop the jammy repo the build adds so
the later trixie pull for libva2 is not resolved against it.

The remaining build scripts and requirement files changed too, but
those come from the checked-out tree and follow the version bump on
their own.

* frigate: stop the detector config from replacing the base config

The install wrote a config with mqtt, cameras, auth and detect, then the
detector branch wrote the file again instead of adding to it. Both
branches used a single redirect, so everything above them was discarded
and the result had neither mqtt nor cameras. frigate/config/config.py
declares both as Field() without a default, in 0.17.2 as well as in
0.18.0, so Frigate rejected the file and came up in safe mode:

  mqtt - Field required
  cameras - Field required

Move hwaccel_args into the base block, since both branches set it, and
append the detector and model sections instead of overwriting.

Checked by generating both branches and parsing the result: the OpenVINO
path yields auth, cameras, detect, detectors, ffmpeg, model, mqtt, the
CPU path the same without detectors, and the test camera survives in
both.

* frigate: write the config in one place

Only the detector and model section depends on the CPU check, but the
file was assembled in three heredocs writing to the same path. That
shape is what produced the safe-mode config: both branches used a plain
redirect and discarded everything above them.

Pick the variable part into DETECTOR_CONFIG first and write the file
once, so the layout is visible in one block and no branch can replace
what came before it.

Output is unchanged, verified by generating both branches from the
previous commit and from this one and diffing: byte-identical.

* Update default RAM and disk values in frigate.sh
2026-09-16 12:01:52 +02:00
CanbiZ (MickLesk)
8050ec7af1 navidrome: repair root-owned data folders left by 0.61.x (#17275)
Navidrome 0.61.x created cache, artwork and plugins under the data
folder whenever any navidrome command ran, including the ones the deb
postinstall runs as root. 0.62 stopped creating them that way but never
corrected the owner, so a container that passed through 0.61.x carries a
root-owned artwork directory. 0.64.0 is the first release to write into
it and fails with

  writing image store: mkdir /var/lib/navidrome/artwork/hashed:
  permission denied

which breaks newly resolved album covers and every playlist cover, since
those are composites.

Repair the three directories the same way navidrome/navidrome#6143 does:
the entries themselves only, since they were created empty, real
directories owned by root only, and chown -h, because the navidrome user
owns the data folder and could otherwise plant a symlink.

The trailing || true is not in the upstream copy and is needed here.
Their postinstall runs without set -e, while update_script runs under
catch_errors, which sets -Ee with an ERR trap. find exits 1 as soon as
one starting point is missing, so on a container without a plugins
directory the update would abort.

Fixes the report in #17247, confirmed there by the reporter's stat and
dpkg log: artwork is root-owned and dated to their 0.60.3 -> 0.61.1
upgrade.
2026-09-16 12:01:42 +02:00
CanbiZ (MickLesk)
b17e8e5abf Refactor: HomeAssistant-OS (core / improve functions / performance) (#17281)
* HomeAssistant-OS (VM): Refactor for improved readability

Refactor script to improve readability and maintainability. Updated function calls and variable assignments for better clarity.

* Modify author line in haos-vm.sh

Updated author information in the script header.

* Refactor Home Assistant OS version selection and caching

Refactor advanced settings dialog for Home Assistant OS version selection and simplify image caching logic.
2026-09-16 12:01:34 +02:00
community-scripts-pr-app[bot]
3dc4e9a2a6 Update .app files (#17294)
Co-authored-by: GitHub Actions <github-actions[bot]@users.noreply.github.com>
2026-09-16 12:00:51 +02:00
community-scripts-pr-app[bot]
cc273998b6 Update CHANGELOG.md (#17293)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-09-16 09:59:46 +00:00
community-scripts-pr-app[bot]
1cb18d928a Update CHANGELOG.md (#17292)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-09-16 09:59:22 +00:00
CanbiZ (MickLesk)
f5d336cfed tor-snowflake: read the Go version from the module root (#17276)
* tor-snowflake: read the Go version from the module root

Snowflake is a single Go module with go.mod at the repository root, not
under proxy/. The install read /opt/tor-snowflake/proxy/go.mod, which
has never existed, so grep failed and the version came out empty. Go
was then fetched from

  https://go.dev/dl/go.linux-amd64.tar.gz

with no version in the name, and the install aborted at that download.

Read the directive with a single awk instead of grep piped into awk.
The pipeline tripped catch_errors, which sets -Ee with pipefail and an
ERR trap, the moment the file was missing; that is the "exit code 2
while executing command awk" line that preceded the download failure.

Fall back to latest when the file cannot be read, so a future upstream
move of go.mod costs a Go version that is newer than the one pinned
rather than a failed build. setup_go already resolves latest, and also
resolves a bare major.minor to its newest patch, so a go directive
without a patch level stays fine.

Verified against v2.14.1: go.mod sits at the root and declares go
1.24.0, and the awk yields 1.24.0 from it and latest from a missing
file without tripping the ERR trap.

* Refactor GO_VERSION extraction in tor-snowflake.sh

Updated the method of extracting GO_VERSION from go.mod and set a default value if not found.
2026-09-16 11:59:19 +02:00
CanbiZ (MickLesk)
79a320fc3a Refactor: TrueNAS VM (core / improve functions / performance) (#17277)
* Refactor: TrueNAS VM (core / improve functions / performance)

* Boot TrueNAS from sata0, the disk it actually installs to

The boot order named scsi0, which never exists: the system disk is
sata0, and imported passthrough disks start at scsi1 because SCSI_NR is
pre-incremented. So the order always fell through to ide2 and the
installer came back up after every reboot.

* Fix URL in truenas-vm.sh script
2026-09-16 11:59:11 +02:00
CanbiZ (MickLesk)
8b01d1c302 docmost: stop corepack asking for confirmation during the build (#17282)
Docmost pins its package manager, so running pnpm goes through corepack,
which asks before fetching the pinned version:

  Corepack is about to download .../pnpm-11.25.0.tgz
  ? Do you want to continue? [Y/n]

The pnpm calls run under $STD, so with verbose off the question is
never shown and the update sits on "Configuring Docmost" waiting for an
answer nobody can see. With verbose on the same update completes,
because the prompt is visible and gets answered, which is exactly what
the reporter observed.

Set COREPACK_ENABLE_DOWNLOAD_PROMPT=0 before the pnpm calls in both the
install and the update, the way fifteen other ct scripts and ten
install scripts already do.
2026-09-16 11:59:00 +02:00
community-scripts-pr-app[bot]
6f00706213 Update CHANGELOG.md (#17287)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-09-15 18:25:50 +00:00
Christian Forgács
0b536d83c3 borg-ui: missing dependency sshpass (#17286)
Co-authored-by: Christian Forgács <christian@wunderbit.de>
2026-09-15 20:25:11 +02:00
14 changed files with 171 additions and 541 deletions

14
.github/autolabeler-config.json generated vendored
View File

@@ -8,7 +8,12 @@
"turnkey/**",
"vm/**"
],
"excludeGlobs": []
"excludeGlobs": [
"**/headers/**",
"ct/headers/**",
"tools/headers/**",
"vm/headers/**"
]
}
],
"update script": [
@@ -41,7 +46,12 @@
"includeGlobs": [
"vm/**"
],
"excludeGlobs": []
"excludeGlobs": [
"**/headers/**",
"ct/headers/**",
"tools/headers/**",
"vm/headers/**"
]
}
],
"tools": [

View File

@@ -28,6 +28,7 @@ jobs:
const allowedBots = [
"push-app-to-main[bot]",
"push-app-to-main",
"community-scripts-pr-app[bot]",
"community-scripts-pr-app"
];
@@ -62,7 +63,9 @@ jobs:
per_page: 100,
});
hasAddedScriptFile = files.some(
f => f.status === "added" && scriptPrefixes.some(p => f.filename.startsWith(p))
f => f.status === "added" &&
!f.filename.includes("/headers/") &&
scriptPrefixes.some(p => f.filename.startsWith(p))
);
} catch (error) {
core.warning(`Could not list files for PR #${prNumber}: ${error.message}`);

40
.github/workflows/pocketbase-bot.yml generated vendored
View File

@@ -26,6 +26,7 @@ jobs:
COMMENT_BODY: ${{ github.event.comment.body }}
COMMENT_ID: ${{ github.event.comment.id }}
ISSUE_NUMBER: ${{ github.event.issue.number }}
IS_PR_COMMENT: ${{ github.event.issue.pull_request && 'true' || 'false' }}
REPO_OWNER: ${{ github.repository_owner }}
REPO_NAME: ${{ github.event.repository.name }}
ACTOR: ${{ github.event.comment.user.login }}
@@ -84,6 +85,7 @@ jobs:
const owner = process.env.REPO_OWNER;
const repo = process.env.REPO_NAME;
const issueNumber = parseInt(process.env.ISSUE_NUMBER, 10);
const isPrComment = process.env.IS_PR_COMMENT === 'true';
const commentId = parseInt(process.env.COMMENT_ID, 10);
const actor = process.env.ACTOR;
@@ -216,11 +218,22 @@ jobs:
const prTitle = 'chore(ct): sync ' + slugValue + ' defaults with PocketBase';
const prBody =
'## Summary\n' +
'- Sync default CT variables for `' + slugValue + '` after `/pocketbase` update.\n' +
'- Updated vars: `' + updateResult.updatedVars.join('`, `') + '`.\n\n' +
'## Source\n' +
'- Triggered by @' + actor + ' via PocketBase bot.\n';
'## ✍️ Description\n\n' +
'Sync of the default CT variables for `' + slugValue + '` after a `/pocketbase` update by @' + actor + '.\n\n' +
'Updated: `' + updateResult.updatedVars.join('`, `') + '`\n\n' +
'## 🔗 Related Issue\n\n' +
(isPrComment ? 'Triggered from #' : 'Fixes #') + issueNumber + '\n\n' +
'## ✅ Prerequisites (**X** in brackets)\n\n' +
'- [x] **Self-review completed** Code follows project standards.\n' +
'- [ ] **Tested thoroughly** Changes work as expected.\n' +
'- [x] **No security risks** No hardcoded secrets, unnecessary privilege escalations, or permission issues.\n\n' +
'**Tested on:** not tested — generated from the PocketBase record, only `var_` defaults changed.\n\n' +
'---\n\n' +
'## 🤖 AI Assistance (**X** in brackets)\n\n' +
'- [x] **No AI used** Scripts were written without AI assistance.\n\n' +
'---\n\n' +
'## 🛠️ Type of Change (**X** in brackets)\n\n' +
'- [x] 🐞 **Bug fix** Resolves an issue without breaking functionality.\n';
const createPrRes = await ghRequest('/repos/' + owner + '/' + repo + '/pulls', 'POST', {
title: prTitle,
body: prBody,
@@ -335,7 +348,10 @@ jobs:
'`architectures` (amd64,arm64) `platforms` (pve,incus) ' +
'`execute_in` (pve,lxc,pbs,vm,pmg,pdm) `categories` (names or ids) ' +
'`type` (ct, vm, addon, …) ' +
'`is_disabled` `disable_message` `is_deleted` `deleted_message`\n\n' +
'`is_disabled` `disable_message` `is_deleted` `deleted_message` ' +
'`pin_reason` `last_update_commit`\n\n' +
'The `var_` names from the ct scripts work too: `var_cpu` `var_ram` `var_disk`\n' +
'`var_os` `var_version` `var_port` `var_tags` `var_unprivileged`\n\n' +
'**Screenshots:**\n' +
'```\n' +
'/pocketbase <slug> screenshot https://example.com/one.png https://example.com/two.png\n' +
@@ -399,6 +415,14 @@ jobs:
// ── Shared helpers ─────────────────────────────────────────────────
// The ct scripts name these var_cpu/var_ram/var_disk, and that is what
// people type. Accept them for the PocketBase keys.
const KEY_ALIASES = {
var_cpu: 'cpu', var_ram: 'ram', var_disk: 'hdd', var_hdd: 'hdd',
var_os: 'os', var_version: 'version', var_unprivileged: 'unprivileged',
var_port: 'port', var_tags: 'tags', disk: 'hdd', memory: 'ram',
};
// Key=value parser: handles unquoted and "quoted" values
function parseKVPairs(str) {
const fields = {};
@@ -426,7 +450,7 @@ jobs:
while (pos < str.length && !/\s/.test(str[pos])) pos++;
value = str.substring(valStart, pos);
}
fields[key] = value;
fields[KEY_ALIASES[key.toLowerCase()] || key] = value;
}
return fields;
}
@@ -982,6 +1006,8 @@ jobs:
disable_message: 'string',
is_deleted: 'boolean',
deleted_message: 'string',
pin_reason: 'string',
last_update_commit: 'string',
};
const parsedFields = parseKVPairs(rest);

View File

@@ -543,6 +543,30 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
</details>
## 2026-09-16
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- navidrome: repair root-owned data folders left by 0.61.x [@MickLesk](https://github.com/MickLesk) ([#17275](https://github.com/community-scripts/ProxmoxVE/pull/17275))
- tor-snowflake: read the Go version from the module root [@MickLesk](https://github.com/MickLesk) ([#17276](https://github.com/community-scripts/ProxmoxVE/pull/17276))
- docmost: stop corepack asking for confirmation during the build [@MickLesk](https://github.com/MickLesk) ([#17282](https://github.com/community-scripts/ProxmoxVE/pull/17282))
- #### ✨ New Features
- Frigate: Bump to 0.18.0 [@MickLesk](https://github.com/MickLesk) ([#17273](https://github.com/community-scripts/ProxmoxVE/pull/17273))
- Refactor: HomeAssistant-OS (core / improve functions / performance) [@MickLesk](https://github.com/MickLesk) ([#17281](https://github.com/community-scripts/ProxmoxVE/pull/17281))
- #### 🔧 Refactor
- Refactor: TrueNAS VM (core / improve functions / performance) [@MickLesk](https://github.com/MickLesk) ([#17277](https://github.com/community-scripts/ProxmoxVE/pull/17277))
### 💾 Core
- Read the IGC version compute-runtime pins, instead of taking the newest [@MickLesk](https://github.com/MickLesk) ([core#43](https://github.com/community-scripts/core/pull/43))
- Install the Intel driver dependency before the .deb that needs it [@MickLesk](https://github.com/MickLesk) ([core#42](https://github.com/community-scripts/core/pull/42))
## 2026-09-15
### 🆕 New Scripts
@@ -553,6 +577,7 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
- #### 🐞 Bug Fixes
- borg-ui: missing dependency `sshpass` [@christian-forgacs](https://github.com/christian-forgacs) ([#17286](https://github.com/community-scripts/ProxmoxVE/pull/17286))
- tracearr: copy packages/emails into the deploy tree [@connorgallopo](https://github.com/connorgallopo) ([#17268](https://github.com/community-scripts/ProxmoxVE/pull/17268))
- Immich: Pin to v3.2.1 [@vhsdream](https://github.com/vhsdream) ([#17264](https://github.com/community-scripts/ProxmoxVE/pull/17264))

View File

@@ -57,6 +57,7 @@ function update_script() {
msg_info "Configuring Docmost"
cd /opt/docmost
export COREPACK_ENABLE_DOWNLOAD_PROMPT=0
$STD pnpm install --force
$STD pnpm build
msg_ok "Configured Docmost"

View File

@@ -10,8 +10,8 @@ source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_
APP="Frigate"
var_tags="${var_tags:-nvr}"
var_cpu="${var_cpu:-8}"
var_ram="${var_ram:-4096}"
var_disk="${var_disk:-20}"
var_ram="${var_ram:-6144}"
var_disk="${var_disk:-25}"
var_os="${var_os:-debian}"
var_version="${var_version:-12}"
var_arm64="${var_arm64:-no}"

View File

@@ -38,6 +38,9 @@ function update_script() {
fetch_and_deploy_gh_release "navidrome" "navidrome/navidrome" "binary"
find /var/lib/navidrome/cache /var/lib/navidrome/artwork /var/lib/navidrome/plugins \
-maxdepth 0 -type d -user root -exec chown -h navidrome:navidrome {} + 2>/dev/null || true
msg_info "Starting Services"
systemctl start navidrome
msg_ok "Started Services"

View File

@@ -44,7 +44,8 @@ function update_script() {
msg_ok "Stopped Service"
CLEAN_INSTALL=1 GITLAB_URL="https://gitlab.torproject.org" fetch_and_deploy_gl_release "tor-snowflake" "tpo/anti-censorship/pluggable-transports/snowflake" "tarball"
GO_VERSION="$(grep -m1 '^go ' /opt/tor-snowflake/proxy/go.mod | awk '{print $2}')" setup_go
GO_VERSION="$(awk '/^go /{print $2; exit}' /opt/tor-snowflake/go.mod 2>/dev/null || true)"
GO_VERSION="${GO_VERSION:-latest}" setup_go
msg_info "Building Snowflake"
cd /opt/tor-snowflake/proxy

View File

@@ -28,7 +28,8 @@ $STD apt install -y \
fuse3 \
rsync \
sshfs \
openssh-client
openssh-client \
sshpass
msg_ok "Installed Dependencies"
UV_PYTHON="3.12" setup_uv

View File

@@ -48,6 +48,7 @@ sed -i -e "s|APP_SECRET=.*|APP_SECRET=$(openssl rand -base64 32 | tr -dc 'a-zA-Z
-e "s|^STORAGE_DRIVER=azure|#STORAGE_DRIVER=azure|" \
/opt/docmost/.env
export NODE_OPTIONS="--max-old-space-size=2048"
export COREPACK_ENABLE_DOWNLOAD_PROMPT=0
$STD pnpm install
$STD pnpm build
msg_ok "Configured Docmost"

View File

@@ -110,7 +110,7 @@ export AUTOGRAPH_VERBOSITY=0
export GLOG_minloglevel=3
export GLOG_logtostderr=0
fetch_and_deploy_gh_release "frigate" "blakeblackshear/frigate" "tarball" "v0.17.2" "/opt/frigate"
fetch_and_deploy_gh_release "frigate" "blakeblackshear/frigate" "tarball" "v0.18.0" "/opt/frigate"
msg_info "Building Nginx"
$STD bash /opt/frigate/docker/main/build_nginx.sh
@@ -122,7 +122,18 @@ msg_info "Building SQLite Extensions"
$STD bash /opt/frigate/docker/main/build_sqlite_vec.sh
msg_ok "Built SQLite Extensions"
fetch_and_deploy_gh_release "go2rtc" "AlexxIT/go2rtc" "singlefile" "latest" "/usr/local/go2rtc/bin" "go2rtc_linux_$(arch_resolve)"
if [[ "$(arch_resolve)" == "amd64" ]]; then
msg_info "Building Intel Media Driver (Patience)"
$STD bash /opt/frigate/docker/main/build_intel_media_driver.sh
cp -a /rootfs/. /
rm -rf /rootfs
rm -f /etc/apt/sources.list.d/intel-gpu-jammy.list /usr/share/keyrings/intel-graphics.gpg
$STD apt update
ldconfig
msg_ok "Built Intel Media Driver"
fi
fetch_and_deploy_gh_release "go2rtc" "AlexxIT/go2rtc" "singlefile" "v1.9.14" "/usr/local/go2rtc/bin" "go2rtc_linux_$(arch_resolve)"
msg_info "Installing Tempio"
sed -i 's|/rootfs/usr/local|/usr/local|g' /opt/frigate/docker/main/install_tempio.sh
@@ -194,17 +205,7 @@ if python3 /opt/frigate/docker/main/build_ov_model.py &>/dev/null; then
mkdir -p /openvino-model
cp /models/ssdlite_mobilenet_v2.xml /openvino-model/
cp /models/ssdlite_mobilenet_v2.bin /openvino-model/
OV_LABELS=$(python3 -c "import omz_tools; import os; print(os.path.join(omz_tools.__path__[0], 'data/dataset_classes/coco_91cl_bkgr.txt'))" 2>/dev/null)
if [[ -n "$OV_LABELS" && -f "$OV_LABELS" ]]; then
ln -sf "$OV_LABELS" /openvino-model/coco_91cl_bkgr.txt
else
OV_LABELS=$(find /usr/local/lib -name "coco_91cl_bkgr.txt" 2>/dev/null | head -1)
if [[ -n "$OV_LABELS" ]]; then
ln -sf "$OV_LABELS" /openvino-model/coco_91cl_bkgr.txt
else
curl_with_retry "https://raw.githubusercontent.com/openvinotoolkit/open_model_zoo/master/data/dataset_classes/coco_91cl_bkgr.txt" "/openvino-model/coco_91cl_bkgr.txt"
fi
fi
curl_with_retry "https://raw.githubusercontent.com/openvinotoolkit/open_model_zoo/master/data/dataset_classes/coco_91cl_bkgr.txt" "/openvino-model/coco_91cl_bkgr.txt"
sed -i 's/truck/car/g' /openvino-model/coco_91cl_bkgr.txt
msg_ok "Built OpenVino Model"
else
@@ -251,8 +252,8 @@ curl_download "/media/frigate/person-bicycle-car-detection.mp4" "https://github.
echo "tmpfs /tmp/cache tmpfs defaults 0 0" >>/etc/fstab
cat <<EOF >/etc/frigate.env
DEFAULT_FFMPEG_VERSION="7.0"
INCLUDED_FFMPEG_VERSIONS="7.0:5.0"
DEFAULT_FFMPEG_VERSION="8.0"
INCLUDED_FFMPEG_VERSIONS="8.0:7.0:5.0"
NVIDIA_VISIBLE_DEVICES=all
NVIDIA_DRIVER_CAPABILITIES="compute,video,utility"
TOKENIZERS_PARALLELISM=true
@@ -268,6 +269,23 @@ GLOG_minloglevel=3
GLOG_logtostderr=0
EOF
if grep -q -o -m1 -E 'avx[^ ]*|sse4_2' /proc/cpuinfo && [[ -f /openvino-model/ssdlite_mobilenet_v2.xml ]] && [[ -f /openvino-model/coco_91cl_bkgr.txt ]]; then
DETECTOR_CONFIG="detectors:
detector01:
type: openvino
device: AUTO
model:
width: 300
height: 300
input_tensor: nhwc
input_pixel_format: bgr
path: /openvino-model/ssdlite_mobilenet_v2.xml
labelmap_path: /openvino-model/coco_91cl_bkgr.txt"
else
DETECTOR_CONFIG="model:
path: /models/cpu_model.tflite"
fi
cat <<EOF >/config/config.yml
mqtt:
enabled: false
@@ -287,32 +305,10 @@ auth:
enabled: false
detect:
enabled: false
EOF
if grep -q -o -m1 -E 'avx[^ ]*|sse4_2' /proc/cpuinfo && [[ -f /openvino-model/ssdlite_mobilenet_v2.xml ]] && [[ -f /openvino-model/coco_91cl_bkgr.txt ]]; then
cat <<EOF >/config/config.yml
ffmpeg:
hwaccel_args: auto
detectors:
detector01:
type: openvino
device: AUTO
model:
width: 300
height: 300
input_tensor: nhwc
input_pixel_format: bgr
path: /openvino-model/ssdlite_mobilenet_v2.xml
labelmap_path: /openvino-model/coco_91cl_bkgr.txt
${DETECTOR_CONFIG}
EOF
else
cat <<EOF >/config/config.yml
ffmpeg:
hwaccel_args: auto
model:
path: /models/cpu_model.tflite
EOF
fi
msg_ok "Configured Frigate"
msg_info "Creating Services"

View File

@@ -16,7 +16,8 @@ update_os
msg_info "Building Snowflake"
GITLAB_URL="https://gitlab.torproject.org" fetch_and_deploy_gl_release "tor-snowflake" "tpo/anti-censorship/pluggable-transports/snowflake" "tarball"
GO_VERSION="$(grep -m1 '^go ' /opt/tor-snowflake/proxy/go.mod | awk '{print $2}')" setup_go
GO_VERSION="$(awk '/^go /{print $2; exit}' /opt/tor-snowflake/go.mod 2>/dev/null || true)"
GO_VERSION="${GO_VERSION:-latest}" setup_go
cd /opt/tor-snowflake/proxy
$STD go build -o snowflake-proxy .
msg_ok "Built Snowflake Proxy"

6
vm/headers/truenas Normal file
View File

@@ -0,0 +1,6 @@
______ _ _____ _____
/_ __/______ _____ / | / / | / ___/
/ / / ___/ / / / _ \/ |/ / /| | \__ \
/ / / / / /_/ / __/ /| / ___ |___/ /
/_/ /_/ \__,_/\___/_/ |_/_/ |_/____/

View File

@@ -1,64 +1,26 @@
#!/usr/bin/env bash
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: juronja
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://www.truenas.com/truenas-community-edition/
source /dev/stdin <<<$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func)
COMMUNITY_SCRIPTS_URL="${COMMUNITY_SCRIPTS_URL:-https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main}"
source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/pve/vm-core.func")
load_functions
function header_info() {
clear
cat <<"EOF"
______ _ _____ _____
/_ __/______ _____ / | / / | / ___/
/ / / ___/ / / / _ \/ |/ / /| | \__ \
/ / / / / /_/ / __/ /| / ___ |___/ /
/_/ /_/ \__,_/\___/_/ |_/_/ |_/____/
(Community Edition)
EOF
}
header_info
echo -e "\n Loading..."
GEN_MAC=02:$(openssl rand -hex 5 | awk '{print toupper($0)}' | sed 's/\(..\)/\1:/g; s/.$//')
RANDOM_UUID="$(cat /proc/sys/kernel/random/uuid)"
METHOD=""
APP="TrueNAS"
APP_TYPE="vm"
NSAPP="truenas-vm"
YW=$(echo "\033[33m")
BL=$(echo "\033[36m")
RD=$(echo "\033[01;31m")
BGN=$(echo "\033[4;92m")
GN=$(echo "\033[1;92m")
DGN=$(echo "\033[32m")
CL=$(echo "\033[m")
header_info
echo -e "\n Loading..."
CL=$(echo "\033[m")
BOLD=$(echo "\033[1m")
BFR="\\r\\033[K"
HOLD=" "
TAB=" "
CM="${TAB}✔️${TAB}${CL}"
CROSS="${TAB}✖️${TAB}${CL}"
INFO="${TAB}💡${TAB}${CL}"
OS="${TAB}🖥️${TAB}${CL}"
CONTAINERTYPE="${TAB}📦${TAB}${CL}"
ISO="${TAB}📀${TAB}${CL}"
DISKSIZE="${TAB}💾${TAB}${CL}"
CPUCORE="${TAB}🧠${TAB}${CL}"
RAMSIZE="${TAB}🛠️${TAB}${CL}"
CONTAINERID="${TAB}🆔${TAB}${CL}"
HOSTNAME="${TAB}🏠${TAB}${CL}"
BRIDGE="${TAB}🌉${TAB}${CL}"
GATEWAY="${TAB}🌐${TAB}${CL}"
DISK="${TAB}💽${TAB}${CL}"
DEFAULT="${TAB}⚙️${TAB}${CL}"
MACADDRESS="${TAB}🔗${TAB}${CL}"
VLANTAG="${TAB}🏷️${TAB}${CL}"
CREATING="${TAB}🚀${TAB}${CL}"
ADVANCED="${TAB}🧩${TAB}${CL}"
CLOUD="${TAB}☁️${TAB}${CL}"
set -e
trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
@@ -66,15 +28,6 @@ trap cleanup EXIT
trap 'post_update_to_api "failed" "130"' SIGINT
trap 'post_update_to_api "failed" "143"' SIGTERM
trap 'post_update_to_api "failed" "129"; exit 129' SIGHUP
function error_handler() {
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}"
post_update_to_api "failed" "${command}"
echo -e "\n$error_message\n"
cleanup_vmid
}
function truenas_iso_lookup() {
local BASE_URL="https://download.truenas.com"
@@ -100,7 +53,7 @@ function truenas_iso_lookup() {
pre_releases+=("$path")
else
local major_version=$(echo "$version" | cut -d'.' -f1,2)
local current_stored_path=${latest_stables["$major_version"]}
local current_stored_path=${latest_stables["$major_version"]:-}
if [[ -z "$current_stored_path" ]]; then
latest_stables["$major_version"]="$path"
else
@@ -121,135 +74,17 @@ function truenas_iso_lookup() {
done | sort -V
}
function get_valid_nextid() {
local try_id
try_id=$(pvesh get /cluster/nextid)
while true; do
if [ -f "/etc/pve/qemu-server/${try_id}.conf" ] || [ -f "/etc/pve/lxc/${try_id}.conf" ]; then
try_id=$((try_id + 1))
continue
fi
if lvs --noheadings -o lv_name | grep -qE "(^|[-_])${try_id}($|[-_])"; then
try_id=$((try_id + 1))
continue
fi
break
done
echo "$try_id"
}
function cleanup_vmid() {
if qm status $VMID &>/dev/null; then
qm stop $VMID &>/dev/null
qm destroy $VMID &>/dev/null
fi
}
function cleanup() {
popd >/dev/null
post_update_to_api "done" "none"
rm -rf $TEMP_DIR
}
TEMP_DIR=$(mktemp -d)
pushd $TEMP_DIR >/dev/null
if whiptail --backtitle "Proxmox VE Helper Scripts" --title "TrueNAS VM" --yesno "This will create a New TrueNAS VM. Proceed?" 10 58; then
:
else
header_info && echo -e "${CROSS}${RD}User exited script${CL}\n" && exit
fi
function msg_info() {
local msg="$1"
echo -ne "${TAB}${YW}${HOLD}${msg}${HOLD}"
}
function msg_ok() {
local msg="$1"
echo -e "${BFR}${CM}${GN}${msg}${CL}"
}
function msg_error() {
local msg="$1"
echo -e "${BFR}${CROSS}${RD}${msg}${CL}"
}
function check_root() {
if [[ "$(id -u)" -ne 0 || $(ps -o comm= -p $PPID) == "sudo" ]]; then
clear
msg_error "Please run this script as root."
echo -e "\nExiting..."
sleep 2
exit
fi
}
function pve_check() {
local PVE_VER
PVE_VER="$(pveversion | awk -F'/' '{print $2}' | awk -F'-' '{print $1}')"
if [[ "$PVE_VER" =~ ^8\.([0-9]+) ]]; then
local MINOR="${BASH_REMATCH[1]}"
if ((MINOR < 0 || MINOR > 9)); then
msg_error "This version of Proxmox VE is not supported."
msg_error "Supported: Proxmox VE version 8.0 8.9"
exit 105
fi
return 0
fi
if [[ "$PVE_VER" =~ ^9\.([0-9]+) ]]; then
local MINOR="${BASH_REMATCH[1]}"
if ((MINOR < 0 || MINOR > 2)); then
msg_error "This version of Proxmox VE is not yet supported."
msg_error "Supported: Proxmox VE version 9.0 9.2"
exit 105
fi
return 0
fi
msg_error "This version of Proxmox VE is not supported."
msg_error "Supported versions: Proxmox VE 8.0 8.x or 9.0 9.2"
exit 105
}
function arch_check() {
if [ "$(dpkg --print-architecture)" != "amd64" ]; then
echo -e "\n ${INFO}${YWB}This script will not work with PiMox! \n"
echo -e "\n ${YWB}Visit https://github.com/asylumexp/Proxmox for ARM64 support. \n"
echo -e "Exiting..."
sleep 2
exit
fi
}
function ssh_check() {
if command -v pveversion >/dev/null 2>&1; then
if [ -n "${SSH_CLIENT:+x}" ]; then
if whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "SSH DETECTED" --yesno "It's suggested to use the Proxmox shell instead of SSH, since SSH can create issues while gathering variables. Would you like to proceed with using SSH?" 10 62; then
echo "you've been warned"
else
clear
exit
fi
fi
fi
}
function exit-script() {
clear
echo -e "\n${CROSS}${RD}User exited script${CL}\n"
exit
}
function default_settings() {
VMID=$(get_valid_nextid)
ISO_DEFAULT="latest stable"
FORMAT=""
MACHINE="q35"
vm_apply_machine_type "q35"
DISK_SIZE="16"
DISK_CACHE=""
HN="truenas"
CPU_TYPE="host"
CPU_TYPE=" -cpu host"
CORE_COUNT="2"
RAM_SIZE="8192"
BRG="vmbr0"
@@ -257,242 +92,38 @@ function default_settings() {
VLAN=""
MTU=""
START_VM="yes"
IMPORT_DISKS="no"
METHOD="default"
echo -e "${CONTAINERID}${BOLD}${DGN}Virtual Machine ID: ${BGN}${VMID}${CL}"
echo -e "${ISO}${BOLD}${DGN}ISO Chosen: ${BGN}${ISO_DEFAULT}${CL}"
echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}${MACHINE}${CL}"
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE}${CL}"
echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}${HN}${CL}"
echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}${CPU_TYPE}${CL}"
echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}${CORE_COUNT}${CL}"
echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE}${CL}"
echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}${BRG}${CL}"
echo -e "${MACADDRESS}${BOLD}${DGN}MAC Address: ${BGN}${MAC}${CL}"
echo -e "${VLANTAG}${BOLD}${DGN}VLAN: ${BGN}Default${CL}"
echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}Default${CL}"
echo -e "${GATEWAY}${BOLD}${DGN}Start VM when completed: ${BGN}yes${CL}"
echo -e "${CREATING}${BOLD}${DGN}Creating a TrueNAS VM using the above default settings${CL}"
vm_echo_default_settings
}
function advanced_settings() {
DISK_SIZE="16"
HN="truenas"
CORE_COUNT="2"
RAM_SIZE="8192"
BRG="vmbr0"
METHOD="advanced"
[ -z "${VMID:-}" ] && VMID=$(get_valid_nextid)
while true; do
if VMID=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Virtual Machine ID" 8 58 $VMID --title "VIRTUAL MACHINE ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
if [ -z "$VMID" ]; then
VMID=$(get_valid_nextid)
fi
if pct status "$VMID" &>/dev/null || qm status "$VMID" &>/dev/null; then
echo -e "${CROSS}${RD} ID $VMID is already in use${CL}"
sleep 2
continue
fi
echo -e "${CONTAINERID}${BOLD}${DGN}Virtual Machine ID: ${BGN}$VMID${CL}"
break
else
exit-script
fi
done
vm_prompt_vmid "${VMID:-$(get_valid_nextid)}"
vm_prompt_machine_type "q35"
vm_prompt_disk_size "16G" "Set Disk Size in GiB (e.g., 16, 32)"
vm_prompt_disk_cache "none"
vm_prompt_hostname "truenas"
vm_prompt_cpu_model "host"
vm_prompt_cpu_cores "2"
vm_prompt_ram "8192"
vm_prompt_bridge "vmbr0"
vm_prompt_mac "$GEN_MAC"
vm_prompt_vlan
vm_prompt_mtu
vm_prompt_verbose "no"
ISOARRAY=()
mapfile -t ALL_ISOS < <(truenas_iso_lookup | sort -V)
ISO_COUNT=${#ALL_ISOS[@]}
if [ $ISO_COUNT -eq 0 ]; then
echo "No ISOs found."
exit 115
fi
# Identify the index of the last stable release
LAST_STABLE_INDEX=-1
for i in "${!ALL_ISOS[@]}"; do
if [[ ! "${ALL_ISOS[$i]}" =~ (BETA|RC) ]]; then
LAST_STABLE_INDEX=$i
fi
done
# Build the whiptail array
for i in "${!ALL_ISOS[@]}"; do
ISOPATH="${ALL_ISOS[$i]}"
FILENAME=$(basename "$ISOPATH")
# Select ON if it's the last stable found, OR fallback to last item if no stable exists
if [[ "$i" -eq "$LAST_STABLE_INDEX" ]]; then
ISOARRAY+=("$ISOPATH" "$FILENAME" "ON")
elif [[ "$LAST_STABLE_INDEX" -eq -1 && "$i" -eq "$((ISO_COUNT - 1))" ]]; then
# Fallback: if somehow no stable is found, select the very last item
ISOARRAY+=("$ISOPATH" "$FILENAME" "ON")
else
ISOARRAY+=("$ISOPATH" "$FILENAME" "OFF")
fi
done
if SELECTED_ISO=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SELECT ISO TO INSTALL" --notags --radiolist "\nSelect version (BETA/RC/Latest stable):" 20 58 12 "${ISOARRAY[@]}" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
echo -e "${ISO}${BOLD}${DGN}ISO Chosen: ${BGN}$(basename "$SELECTED_ISO")${CL}"
else
exit-script
fi
if DISK_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Disk Size in GiB (e.g., 10, 20)" 8 58 "$DISK_SIZE" --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
DISK_SIZE=$(echo "$DISK_SIZE" | tr -d ' ')
if [[ "$DISK_SIZE" =~ ^[0-9]+$ ]]; then
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}$DISK_SIZE${CL}"
else
echo -e "${DISKSIZE}${BOLD}${RD}Invalid Disk Size. Please use a number (e.g., 10).${CL}"
exit-script
fi
else
exit-script
fi
if VM_NAME=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Hostname" 8 58 "$HN" --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
if [ -z $VM_NAME ]; then
echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}$HN${CL}"
else
HN=$(echo "${VM_NAME,,}" | tr -cs 'a-z0-9-' '-' | sed 's/^-//;s/-$//')
if [ "$HN" != "${VM_NAME,,}" ]; then
whiptail --backtitle "Proxmox VE Helper Scripts" --title "HOSTNAME ADJUSTED" --msgbox "Invalid characters detected. Hostname has been adjusted to:\n\n $HN" 10 58
fi
echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}$HN${CL}"
fi
else
exit-script
fi
if CPU_TYPE1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "CPU MODEL" --radiolist "Choose CPU Model" --cancel-button Exit-Script 10 58 2 \
"KVM64" "Default safe for migration/compatibility" OFF \
"Host" "Use host CPU features (faster, no migration)" ON \
3>&1 1>&2 2>&3); then
case "$CPU_TYPE1" in
Host)
echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}Host${CL}"
CPU_TYPE="host"
;;
*)
echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}KVM64${CL}"
CPU_TYPE=""
;;
esac
else
exit-script
fi
while true; do
if CORE_COUNT=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate CPU Cores" 8 58 "$CORE_COUNT" --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
if [ -z "$CORE_COUNT" ]; then CORE_COUNT="2"; fi
if [[ "$CORE_COUNT" =~ ^[1-9][0-9]*$ ]]; then
echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}$CORE_COUNT${CL}"
break
fi
whiptail --backtitle "Proxmox VE Helper Scripts" --title "INVALID INPUT" --msgbox "CPU Cores must be a positive integer (e.g., 2)." 8 58
else
exit-script
fi
done
while true; do
if RAM_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate RAM in MiB" 8 58 "$RAM_SIZE" --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
if [ -z "$RAM_SIZE" ]; then RAM_SIZE="8192"; fi
if [[ "$RAM_SIZE" =~ ^[1-9][0-9]*$ ]]; then
echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}$RAM_SIZE${CL}"
break
fi
whiptail --backtitle "Proxmox VE Helper Scripts" --title "INVALID INPUT" --msgbox "RAM Size must be a positive integer in MiB (e.g., 8192)." 8 58
else
exit-script
fi
done
if BRG=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Bridge" 8 58 "$BRG" --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
if [ -z $BRG ]; then
BRG="vmbr0"
echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}"
else
echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}"
fi
else
exit-script
fi
while true; do
if MAC1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
if [ -z "$MAC1" ]; then
MAC="$GEN_MAC"
echo -e "${MACADDRESS}${BOLD}${DGN}MAC Address: ${BGN}$MAC${CL}"
break
fi
if [[ "$MAC1" =~ ^([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}$ ]]; then
MAC="$MAC1"
echo -e "${MACADDRESS}${BOLD}${DGN}MAC Address: ${BGN}$MAC1${CL}"
break
fi
whiptail --backtitle "Proxmox VE Helper Scripts" --title "INVALID INPUT" --msgbox "Invalid MAC address format. Use XX:XX:XX:XX:XX:XX (e.g., AA:BB:CC:DD:EE:FF)." 8 58
else
exit-script
fi
done
while true; do
if VLAN1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
if [ -z "$VLAN1" ]; then
VLAN1="Default"
VLAN=""
echo -e "${VLANTAG}${BOLD}${DGN}VLAN: ${BGN}$VLAN1${CL}"
break
fi
if [[ "$VLAN1" =~ ^[0-9]+$ ]] && [ "$VLAN1" -ge 1 ] && [ "$VLAN1" -le 4094 ]; then
VLAN=",tag=$VLAN1"
echo -e "${VLANTAG}${BOLD}${DGN}VLAN: ${BGN}$VLAN1${CL}"
break
fi
whiptail --backtitle "Proxmox VE Helper Scripts" --title "INVALID INPUT" --msgbox "VLAN must be a number between 1 and 4094, or leave blank for default." 8 58
else
exit-script
fi
done
while true; do
if MTU1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
if [ -z "$MTU1" ]; then
MTU1="Default"
MTU=""
echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}$MTU1${CL}"
break
fi
if [[ "$MTU1" =~ ^[0-9]+$ ]] && [ "$MTU1" -ge 576 ] && [ "$MTU1" -le 65520 ]; then
MTU=",mtu=$MTU1"
echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}$MTU1${CL}"
break
fi
whiptail --backtitle "Proxmox VE Helper Scripts" --title "INVALID INPUT" --msgbox "MTU Size must be a number between 576 and 65520, or leave blank for default." 8 58
else
exit-script
fi
done
if (whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "IMPORT ONBOARD DISKS" --yesno "Would you like to import onboard disks?" 10 58); then
echo -e "${DISK}${BOLD}${DGN}Import onboard disks: ${BGN}yes${CL}"
if vm_dialog yesno "IMPORT ONBOARD DISKS" --defaultno "Would you like to import onboard disks?" 10 58; then
IMPORT_DISKS="yes"
else
echo -e "${DISK}${BOLD}${DGN}Import onboard disks: ${BGN}no${CL}"
IMPORT_DISKS="no"
fi
echo -e "${DISK}${BOLD}${DGN}Import onboard disks: ${BGN}${IMPORT_DISKS}${CL}"
if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "START VIRTUAL MACHINE" --yesno "Start VM when completed?" 10 58); then
echo -e "${GATEWAY}${BOLD}${DGN}Start VM when completed: ${BGN}yes${CL}"
START_VM="yes"
else
echo -e "${GATEWAY}${BOLD}${DGN}Start VM when completed: ${BGN}no${CL}"
START_VM="no"
fi
vm_prompt_start_vm "yes"
if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create a TrueNAS VM?" --no-button Do-Over 10 58); then
if vm_confirm_advanced_settings "Ready to create a TrueNAS VM?"; then
echo -e "${CREATING}${BOLD}${DGN}Creating a TrueNAS VM using the above advanced settings${CL}"
else
header_info
@@ -501,54 +132,11 @@ function advanced_settings() {
fi
}
function start_script() {
if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then
header_info
echo -e "${DEFAULT}${BOLD}${BL}Using Default Settings${CL}"
default_settings
else
header_info
echo -e "${ADVANCED}${BOLD}${RD}Using Advanced Settings${CL}"
advanced_settings
fi
}
check_root
arch_check
pve_check
ssh_check
start_script
vm_preflight
vm_start_script "Use Default Settings?" 10 58
post_to_api_vm
msg_info "Validating Storage"
while read -r line; do
TAG=$(echo $line | awk '{print $1}')
TYPE=$(echo $line | awk '{printf "%-10s", $2}')
FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}')
ITEM=" Type: $TYPE Free: $FREE "
OFFSET=2
if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then
MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET))
fi
STORAGE_MENU+=("$TAG" "$ITEM" "OFF")
done < <(pvesm status -content images | awk 'NR>1')
VALID=$(pvesm status -content images | awk 'NR>1')
if [ -z "$VALID" ]; then
msg_error "Unable to detect a valid storage location."
exit
elif [ $((${#STORAGE_MENU[@]} / 3)) -eq 1 ]; then
STORAGE=${STORAGE_MENU[0]}
else
while [ -z "${STORAGE:+x}" ]; do
if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID >/dev/null; then kill $SPINNER_PID >/dev/null; fi
printf "\e[?25h"
STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \
"Which storage pool would you like to use for ${HN}?\nTo make a selection, use the Spacebar.\n" \
16 $(($MSG_MAX_LENGTH + 23)) 6 \
"${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3)
done
fi
msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location."
msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}."
vm_select_storage "$HN"
if [ -z "${SELECTED_ISO:-}" ]; then
SELECTED_ISO=$(truenas_iso_lookup | grep -vE 'RC|BETA' | sort -V | tail -n 1)
@@ -564,21 +152,17 @@ ISO_NAME=$(basename "$FULL_URL")
CACHE_DIR="/var/lib/vz/template/iso"
CACHE_FILE="$CACHE_DIR/$ISO_NAME"
if [[ ! -s "$CACHE_FILE" ]]; then
msg_info "Retrieving the ISO for the TrueNAS Disk Image"
curl -f#SL -o "$CACHE_FILE" "$FULL_URL"
msg_ok "Downloaded ${CL}${BL}$(basename "$CACHE_FILE")${CL}"
else
msg_ok "Using cached image ${CL}${BL}$(basename "$CACHE_FILE")${CL}"
fi
msg_info "Retrieving the ISO for the TrueNAS Disk Image"
MIN_ISO_BYTES=$((500 * 1024 * 1024))
vm_fetch_image "$FULL_URL" "$CACHE_FILE" --cache --min-bytes "$MIN_ISO_BYTES" || exit 115
set -o pipefail
msg_info "Creating TrueNAS VM shell"
qm create "$VMID" -machine q35 -bios ovmf -agent enabled=1 -tablet 0 -localtime 1 -cpu "$CPU_TYPE" \
qm create "$VMID"${MACHINE} -bios ovmf -agent enabled=1 -tablet 0 -localtime 1${CPU_TYPE} \
-cores "$CORE_COUNT" -memory "$RAM_SIZE" -balloon 0 -name "$HN" -tags community-script \
-net0 "virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU" -onboot 1 -ostype l26 \
-efidisk0 $STORAGE:1,efitype=4m,pre-enrolled-keys=0 -sata0 $STORAGE:$DISK_SIZE,ssd=1 \
-scsihw virtio-scsi-single -cdrom local:iso/$ISO_NAME -vga virtio >/dev/null
-scsihw virtio-scsi-single -cdrom local:iso/$ISO_NAME -boot order='sata0;ide2' -vga virtio >/dev/null
msg_ok "Created VM shell"
if [ "$IMPORT_DISKS" == "yes" ]; then
@@ -594,7 +178,9 @@ if [ "$IMPORT_DISKS" == "yes" ]; then
DISKARRAY+=("$LSOUTPUT" "$TRUNCATED" "OFF")
done < <(ls /dev/disk/by-id | grep -E '^ata-|^nvme-|^usb-' | grep -v 'part')
SELECTIONS=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SELECT DISKS TO IMPORT" --checklist "\nSelect disk IDs to import. (Use Spacebar to select)\n" --notags --cancel-button "Exit Script" 20 58 10 "${DISKARRAY[@]}" 3>&1 1>&2 2>&3 | tr -d '"') || exit
vm_dialog checklist "SELECT DISKS TO IMPORT" --notags --cancel-button "Exit Script" \
"\nSelect disk IDs to import. (Use Spacebar to select)\n" 20 58 10 "${DISKARRAY[@]}" || exit
SELECTIONS=$(echo "$VM_DIALOG_RESULT" | tr -d '"')
for SELECTION in $SELECTIONS; do
((++SCSI_NR))
@@ -607,44 +193,14 @@ if [ "$IMPORT_DISKS" == "yes" ]; then
msg_ok "Disks imported successfully"
fi
DESCRIPTION=$(
cat <<EOF
<div align='center'>
<a href='https://community-scripts.org' target='_blank' rel='noopener noreferrer'>
<img src='https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/images/logo-81x112.png' alt='Logo' style='width:81px;height:112px;'/>
</a>
<h2 style='font-size: 24px; margin: 20px 0;'>TrueNAS Community Edition</h2>
<p style='margin: 16px 0;'>
<a href='https://ko-fi.com/community_scripts' target='_blank' rel='noopener noreferrer'>
<img src='https://img.shields.io/badge/&#x2615;-Buy us a coffee-blue' alt='spend Coffee' />
</a>
</p>
<span style='margin: 0 10px;'>
<i class="fa fa-github fa-fw" style="color: #f5f5f5;"></i>
<a href='https://github.com/community-scripts/ProxmoxVE' target='_blank' rel='noopener noreferrer' style='text-decoration: none; color: #00617f;'>GitHub</a>
</span>
<span style='margin: 0 10px;'>
<i class="fa fa-comments fa-fw" style="color: #f5f5f5;"></i>
<a href='https://github.com/community-scripts/ProxmoxVE/discussions' target='_blank' rel='noopener noreferrer' style='text-decoration: none; color: #00617f;'>Discussions</a>
</span>
<span style='margin: 0 10px;'>
<i class="fa fa-exclamation-circle fa-fw" style="color: #f5f5f5;"></i>
<a href='https://github.com/community-scripts/ProxmoxVE/issues' target='_blank' rel='noopener noreferrer' style='text-decoration: none; color: #00617f;'>Issues</a>
</span>
</div>
EOF
)
qm set "$VMID" -description "$DESCRIPTION" >/dev/null
set_description
sleep 3
msg_ok "Created a TrueNAS VM ${CL}${BL}(${HN})"
if [ "$START_VM" == "yes" ]; then
msg_info "Starting TrueNAS VM"
qm start $VMID
$STD qm start $VMID
msg_ok "Started TrueNAS VM"
fi