Compare commits

...

43 Commits

Author SHA1 Message Date
CanbiZ
9ead3a2a32 Improve Node.js upgrade and service recovery in update.sh
Enhances the Node.js upgrade process by handling both .list and .sources files, updating the apt cache, and adding error handling for download and install failures. Introduces a function to re-enable and start the systemd service on failure to prevent user lockout, and ensures this is called during rollback and upgrade errors. Also refines Node.js version checks and build environment setup.
2026-01-13 16:52:22 +01:00
dependabot[bot]
6fe2a790fd build(deps): Bump @xterm/xterm from 5.5.0 to 6.0.0 (#431)
Bumps [@xterm/xterm](https://github.com/xtermjs/xterm.js) from 5.5.0 to 6.0.0.
- [Release notes](https://github.com/xtermjs/xterm.js/releases)
- [Commits](https://github.com/xtermjs/xterm.js/compare/5.5.0...6.0.0)

---
updated-dependencies:
- dependency-name: "@xterm/xterm"
  dependency-version: 6.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-13 16:47:18 +01:00
Bryan Lieberman
5ea71837e7 Fix nodejs update failure (#435)
* fix: update fails during NodeJS Version check

- Removed redundant NodeJS Update call

* fix: update fails after nodejs version check (#429)

- Removed redundant nodejs update call
2026-01-13 16:47:05 +01:00
dependabot[bot]
bf5ebc72b6 build(deps-dev): Bump @vitest/coverage-v8 from 4.0.15 to 4.0.16 (#434)
Bumps [@vitest/coverage-v8](https://github.com/vitest-dev/vitest/tree/HEAD/packages/coverage-v8) from 4.0.15 to 4.0.16.
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.0.16/packages/coverage-v8)

---
updated-dependencies:
- dependency-name: "@vitest/coverage-v8"
  dependency-version: 4.0.16
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-13 16:46:25 +01:00
dependabot[bot]
a32c7bcbba build(deps): Bump lucide-react from 0.561.0 to 0.562.0 (#433)
Bumps [lucide-react](https://github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-react) from 0.561.0 to 0.562.0.
- [Release notes](https://github.com/lucide-icons/lucide/releases)
- [Commits](https://github.com/lucide-icons/lucide/commits/0.562.0/packages/lucide-react)

---
updated-dependencies:
- dependency-name: lucide-react
  dependency-version: 0.562.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-13 16:46:14 +01:00
dependabot[bot]
98c6e79db6 build(deps-dev): Bump @testing-library/react from 16.3.0 to 16.3.1 (#432)
Bumps [@testing-library/react](https://github.com/testing-library/react-testing-library) from 16.3.0 to 16.3.1.
- [Release notes](https://github.com/testing-library/react-testing-library/releases)
- [Changelog](https://github.com/testing-library/react-testing-library/blob/main/CHANGELOG.md)
- [Commits](https://github.com/testing-library/react-testing-library/compare/v16.3.0...v16.3.1)

---
updated-dependencies:
- dependency-name: "@testing-library/react"
  dependency-version: 16.3.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-13 16:46:05 +01:00
dependabot[bot]
c962a9cd5a build(deps): Bump @xterm/addon-web-links from 0.11.0 to 0.12.0 (#430)
Bumps [@xterm/addon-web-links](https://github.com/xtermjs/xterm.js) from 0.11.0 to 0.12.0.
- [Release notes](https://github.com/xtermjs/xterm.js/releases)
- [Commits](https://github.com/xtermjs/xterm.js/compare/0.11...0.12)

---
updated-dependencies:
- dependency-name: "@xterm/addon-web-links"
  dependency-version: 0.12.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-13 16:45:53 +01:00
CanbiZ
5d20a6d694 fix: allow update without existing database file
Database verification now allows missing database files for new
installations. The app will create the database automatically
via Prisma migrations on first start.
2026-01-07 20:54:16 +01:00
github-actions[bot]
cb4e8c543a chore: add VERSION v0.5.3 (#428)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-07 19:52:06 +00:00
CanbiZ (MickLesk)
2ba213de49 fix: pct create fails with malformed arguments (#423) (#427)
- Fix NS/MTU/MAC/VLAN/SD variables missing proper prefixes in base_settings()
  Variables were passed as raw values instead of formatted pct options
  (e.g., '192.168.1.1' instead of '-nameserver=192.168.1.1')

- Strip spaces from nameserver values to prevent 'too many arguments' error
  Multiple DNS servers must be comma-separated without spaces

- Auto-create database directory before Prisma initialization
  Fixes 'Cannot open database because directory does not exist' error
  for manual Git installations
2026-01-07 20:50:51 +01:00
CanbiZ (MickLesk)
849aabb575 update footer to 2026 (#426) 2026-01-07 20:45:45 +01:00
CanbiZ (MickLesk)
dd33df2033 Update Core to 2026 State-Of-The Art (ProxmoxVE Upstream Merge) (#425)
* update core.func

* Add advanced container features and IP range scanning

Introduces support for scanning and assigning the first free IP from a user-specified range, and expands advanced LXC container settings to include GPU passthrough, TUN/TAP, nesting, keyctl, mknod, timezone, protection, and APT cacher options. Refactors advanced_settings wizard to support these new features, updates variable handling and defaults, and improves summary and output formatting. Also enhances SSH key configuration, storage/template validation, and GPU passthrough logic.

* update install.func

* Enhance hardware acceleration and MariaDB setup

Refactors and expands the hardware acceleration setup to support multiple GPU types (Intel, AMD, NVIDIA), adds user selection for GPU configuration, and improves driver installation logic for Debian and Ubuntu. Adds runtime directory persistence for MariaDB using tmpfiles.d to ensure /run/mysqld exists after reboot. Includes minor robustness improvements and error handling throughout the script.

* Update error-handler.func

* Update copyright years to 2026 in core scripts

Updated the copyright year from 2025 to 2026 in alpine-install.func, api.func, and cloud-init.func to reflect the new year. No functional changes were made.
2026-01-07 20:43:49 +01:00
dependabot[bot]
94eb2820fd build(deps): Bump @trpc/react-query from 11.7.2 to 11.8.0 (#417)
Bumps [@trpc/react-query](https://github.com/trpc/trpc/tree/HEAD/packages/react) from 11.7.2 to 11.8.0.
- [Release notes](https://github.com/trpc/trpc/releases)
- [Commits](https://github.com/trpc/trpc/commits/v11.8.0/packages/react)

---
updated-dependencies:
- dependency-name: "@trpc/react-query"
  dependency-version: 11.8.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-07 20:35:00 +01:00
dependabot[bot]
e49708770c build(deps-dev): Bump @types/node from 24.10.1 to 24.10.4 (#418)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 24.10.1 to 24.10.4.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 24.10.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-07 20:33:48 +01:00
dependabot[bot]
5eafa01843 build(deps-dev): Bump @tailwindcss/postcss from 4.1.17 to 4.1.18 (#416)
Bumps [@tailwindcss/postcss](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-postcss) from 4.1.17 to 4.1.18.
- [Release notes](https://github.com/tailwindlabs/tailwindcss/releases)
- [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.1.18/packages/@tailwindcss-postcss)

---
updated-dependencies:
- dependency-name: "@tailwindcss/postcss"
  dependency-version: 4.1.18
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-07 20:33:35 +01:00
dependabot[bot]
0c1477e087 build(deps-dev): Bump eslint-config-next from 16.0.7 to 16.1.0 (#415)
Bumps [eslint-config-next](https://github.com/vercel/next.js/tree/HEAD/packages/eslint-config-next) from 16.0.7 to 16.1.0.
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/commits/v16.1.0/packages/eslint-config-next)

---
updated-dependencies:
- dependency-name: eslint-config-next
  dependency-version: 16.1.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-07 20:33:28 +01:00
dependabot[bot]
ef73d98873 build(deps): Bump @trpc/server (#413)
Bumps the npm_and_yarn group with 1 update in the / directory: [@trpc/server](https://github.com/trpc/trpc/tree/HEAD/packages/server).


Updates `@trpc/server` from 11.7.2 to 11.8.0
- [Release notes](https://github.com/trpc/trpc/releases)
- [Commits](https://github.com/trpc/trpc/commits/v11.8.0/packages/server)

---
updated-dependencies:
- dependency-name: "@trpc/server"
  dependency-version: 11.8.0
  dependency-type: direct:production
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-07 20:33:20 +01:00
Slaviša Arežina
ec92c0ea6d Merge pull request #421 from zeosamaster/patch-1 2025-12-30 13:51:57 +01:00
Fábio Matias
ee14b89868 Fix directory path in README after cloning 2025-12-30 11:46:33 +00:00
Michel Roegl-Brunner
be68160cd9 Merge pull request #411 from community-scripts/dependabot/npm_and_yarn/t3-oss/env-nextjs-0.13.10 2025-12-18 19:43:58 +01:00
Michel Roegl-Brunner
dbc15b1bc3 Merge pull request #410 from community-scripts/dependabot/npm_and_yarn/jsdom-27.3.0 2025-12-18 19:43:44 +01:00
Michel Roegl-Brunner
dc6ce16e5a Merge pull request #409 from community-scripts/dependabot/npm_and_yarn/tanstack/react-query-5.90.12 2025-12-18 19:43:33 +01:00
Michel Roegl-Brunner
0c9d4ad6e2 Merge pull request #408 from community-scripts/dependabot/npm_and_yarn/react-dom-19.2.3 2025-12-18 19:43:20 +01:00
dependabot[bot]
13d57b77d4 build(deps): Bump @t3-oss/env-nextjs from 0.13.8 to 0.13.10
Bumps [@t3-oss/env-nextjs](https://github.com/t3-oss/t3-env/tree/HEAD/packages/nextjs) from 0.13.8 to 0.13.10.
- [Release notes](https://github.com/t3-oss/t3-env/releases)
- [Changelog](https://github.com/t3-oss/t3-env/blob/main/packages/nextjs/CHANGELOG.md)
- [Commits](https://github.com/t3-oss/t3-env/commits/@t3-oss/env-nextjs@0.13.10/packages/nextjs)

---
updated-dependencies:
- dependency-name: "@t3-oss/env-nextjs"
  dependency-version: 0.13.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-15 19:25:26 +00:00
dependabot[bot]
f9e5bd5bf0 build(deps-dev): Bump jsdom from 27.2.0 to 27.3.0
Bumps [jsdom](https://github.com/jsdom/jsdom) from 27.2.0 to 27.3.0.
- [Release notes](https://github.com/jsdom/jsdom/releases)
- [Changelog](https://github.com/jsdom/jsdom/blob/main/Changelog.md)
- [Commits](https://github.com/jsdom/jsdom/compare/27.2.0...27.3.0)

---
updated-dependencies:
- dependency-name: jsdom
  dependency-version: 27.3.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-15 19:25:15 +00:00
dependabot[bot]
adf2b06efa build(deps): Bump @tanstack/react-query from 5.90.11 to 5.90.12
Bumps [@tanstack/react-query](https://github.com/TanStack/query/tree/HEAD/packages/react-query) from 5.90.11 to 5.90.12.
- [Release notes](https://github.com/TanStack/query/releases)
- [Changelog](https://github.com/TanStack/query/blob/main/packages/react-query/CHANGELOG.md)
- [Commits](https://github.com/TanStack/query/commits/@tanstack/react-query@5.90.12/packages/react-query)

---
updated-dependencies:
- dependency-name: "@tanstack/react-query"
  dependency-version: 5.90.12
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-15 19:25:03 +00:00
dependabot[bot]
80e3966e4e build(deps): Bump react-dom from 19.2.1 to 19.2.3
Bumps [react-dom](https://github.com/facebook/react/tree/HEAD/packages/react-dom) from 19.2.1 to 19.2.3.
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v19.2.3/packages/react-dom)

---
updated-dependencies:
- dependency-name: react-dom
  dependency-version: 19.2.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-15 19:24:52 +00:00
Michel Roegl-Brunner
3662a057dc Merge pull request #401 from community-scripts/dependabot/npm_and_yarn/tailwindcss-4.1.18 2025-12-14 11:10:27 +01:00
Michel Roegl-Brunner
bdf336f9bf Merge pull request #400 from community-scripts/dependabot/npm_and_yarn/react-19.2.3 2025-12-14 11:10:17 +01:00
Michel Roegl-Brunner
f6c310fa22 Merge pull request #399 from community-scripts/dependabot/npm_and_yarn/vitejs/plugin-react-5.1.2 2025-12-14 11:10:04 +01:00
Michel Roegl-Brunner
d658894b7f Merge pull request #397 from community-scripts/dependabot/npm_and_yarn/npm_and_yarn-3b9adafb77 2025-12-14 11:09:56 +01:00
dependabot[bot]
783744b497 build(deps-dev): Bump tailwindcss from 4.1.17 to 4.1.18
Bumps [tailwindcss](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss) from 4.1.17 to 4.1.18.
- [Release notes](https://github.com/tailwindlabs/tailwindcss/releases)
- [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.1.18/packages/tailwindcss)

---
updated-dependencies:
- dependency-name: tailwindcss
  dependency-version: 4.1.18
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-12 19:49:47 +00:00
dependabot[bot]
de9ac41f76 build(deps): Bump react from 19.2.1 to 19.2.3
Bumps [react](https://github.com/facebook/react/tree/HEAD/packages/react) from 19.2.1 to 19.2.3.
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v19.2.3/packages/react)

---
updated-dependencies:
- dependency-name: react
  dependency-version: 19.2.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-12 19:49:38 +00:00
dependabot[bot]
060202e557 build(deps-dev): Bump @vitejs/plugin-react from 5.1.1 to 5.1.2
Bumps [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react) from 5.1.1 to 5.1.2.
- [Release notes](https://github.com/vitejs/vite-plugin-react/releases)
- [Changelog](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite-plugin-react/commits/plugin-react@5.1.2/packages/plugin-react)

---
updated-dependencies:
- dependency-name: "@vitejs/plugin-react"
  dependency-version: 5.1.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-12 19:49:27 +00:00
dependabot[bot]
8d45ac14cc build(deps): Bump next in the npm_and_yarn group across 1 directory
Bumps the npm_and_yarn group with 1 update in the / directory: [next](https://github.com/vercel/next.js).


Updates `next` from 16.0.9 to 16.0.10
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/compare/v16.0.9...v16.0.10)

---
updated-dependencies:
- dependency-name: next
  dependency-version: 16.0.10
  dependency-type: direct:production
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-12 17:26:19 +00:00
CanbiZ
47ee2247c8 fix for code scanning alert no. 4: Insecure randomness (#396)
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2025-12-12 11:45:43 +01:00
dependabot[bot]
c16c8d54db build(deps): Bump lucide-react from 0.555.0 to 0.556.0 (#392)
Bumps [lucide-react](https://github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-react) from 0.555.0 to 0.556.0.
- [Release notes](https://github.com/lucide-icons/lucide/releases)
- [Commits](https://github.com/lucide-icons/lucide/commits/0.556.0/packages/lucide-react)

---
updated-dependencies:
- dependency-name: lucide-react
  dependency-version: 0.556.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-12 11:29:10 +01:00
dependabot[bot]
3e669a0739 build(deps): Bump jsonwebtoken from 9.0.2 to 9.0.3 (#390)
Bumps [jsonwebtoken](https://github.com/auth0/node-jsonwebtoken) from 9.0.2 to 9.0.3.
- [Changelog](https://github.com/auth0/node-jsonwebtoken/blob/master/CHANGELOG.md)
- [Commits](https://github.com/auth0/node-jsonwebtoken/compare/v9.0.2...v9.0.3)

---
updated-dependencies:
- dependency-name: jsonwebtoken
  dependency-version: 9.0.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-12 11:27:47 +01:00
dependabot[bot]
02e175c8a0 build(deps-dev): Bump eslint-config-next from 16.0.6 to 16.0.7 (#391)
Bumps [eslint-config-next](https://github.com/vercel/next.js/tree/HEAD/packages/eslint-config-next) from 16.0.6 to 16.0.7.
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/commits/v16.0.7/packages/eslint-config-next)

---
updated-dependencies:
- dependency-name: eslint-config-next
  dependency-version: 16.0.7
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-12 11:27:41 +01:00
dependabot[bot]
b4e98e7624 build(deps-dev): Bump prettier from 3.7.3 to 3.7.4 (#393)
Bumps [prettier](https://github.com/prettier/prettier) from 3.7.3 to 3.7.4.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/3.7.3...3.7.4)

---
updated-dependencies:
- dependency-name: prettier
  dependency-version: 3.7.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-12 11:27:23 +01:00
dependabot[bot]
2392529092 build(deps-dev): Bump baseline-browser-mapping from 2.8.32 to 2.9.3 (#394)
Bumps [baseline-browser-mapping](https://github.com/web-platform-dx/baseline-browser-mapping) from 2.8.32 to 2.9.3.
- [Release notes](https://github.com/web-platform-dx/baseline-browser-mapping/releases)
- [Commits](https://github.com/web-platform-dx/baseline-browser-mapping/compare/v2.8.32...v2.9.3)

---
updated-dependencies:
- dependency-name: baseline-browser-mapping
  dependency-version: 2.9.3
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-12 11:27:17 +01:00
dependabot[bot]
f9f5772d92 build(deps): Bump next in the npm_and_yarn group across 1 directory (#395)
Bumps the npm_and_yarn group with 1 update in the / directory: [next](https://github.com/vercel/next.js).


Updates `next` from 16.0.7 to 16.0.9
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/compare/v16.0.7...v16.0.9)

---
updated-dependencies:
- dependency-name: next
  dependency-version: 16.0.9
  dependency-type: direct:production
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-12 11:27:11 +01:00
github-actions[bot]
4267d7340e chore: add VERSION v0.5.2 (#389)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-12-05 15:13:42 +00:00
17 changed files with 1963 additions and 778 deletions

View File

@@ -100,7 +100,7 @@ apt install -y nodejs
```bash ```bash
# Clone the repository # Clone the repository
git clone https://github.com/community-scripts/ProxmoxVE-Local.git /opt/PVESciptslocal git clone https://github.com/community-scripts/ProxmoxVE-Local.git /opt/PVESciptslocal
cd PVESciptslocal cd /opt/PVESciptslocal
# Install dependencies and build # Install dependencies and build
npm install npm install

View File

@@ -1 +1 @@
0.5.1 0.5.3

615
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -29,17 +29,17 @@
"@prisma/client": "^7.1.0", "@prisma/client": "^7.1.0",
"@radix-ui/react-dropdown-menu": "^2.1.16", "@radix-ui/react-dropdown-menu": "^2.1.16",
"@radix-ui/react-slot": "^1.2.4", "@radix-ui/react-slot": "^1.2.4",
"@t3-oss/env-nextjs": "^0.13.8", "@t3-oss/env-nextjs": "^0.13.10",
"@tailwindcss/typography": "^0.5.19", "@tailwindcss/typography": "^0.5.19",
"@tanstack/react-query": "^5.90.11", "@tanstack/react-query": "^5.90.12",
"@trpc/client": "^11.7.2", "@trpc/client": "^11.8.0",
"@trpc/react-query": "^11.7.2", "@trpc/react-query": "^11.8.1",
"@trpc/server": "^11.7.2", "@trpc/server": "^11.8.0",
"@types/react-syntax-highlighter": "^15.5.13", "@types/react-syntax-highlighter": "^15.5.13",
"@types/ws": "^8.18.1", "@types/ws": "^8.18.1",
"@xterm/addon-fit": "^0.10.0", "@xterm/addon-fit": "^0.10.0",
"@xterm/addon-web-links": "^0.11.0", "@xterm/addon-web-links": "^0.12.0",
"@xterm/xterm": "^5.5.0", "@xterm/xterm": "^6.0.0",
"axios": "^1.13.2", "axios": "^1.13.2",
"bcryptjs": "^3.0.3", "bcryptjs": "^3.0.3",
"better-sqlite3": "^12.5.0", "better-sqlite3": "^12.5.0",
@@ -47,13 +47,13 @@
"clsx": "^2.1.1", "clsx": "^2.1.1",
"cron-validator": "^1.4.0", "cron-validator": "^1.4.0",
"dotenv": "^17.2.3", "dotenv": "^17.2.3",
"jsonwebtoken": "^9.0.2", "jsonwebtoken": "^9.0.3",
"lucide-react": "^0.555.0", "lucide-react": "^0.562.0",
"next": "^16.0.7", "next": "^16.0.10",
"node-cron": "^4.2.1", "node-cron": "^4.2.1",
"node-pty": "^1.0.0", "node-pty": "^1.0.0",
"react": "^19.2.0", "react": "^19.2.3",
"react-dom": "^19.2.1", "react-dom": "^19.2.3",
"react-markdown": "^10.1.0", "react-markdown": "^10.1.0",
"react-syntax-highlighter": "^16.1.0", "react-syntax-highlighter": "^16.1.0",
"refractor": "^5.0.0", "refractor": "^5.0.0",
@@ -66,29 +66,29 @@
"zod": "^4.1.13" "zod": "^4.1.13"
}, },
"devDependencies": { "devDependencies": {
"@tailwindcss/postcss": "^4.1.17", "@tailwindcss/postcss": "^4.1.18",
"@testing-library/jest-dom": "^6.9.1", "@testing-library/jest-dom": "^6.9.1",
"@testing-library/react": "^16.3.0", "@testing-library/react": "^16.3.1",
"@testing-library/user-event": "^14.6.1", "@testing-library/user-event": "^14.6.1",
"@types/bcryptjs": "^3.0.0", "@types/bcryptjs": "^3.0.0",
"@types/better-sqlite3": "^7.6.13", "@types/better-sqlite3": "^7.6.13",
"@types/jsonwebtoken": "^9.0.10", "@types/jsonwebtoken": "^9.0.10",
"@types/node": "^24.10.1", "@types/node": "^24.10.4",
"@types/node-cron": "^3.0.11", "@types/node-cron": "^3.0.11",
"@types/react": "^19.2.7", "@types/react": "^19.2.7",
"@types/react-dom": "^19.2.3", "@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^5.1.1", "@vitejs/plugin-react": "^5.1.2",
"@vitest/coverage-v8": "^4.0.15", "@vitest/coverage-v8": "^4.0.16",
"@vitest/ui": "^4.0.14", "@vitest/ui": "^4.0.14",
"baseline-browser-mapping": "^2.8.32", "baseline-browser-mapping": "^2.9.3",
"eslint": "^9.39.1", "eslint": "^9.39.1",
"eslint-config-next": "^16.0.6", "eslint-config-next": "^16.1.0",
"jsdom": "^27.2.0", "jsdom": "^27.3.0",
"postcss": "^8.5.6", "postcss": "^8.5.6",
"prettier": "^3.7.3", "prettier": "^3.7.4",
"prettier-plugin-tailwindcss": "^0.7.2", "prettier-plugin-tailwindcss": "^0.7.2",
"prisma": "^7.1.0", "prisma": "^7.1.0",
"tailwindcss": "^4.1.17", "tailwindcss": "^4.1.18",
"tsx": "^4.21.0", "tsx": "^4.21.0",
"typescript": "^5.9.3", "typescript": "^5.9.3",
"typescript-eslint": "^8.48.1", "typescript-eslint": "^8.48.1",

View File

@@ -1,4 +1,4 @@
# Copyright (c) 2021-2025 community-scripts ORG # Copyright (c) 2021-2026 community-scripts ORG
# Author: tteck (tteckster) # Author: tteck (tteckster)
# Co-Author: MickLesk # Co-Author: MickLesk
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE

View File

@@ -1,4 +1,4 @@
# Copyright (c) 2021-2025 community-scripts ORG # Copyright (c) 2021-2026 community-scripts ORG
# Author: michelroegl-brunner # Author: michelroegl-brunner
# License: MIT | https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/LICENSE # License: MIT | https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/LICENSE

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG # Copyright (c) 2021-2026 community-scripts ORG
# Author: community-scripts ORG # Author: community-scripts ORG
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/branch/main/LICENSE # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/branch/main/LICENSE
# Revision: 1 # Revision: 1
@@ -502,4 +502,4 @@ if validate_ip_cidr "192.168.1.100/24"; then
echo "Valid IP/CIDR" echo "Valid IP/CIDR"
fi fi
EXAMPLES EXAMPLES

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG # Copyright (c) 2021-2026 community-scripts ORG
# License: MIT | https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/LICENSE # License: MIT | https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/LICENSE
# ============================================================================== # ==============================================================================
@@ -123,6 +123,7 @@ icons() {
CREATING="${TAB}🚀${TAB}${CL}" CREATING="${TAB}🚀${TAB}${CL}"
ADVANCED="${TAB}🧩${TAB}${CL}" ADVANCED="${TAB}🧩${TAB}${CL}"
FUSE="${TAB}🗂️${TAB}${CL}" FUSE="${TAB}🗂️${TAB}${CL}"
GPU="${TAB}🎮${TAB}${CL}"
HOURGLASS="${TAB}⏳${TAB}" HOURGLASS="${TAB}⏳${TAB}"
} }
@@ -808,18 +809,15 @@ cleanup_lxc() {
find /tmp /var/tmp -type f -name 'tmp*' -delete 2>/dev/null || true find /tmp /var/tmp -type f -name 'tmp*' -delete 2>/dev/null || true
find /tmp /var/tmp -type f -name 'tempfile*' -delete 2>/dev/null || true find /tmp /var/tmp -type f -name 'tempfile*' -delete 2>/dev/null || true
# Truncate writable log files silently (permission errors ignored) # Node.js npm - directly remove cache directory
if command -v truncate >/dev/null 2>&1; then # npm cache clean/verify can fail with ENOTEMPTY errors, so we skip them
find /var/log -type f -writable -print0 2>/dev/null | if command -v npm &>/dev/null; then
xargs -0 -n1 truncate -s 0 2>/dev/null || true rm -rf /root/.npm/_cacache /root/.npm/_logs 2>/dev/null || true
fi fi
# Node.js npm
if command -v npm &>/dev/null; then $STD npm cache clean --force || true; fi
# Node.js yarn # Node.js yarn
if command -v yarn &>/dev/null; then $STD yarn cache clean || true; fi if command -v yarn &>/dev/null; then yarn cache clean &>/dev/null || true; fi
# Node.js pnpm # Node.js pnpm
if command -v pnpm &>/dev/null; then $STD pnpm store prune || true; fi if command -v pnpm &>/dev/null; then pnpm store prune &>/dev/null || true; fi
# Go # Go
if command -v go &>/dev/null; then $STD go clean -cache -modcache || true; fi if command -v go &>/dev/null; then $STD go clean -cache -modcache || true; fi
# Rust cargo # Rust cargo
@@ -827,11 +825,8 @@ cleanup_lxc() {
# Ruby gem # Ruby gem
if command -v gem &>/dev/null; then $STD gem cleanup || true; fi if command -v gem &>/dev/null; then $STD gem cleanup || true; fi
# Composer (PHP) # Composer (PHP)
if command -v composer &>/dev/null; then $STD composer clear-cache || true; fi if command -v composer &>/dev/null; then COMPOSER_ALLOW_SUPERUSER=1 $STD composer clear-cache || true; fi
if command -v journalctl &>/dev/null; then
$STD journalctl --vacuum-time=10m || true
fi
msg_ok "Cleaned" msg_ok "Cleaned"
} }
@@ -887,4 +882,4 @@ check_or_create_swap() {
# SIGNAL TRAPS # SIGNAL TRAPS
# ============================================================================== # ==============================================================================
trap 'stop_spinner' EXIT INT TERM trap 'stop_spinner' EXIT INT TERM

View File

@@ -2,7 +2,7 @@
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# ERROR HANDLER - ERROR & SIGNAL MANAGEMENT # ERROR HANDLER - ERROR & SIGNAL MANAGEMENT
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Copyright (c) 2021-2025 community-scripts ORG # Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ) # Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
@@ -34,9 +34,9 @@
# * Node.js/npm errors (243-249, 254) # * Node.js/npm errors (243-249, 254)
# * Python/pip/uv errors (210-212) # * Python/pip/uv errors (210-212)
# * PostgreSQL errors (231-234) # * PostgreSQL errors (231-234)
# * MySQL/MariaDB errors (260-263) # * MySQL/MariaDB errors (241-244)
# * MongoDB errors (251-253) # * MongoDB errors (251-254)
# * Proxmox custom codes (200-209, 213-223, 225) # * Proxmox custom codes (200-231)
# - Returns description string for given exit code # - Returns description string for given exit code
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
explain_exit_code() { explain_exit_code() {
@@ -319,4 +319,4 @@ catch_errors() {
trap on_exit EXIT trap on_exit EXIT
trap on_interrupt INT trap on_interrupt INT
trap on_terminate TERM trap on_terminate TERM
} }

View File

@@ -1,4 +1,4 @@
# Copyright (c) 2021-2025 community-scripts ORG # Copyright (c) 2021-2026 community-scripts ORG
# Author: tteck (tteckster) # Author: tteck (tteckster)
# Co-Author: MickLesk # Co-Author: MickLesk
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
@@ -222,21 +222,12 @@ motd_ssh() {
# Set terminal to 256-color mode # Set terminal to 256-color mode
grep -qxF "export TERM='xterm-256color'" /root/.bashrc || echo "export TERM='xterm-256color'" >>/root/.bashrc grep -qxF "export TERM='xterm-256color'" /root/.bashrc || echo "export TERM='xterm-256color'" >>/root/.bashrc
# Get OS information (Debian / Ubuntu)
if [ -f "/etc/os-release" ]; then
OS_NAME=$(grep ^NAME /etc/os-release | cut -d= -f2 | tr -d '"')
OS_VERSION=$(grep ^VERSION_ID /etc/os-release | cut -d= -f2 | tr -d '"')
elif [ -f "/etc/debian_version" ]; then
OS_NAME="Debian"
OS_VERSION=$(cat /etc/debian_version)
fi
PROFILE_FILE="/etc/profile.d/00_lxc-details.sh" PROFILE_FILE="/etc/profile.d/00_lxc-details.sh"
echo "echo -e \"\"" >"$PROFILE_FILE" echo "echo -e \"\"" >"$PROFILE_FILE"
echo -e "echo -e \"${BOLD}${APPLICATION} LXC Container${CL}"\" >>"$PROFILE_FILE" echo -e "echo -e \"${BOLD}${APPLICATION} LXC Container${CL}"\" >>"$PROFILE_FILE"
echo -e "echo -e \"${TAB}${GATEWAY}${YW} Provided by: ${GN}community-scripts ORG ${YW}| GitHub: ${GN}https://github.com/community-scripts/ProxmoxVE${CL}\"" >>"$PROFILE_FILE" echo -e "echo -e \"${TAB}${GATEWAY}${YW} Provided by: ${GN}community-scripts ORG ${YW}| GitHub: ${GN}https://github.com/community-scripts/ProxmoxVE${CL}\"" >>"$PROFILE_FILE"
echo "echo \"\"" >>"$PROFILE_FILE" echo "echo \"\"" >>"$PROFILE_FILE"
echo -e "echo -e \"${TAB}${OS}${YW} OS: ${GN}${OS_NAME} - Version: ${OS_VERSION}${CL}\"" >>"$PROFILE_FILE" echo -e "echo -e \"${TAB}${OS}${YW} OS: ${GN}\$(grep ^NAME /etc/os-release | cut -d= -f2 | tr -d '\"') - Version: \$(grep ^VERSION_ID /etc/os-release | cut -d= -f2 | tr -d '\"')${CL}\"" >>"$PROFILE_FILE"
echo -e "echo -e \"${TAB}${HOSTNAME}${YW} Hostname: ${GN}\$(hostname)${CL}\"" >>"$PROFILE_FILE" echo -e "echo -e \"${TAB}${HOSTNAME}${YW} Hostname: ${GN}\$(hostname)${CL}\"" >>"$PROFILE_FILE"
echo -e "echo -e \"${TAB}${INFO}${YW} IP Address: ${GN}\$(hostname -I | awk '{print \$1}')${CL}\"" >>"$PROFILE_FILE" echo -e "echo -e \"${TAB}${INFO}${YW} IP Address: ${GN}\$(hostname -I | awk '{print \$1}')${CL}\"" >>"$PROFILE_FILE"

File diff suppressed because it is too large Load Diff

View File

@@ -16,7 +16,7 @@ export function Footer({ onOpenReleaseNotes }: FooterProps) {
<div className="container mx-auto px-4"> <div className="container mx-auto px-4">
<div className="flex flex-col sm:flex-row items-center justify-between gap-2 text-sm text-muted-foreground"> <div className="flex flex-col sm:flex-row items-center justify-between gap-2 text-sm text-muted-foreground">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<span>© 2024 PVE Scripts Local</span> <span>© 2026 PVE Scripts Local</span>
{versionData?.success && versionData.version && ( {versionData?.success && versionData.version && (
<Button <Button
variant="ghost" variant="ghost"

View File

@@ -416,11 +416,20 @@ export function VersionDisplay({ onOpenReleaseNotes }: VersionDisplayProps = {})
setShowUpdateConfirmation(true); setShowUpdateConfirmation(true);
}; };
// Helper to generate secure random string
function getSecureRandomString(length: number): string {
const array = new Uint8Array(length);
window.crypto.getRandomValues(array);
// Convert to base36 string (alphanumeric)
return Array.from(array, b => b.toString(36)).join('').substr(0, length);
}
const handleConfirmUpdate = () => { const handleConfirmUpdate = () => {
// Close the confirmation modal // Close the confirmation modal
setShowUpdateConfirmation(false); setShowUpdateConfirmation(false);
// Start the actual update process // Start the actual update process
const sessionId = `update_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`; const randomSuffix = getSecureRandomString(9);
const sessionId = `update_${Date.now()}_${randomSuffix}`;
const startTime = Date.now(); const startTime = Date.now();
setIsUpdating(true); setIsUpdating(true);

View File

@@ -1,9 +1,22 @@
import 'dotenv/config' import 'dotenv/config'
import { PrismaClient } from '../../prisma/generated/prisma/client.ts' import { PrismaClient } from '../../prisma/generated/prisma/client.ts'
import { PrismaBetterSqlite3 } from '@prisma/adapter-better-sqlite3' import { PrismaBetterSqlite3 } from '@prisma/adapter-better-sqlite3'
import { existsSync, mkdirSync } from 'fs'
import { dirname } from 'path'
const globalForPrisma = globalThis; const globalForPrisma = globalThis;
// Ensure database directory exists before initializing Prisma
// DATABASE_URL format: file:/path/to/database.db
const dbUrl = process.env.DATABASE_URL || 'file:./data/settings.db';
const dbPath = dbUrl.replace(/^file:/, '');
const dbDir = dirname(dbPath);
if (!existsSync(dbDir)) {
console.log(`Creating database directory: ${dbDir}`);
mkdirSync(dbDir, { recursive: true });
}
const adapter = new PrismaBetterSqlite3({ url: process.env.DATABASE_URL }); const adapter = new PrismaBetterSqlite3({ url: process.env.DATABASE_URL });
export const prisma = globalForPrisma.prisma ?? new PrismaClient({ adapter }); export const prisma = globalForPrisma.prisma ?? new PrismaClient({ adapter });

View File

@@ -1,9 +1,22 @@
import 'dotenv/config' import 'dotenv/config'
import { PrismaClient } from '../../prisma/generated/prisma/client' import { PrismaClient } from '../../prisma/generated/prisma/client'
import { PrismaBetterSqlite3 } from '@prisma/adapter-better-sqlite3' import { PrismaBetterSqlite3 } from '@prisma/adapter-better-sqlite3'
import { existsSync, mkdirSync } from 'fs'
import { dirname } from 'path'
const globalForPrisma = globalThis as { prisma?: PrismaClient }; const globalForPrisma = globalThis as { prisma?: PrismaClient };
// Ensure database directory exists before initializing Prisma
// DATABASE_URL format: file:/path/to/database.db
const dbUrl = process.env.DATABASE_URL || 'file:./data/settings.db';
const dbPath = dbUrl.replace(/^file:/, '');
const dbDir = dirname(dbPath);
if (!existsSync(dbDir)) {
console.log(`Creating database directory: ${dbDir}`);
mkdirSync(dbDir, { recursive: true });
}
const adapter = new PrismaBetterSqlite3({ url: process.env.DATABASE_URL! }); const adapter = new PrismaBetterSqlite3({ url: process.env.DATABASE_URL! });
export const prisma: PrismaClient = globalForPrisma.prisma ?? new PrismaClient({ export const prisma: PrismaClient = globalForPrisma.prisma ?? new PrismaClient({

356
update.sh
View File

@@ -4,7 +4,7 @@
# Enhanced update script for ProxmoxVE-Local # Enhanced update script for ProxmoxVE-Local
# Fetches latest release from GitHub and backs up data directory # Fetches latest release from GitHub and backs up data directory
set -euo pipefail # Exit on error, undefined vars, pipe failures set -euo pipefail # Exit on error, undefined vars, pipe failures
# Add error trap for debugging # Add error trap for debugging
trap 'echo "Error occurred at line $LINENO, command: $BASH_COMMAND"' ERR trap 'echo "Error occurred at line $LINENO, command: $BASH_COMMAND"' ERR
@@ -38,7 +38,7 @@ load_github_token() {
log "Using GitHub token from environment variable" log "Using GitHub token from environment variable"
return 0 return 0
fi fi
# Try .env file # Try .env file
if [ -f ".env" ]; then if [ -f ".env" ]; then
local env_token local env_token
@@ -49,21 +49,21 @@ load_github_token() {
return 0 return 0
fi fi
fi fi
# Try .github_token file # Try .github_token file
if [ -f ".github_token" ]; then if [ -f ".github_token" ]; then
GITHUB_TOKEN=$(cat .github_token | tr -d '\n\r') GITHUB_TOKEN=$(cat .github_token | tr -d '\n\r')
log "Using GitHub token from .github_token file" log "Using GitHub token from .github_token file"
return 0 return 0
fi fi
# Try ~/.github_token file # Try ~/.github_token file
if [ -f "$HOME/.github_token" ]; then if [ -f "$HOME/.github_token" ]; then
GITHUB_TOKEN=$(cat "$HOME/.github_token" | tr -d '\n\r') GITHUB_TOKEN=$(cat "$HOME/.github_token" | tr -d '\n\r')
log "Using GitHub token from ~/.github_token file" log "Using GitHub token from ~/.github_token file"
return 0 return 0
fi fi
log_warning "No GitHub token found. Using unauthenticated requests (lower rate limits)" log_warning "No GitHub token found. Using unauthenticated requests (lower rate limits)"
log_warning "To use a token, add GITHUB_TOKEN=your_token to .env file or set GITHUB_TOKEN environment variable" log_warning "To use a token, add GITHUB_TOKEN=your_token to .env file or set GITHUB_TOKEN environment variable"
return 1 return 1
@@ -72,7 +72,7 @@ load_github_token() {
# Initialize log file # Initialize log file
init_log() { init_log() {
# Clear/create log file # Clear/create log file
> "$LOG_FILE" >"$LOG_FILE"
log "Starting ProxmoxVE-Local update process..." log "Starting ProxmoxVE-Local update process..."
log "Log file: $LOG_FILE" log "Log file: $LOG_FILE"
} }
@@ -97,40 +97,40 @@ log_warning() {
# Check if required tools are available # Check if required tools are available
check_dependencies() { check_dependencies() {
log "Checking dependencies..." log "Checking dependencies..."
local missing_deps=() local missing_deps=()
if ! command -v curl &> /dev/null; then if ! command -v curl &>/dev/null; then
missing_deps+=("curl") missing_deps+=("curl")
fi fi
if ! command -v jq &> /dev/null; then if ! command -v jq &>/dev/null; then
missing_deps+=("jq") missing_deps+=("jq")
fi fi
if ! command -v npm &> /dev/null; then if ! command -v npm &>/dev/null; then
missing_deps+=("npm") missing_deps+=("npm")
fi fi
if ! command -v node &> /dev/null; then if ! command -v node &>/dev/null; then
missing_deps+=("node") missing_deps+=("node")
fi fi
if [ ${#missing_deps[@]} -ne 0 ]; then if [ ${#missing_deps[@]} -ne 0 ]; then
log_error "Missing dependencies: ${missing_deps[*]}" log_error "Missing dependencies: ${missing_deps[*]}"
log_error "Please install the missing dependencies and try again." log_error "Please install the missing dependencies and try again."
exit 1 exit 1
fi fi
log_success "All dependencies are available" log_success "All dependencies are available"
} }
# Get latest release info from GitHub API # Get latest release info from GitHub API
get_latest_release() { get_latest_release() {
log "Fetching latest release information from GitHub..." log "Fetching latest release information from GitHub..."
local curl_opts="-s --connect-timeout 15 --max-time 60 --retry 2 --retry-delay 3" local curl_opts="-s --connect-timeout 15 --max-time 60 --retry 2 --retry-delay 3"
# Add authentication header if token is available # Add authentication header if token is available
if [ -n "$GITHUB_TOKEN" ]; then if [ -n "$GITHUB_TOKEN" ]; then
curl_opts="$curl_opts -H \"Authorization: token $GITHUB_TOKEN\"" curl_opts="$curl_opts -H \"Authorization: token $GITHUB_TOKEN\""
@@ -138,35 +138,35 @@ get_latest_release() {
else else
log "Using unauthenticated GitHub API request (lower rate limits)" log "Using unauthenticated GitHub API request (lower rate limits)"
fi fi
local release_info local release_info
if ! release_info=$(eval "curl $curl_opts \"$GITHUB_API/releases/latest\""); then if ! release_info=$(eval "curl $curl_opts \"$GITHUB_API/releases/latest\""); then
log_error "Failed to fetch release information from GitHub API (timeout or network error)" log_error "Failed to fetch release information from GitHub API (timeout or network error)"
exit 1 exit 1
fi fi
# Check if response is valid JSON # Check if response is valid JSON
if ! echo "$release_info" | jq empty 2>/dev/null; then if ! echo "$release_info" | jq empty 2>/dev/null; then
log_error "Invalid JSON response from GitHub API" log_error "Invalid JSON response from GitHub API"
log "Response: $release_info" log "Response: $release_info"
exit 1 exit 1
fi fi
local tag_name local tag_name
local download_url local download_url
local published_at local published_at
tag_name=$(echo "$release_info" | jq -r '.tag_name') tag_name=$(echo "$release_info" | jq -r '.tag_name')
download_url=$(echo "$release_info" | jq -r '.tarball_url') download_url=$(echo "$release_info" | jq -r '.tarball_url')
published_at=$(echo "$release_info" | jq -r '.published_at') published_at=$(echo "$release_info" | jq -r '.published_at')
if [ "$tag_name" = "null" ] || [ "$download_url" = "null" ] || [ -z "$tag_name" ] || [ -z "$download_url" ]; then if [ "$tag_name" = "null" ] || [ "$download_url" = "null" ] || [ -z "$tag_name" ] || [ -z "$download_url" ]; then
log_error "Failed to parse release information from API response" log_error "Failed to parse release information from API response"
log "Tag name: $tag_name" log "Tag name: $tag_name"
log "Download URL: $download_url" log "Download URL: $download_url"
exit 1 exit 1
fi fi
log_success "Latest release: $tag_name (published: $published_at)" log_success "Latest release: $tag_name (published: $published_at)"
echo "$tag_name|$download_url" echo "$tag_name|$download_url"
} }
@@ -174,16 +174,16 @@ get_latest_release() {
# Backup data directory, .env file, and scripts directories # Backup data directory, .env file, and scripts directories
backup_data() { backup_data() {
log "Creating backup directory at $BACKUP_DIR..." log "Creating backup directory at $BACKUP_DIR..."
if ! mkdir -p "$BACKUP_DIR"; then if ! mkdir -p "$BACKUP_DIR"; then
log_error "Failed to create backup directory" log_error "Failed to create backup directory"
exit 1 exit 1
fi fi
# Backup data directory # Backup data directory
if [ -d "$DATA_DIR" ]; then if [ -d "$DATA_DIR" ]; then
log "Backing up data directory..." log "Backing up data directory..."
if ! cp -r "$DATA_DIR" "$BACKUP_DIR/data"; then if ! cp -r "$DATA_DIR" "$BACKUP_DIR/data"; then
log_error "Failed to backup data directory" log_error "Failed to backup data directory"
exit 1 exit 1
@@ -193,7 +193,7 @@ backup_data() {
else else
log_warning "Data directory not found, skipping backup" log_warning "Data directory not found, skipping backup"
fi fi
# Backup .env file # Backup .env file
if [ -f ".env" ]; then if [ -f ".env" ]; then
log "Backing up .env file..." log "Backing up .env file..."
@@ -206,7 +206,7 @@ backup_data() {
else else
log_warning ".env file not found, skipping backup" log_warning ".env file not found, skipping backup"
fi fi
# Backup scripts directories # Backup scripts directories
local scripts_dirs=("scripts/ct" "scripts/install" "scripts/tools" "scripts/vm") local scripts_dirs=("scripts/ct" "scripts/install" "scripts/tools" "scripts/vm")
for scripts_dir in "${scripts_dirs[@]}"; do for scripts_dir in "${scripts_dirs[@]}"; do
@@ -230,60 +230,60 @@ download_release() {
local release_info="$1" local release_info="$1"
local tag_name="${release_info%|*}" local tag_name="${release_info%|*}"
local download_url="${release_info#*|}" local download_url="${release_info#*|}"
log "Downloading release $tag_name..." log "Downloading release $tag_name..."
local temp_dir="/tmp/pve-update-$$" local temp_dir="/tmp/pve-update-$$"
local archive_file="$temp_dir/release.tar.gz" local archive_file="$temp_dir/release.tar.gz"
# Create temporary directory # Create temporary directory
if ! mkdir -p "$temp_dir"; then if ! mkdir -p "$temp_dir"; then
log_error "Failed to create temporary directory" log_error "Failed to create temporary directory"
exit 1 exit 1
fi fi
# Download release with timeout and progress # Download release with timeout and progress
if ! curl -L --connect-timeout 30 --max-time 300 --retry 3 --retry-delay 5 -o "$archive_file" "$download_url" 2>/dev/null; then if ! curl -L --connect-timeout 30 --max-time 300 --retry 3 --retry-delay 5 -o "$archive_file" "$download_url" 2>/dev/null; then
log_error "Failed to download release from GitHub" log_error "Failed to download release from GitHub"
rm -rf "$temp_dir" rm -rf "$temp_dir"
exit 1 exit 1
fi fi
# Verify download # Verify download
if [ ! -f "$archive_file" ] || [ ! -s "$archive_file" ]; then if [ ! -f "$archive_file" ] || [ ! -s "$archive_file" ]; then
log_error "Downloaded file is empty or missing" log_error "Downloaded file is empty or missing"
rm -rf "$temp_dir" rm -rf "$temp_dir"
exit 1 exit 1
fi fi
log_success "Downloaded release" log_success "Downloaded release"
# Extract release # Extract release
if ! tar -xzf "$archive_file" -C "$temp_dir" 2>/dev/null; then if ! tar -xzf "$archive_file" -C "$temp_dir" 2>/dev/null; then
log_error "Failed to extract release" log_error "Failed to extract release"
rm -rf "$temp_dir" rm -rf "$temp_dir"
exit 1 exit 1
fi fi
# Find the extracted directory (GitHub tarballs have a root directory) # Find the extracted directory (GitHub tarballs have a root directory)
local extracted_dir local extracted_dir
extracted_dir=$(find "$temp_dir" -maxdepth 1 -type d -name "community-scripts-ProxmoxVE-Local-*" 2>/dev/null | head -1) extracted_dir=$(find "$temp_dir" -maxdepth 1 -type d -name "community-scripts-ProxmoxVE-Local-*" 2>/dev/null | head -1)
# Try alternative patterns if not found # Try alternative patterns if not found
if [ -z "$extracted_dir" ]; then if [ -z "$extracted_dir" ]; then
extracted_dir=$(find "$temp_dir" -maxdepth 1 -type d -name "${REPO_NAME}-*" 2>/dev/null | head -1) extracted_dir=$(find "$temp_dir" -maxdepth 1 -type d -name "${REPO_NAME}-*" 2>/dev/null | head -1)
fi fi
if [ -z "$extracted_dir" ]; then if [ -z "$extracted_dir" ]; then
extracted_dir=$(find "$temp_dir" -maxdepth 1 -type d ! -name "$temp_dir" 2>/dev/null | head -1) extracted_dir=$(find "$temp_dir" -maxdepth 1 -type d ! -name "$temp_dir" 2>/dev/null | head -1)
fi fi
if [ -z "$extracted_dir" ]; then if [ -z "$extracted_dir" ]; then
log_error "Could not find extracted directory" log_error "Could not find extracted directory"
rm -rf "$temp_dir" rm -rf "$temp_dir"
exit 1 exit 1
fi fi
log_success "Release extracted successfully" log_success "Release extracted successfully"
echo "$extracted_dir" echo "$extracted_dir"
} }
@@ -291,11 +291,11 @@ download_release() {
# Clear the original directory before updating # Clear the original directory before updating
clear_original_directory() { clear_original_directory() {
log "Clearing original directory..." log "Clearing original directory..."
# Remove old lock files and node_modules before update # Remove old lock files and node_modules before update
rm -f package-lock.json 2>/dev/null rm -f package-lock.json 2>/dev/null
rm -rf node_modules 2>/dev/null rm -rf node_modules 2>/dev/null
# List of files/directories to preserve (already backed up) # List of files/directories to preserve (already backed up)
local preserve_patterns=( local preserve_patterns=(
"data" "data"
@@ -308,48 +308,48 @@ clear_original_directory() {
".git" ".git"
"scripts" "scripts"
) )
# Remove all files except preserved ones # Remove all files except preserved ones
while IFS= read -r file; do while IFS= read -r file; do
local should_preserve=false local should_preserve=false
local filename=$(basename "$file") local filename=$(basename "$file")
for pattern in "${preserve_patterns[@]}"; do for pattern in "${preserve_patterns[@]}"; do
if [[ "$filename" == $pattern ]]; then if [[ "$filename" == $pattern ]]; then
should_preserve=true should_preserve=true
break break
fi fi
done done
if [ "$should_preserve" = false ]; then if [ "$should_preserve" = false ]; then
rm -f "$file" rm -f "$file"
fi fi
done < <(find . -maxdepth 1 -type f ! -name ".*") done < <(find . -maxdepth 1 -type f ! -name ".*")
# Remove all directories except preserved ones # Remove all directories except preserved ones
while IFS= read -r dir; do while IFS= read -r dir; do
local should_preserve=false local should_preserve=false
local dirname=$(basename "$dir") local dirname=$(basename "$dir")
for pattern in "${preserve_patterns[@]}"; do for pattern in "${preserve_patterns[@]}"; do
if [[ "$dirname" == $pattern ]]; then if [[ "$dirname" == $pattern ]]; then
should_preserve=true should_preserve=true
break break
fi fi
done done
if [ "$should_preserve" = false ]; then if [ "$should_preserve" = false ]; then
rm -rf "$dir" rm -rf "$dir"
fi fi
done < <(find . -maxdepth 1 -type d ! -name "." ! -name "..") done < <(find . -maxdepth 1 -type d ! -name "." ! -name "..")
log_success "Original directory cleared" log_success "Original directory cleared"
} }
# Restore backup files before building # Restore backup files before building
restore_backup_files() { restore_backup_files() {
log "Restoring .env, data directory, and scripts directories from backup..." log "Restoring .env, data directory, and scripts directories from backup..."
if [ -d "$BACKUP_DIR" ]; then if [ -d "$BACKUP_DIR" ]; then
# Restore .env file # Restore .env file
if [ -f "$BACKUP_DIR/.env" ]; then if [ -f "$BACKUP_DIR/.env" ]; then
@@ -365,7 +365,7 @@ restore_backup_files() {
else else
log_warning "No .env file backup found" log_warning "No .env file backup found"
fi fi
# Restore data directory # Restore data directory
if [ -d "$BACKUP_DIR/data" ]; then if [ -d "$BACKUP_DIR/data" ]; then
if [ -d "data" ]; then if [ -d "data" ]; then
@@ -380,24 +380,24 @@ restore_backup_files() {
else else
log_warning "No data directory backup found" log_warning "No data directory backup found"
fi fi
# Restore scripts directories # Restore scripts directories
local scripts_dirs=("ct" "install" "tools" "vm") local scripts_dirs=("ct" "install" "tools" "vm")
for backup_name in "${scripts_dirs[@]}"; do for backup_name in "${scripts_dirs[@]}"; do
if [ -d "$BACKUP_DIR/$backup_name" ]; then if [ -d "$BACKUP_DIR/$backup_name" ]; then
local target_dir="scripts/$backup_name" local target_dir="scripts/$backup_name"
log "Restoring $target_dir directory from backup..." log "Restoring $target_dir directory from backup..."
# Ensure scripts directory exists # Ensure scripts directory exists
if [ ! -d "scripts" ]; then if [ ! -d "scripts" ]; then
mkdir -p "scripts" mkdir -p "scripts"
fi fi
# Remove existing directory if it exists # Remove existing directory if it exists
if [ -d "$target_dir" ]; then if [ -d "$target_dir" ]; then
rm -rf "$target_dir" rm -rf "$target_dir"
fi fi
if cp -r "$BACKUP_DIR/$backup_name" "$target_dir"; then if cp -r "$BACKUP_DIR/$backup_name" "$target_dir"; then
log_success "$target_dir directory restored from backup" log_success "$target_dir directory restored from backup"
else else
@@ -417,7 +417,13 @@ restore_backup_files() {
# Verify database was restored correctly # Verify database was restored correctly
verify_database_restored() { verify_database_restored() {
log "Verifying database was restored correctly..." log "Verifying database was restored correctly..."
# Ensure data directory exists (will be auto-created by app if needed)
if [ ! -d "data" ]; then
log "Creating data directory..."
mkdir -p data
fi
# Check for both possible database filenames # Check for both possible database filenames
local db_file="" local db_file=""
if [ -f "data/database.sqlite" ]; then if [ -f "data/database.sqlite" ]; then
@@ -425,23 +431,25 @@ verify_database_restored() {
elif [ -f "data/settings.db" ]; then elif [ -f "data/settings.db" ]; then
db_file="data/settings.db" db_file="data/settings.db"
else else
log_error "Database file not found after restore! (checked database.sqlite and settings.db)" # Database doesn't exist yet - this is OK for new installations
return 1 # The app will create it automatically via Prisma migrations
log_warning "No existing database file found - will be created automatically on first start"
return 0
fi fi
local db_size=$(stat -f%z "$db_file" 2>/dev/null || stat -c%s "$db_file" 2>/dev/null) local db_size=$(stat -f%z "$db_file" 2>/dev/null || stat -c%s "$db_file" 2>/dev/null)
if [ "$db_size" -eq 0 ]; then if [ "$db_size" -eq 0 ]; then
log_warning "Database file is empty - will be recreated by Prisma migrations" log_warning "Database file is empty - will be recreated by Prisma migrations"
return 0 # Don't fail the update, let Prisma recreate the database return 0 # Don't fail the update, let Prisma recreate the database
fi fi
log_success "Database verified (file: $db_file, size: $db_size bytes)" log_success "Database verified (file: $db_file, size: $db_size bytes)"
} }
# Ensure DATABASE_URL is set in .env file for Prisma # Ensure DATABASE_URL is set in .env file for Prisma
ensure_database_url() { ensure_database_url() {
log "Ensuring DATABASE_URL is set in .env file..." log "Ensuring DATABASE_URL is set in .env file..."
# Check if .env file exists # Check if .env file exists
if [ ! -f ".env" ]; then if [ ! -f ".env" ]; then
log_warning ".env file not found, creating from .env.example..." log_warning ".env file not found, creating from .env.example..."
@@ -452,19 +460,19 @@ ensure_database_url() {
return 1 return 1
fi fi
fi fi
# Check if DATABASE_URL is already set # Check if DATABASE_URL is already set
if grep -q "^DATABASE_URL=" .env; then if grep -q "^DATABASE_URL=" .env; then
log "DATABASE_URL already exists in .env file" log "DATABASE_URL already exists in .env file"
return 0 return 0
fi fi
# Add DATABASE_URL to .env file # Add DATABASE_URL to .env file
log "Adding DATABASE_URL to .env file..." log "Adding DATABASE_URL to .env file..."
echo "" >> .env echo "" >>.env
echo "# Database" >> .env echo "# Database" >>.env
echo "DATABASE_URL=\"file:./data/settings.db\"" >> .env echo "DATABASE_URL=\"file:./data/settings.db\"" >>.env
log_success "DATABASE_URL added to .env file" log_success "DATABASE_URL added to .env file"
} }
@@ -481,11 +489,9 @@ check_service() {
fi fi
} }
# Stop the application before updating # Stop the application before updating
stop_application() { stop_application() {
# Change to the application directory if we're not already there # Change to the application directory if we're not already there
local app_dir local app_dir
if [ -f "package.json" ] && [ -f "server.js" ]; then if [ -f "package.json" ] && [ -f "server.js" ]; then
@@ -503,9 +509,9 @@ stop_application() {
return 1 return 1
fi fi
fi fi
log "Working from application directory: $(pwd)" log "Working from application directory: $(pwd)"
# Check if systemd service is running and disable it temporarily # Check if systemd service is running and disable it temporarily
if check_service && systemctl is-active --quiet pvescriptslocal.service; then if check_service && systemctl is-active --quiet pvescriptslocal.service; then
log "Disabling systemd service temporarily to prevent auto-restart..." log "Disabling systemd service temporarily to prevent auto-restart..."
@@ -518,7 +524,7 @@ stop_application() {
else else
log "No running systemd service found" log "No running systemd service found"
fi fi
# Kill any remaining npm/node processes # Kill any remaining npm/node processes
log "Killing any remaining npm/node processes..." log "Killing any remaining npm/node processes..."
local pids local pids
@@ -537,9 +543,9 @@ stop_application() {
# Update application files # Update application files
update_files() { update_files() {
local source_dir="$1" local source_dir="$1"
log "Updating application files..." log "Updating application files..."
# List of files/directories to exclude from update # List of files/directories to exclude from update
local exclude_patterns=( local exclude_patterns=(
"data" "data"
@@ -555,48 +561,48 @@ update_files() {
"scripts/tools" "scripts/tools"
"scripts/vm" "scripts/vm"
) )
# Find the actual source directory (strip the top-level directory) # Find the actual source directory (strip the top-level directory)
local actual_source_dir local actual_source_dir
actual_source_dir=$(find "$source_dir" -maxdepth 1 -type d -name "community-scripts-ProxmoxVE-Local-*" | head -1) actual_source_dir=$(find "$source_dir" -maxdepth 1 -type d -name "community-scripts-ProxmoxVE-Local-*" | head -1)
if [ -z "$actual_source_dir" ]; then if [ -z "$actual_source_dir" ]; then
log_error "Could not find the actual source directory in $source_dir" log_error "Could not find the actual source directory in $source_dir"
return 1 return 1
fi fi
# Verify critical files exist in source # Verify critical files exist in source
if [ ! -f "$actual_source_dir/package.json" ]; then if [ ! -f "$actual_source_dir/package.json" ]; then
log_error "package.json not found in source directory!" log_error "package.json not found in source directory!"
return 1 return 1
fi fi
# Use process substitution instead of pipe to avoid subshell issues # Use process substitution instead of pipe to avoid subshell issues
local files_copied=0 local files_copied=0
local files_excluded=0 local files_excluded=0
# Create a temporary file list to avoid process substitution issues # Create a temporary file list to avoid process substitution issues
local file_list="/tmp/file_list_$$.txt" local file_list="/tmp/file_list_$$.txt"
find "$actual_source_dir" -type f > "$file_list" find "$actual_source_dir" -type f >"$file_list"
while IFS= read -r file; do while IFS= read -r file; do
local rel_path="${file#$actual_source_dir/}" local rel_path="${file#$actual_source_dir/}"
local should_exclude=false local should_exclude=false
for pattern in "${exclude_patterns[@]}"; do for pattern in "${exclude_patterns[@]}"; do
if [[ "$rel_path" == $pattern ]] || [[ "$rel_path" == $pattern/* ]]; then if [[ "$rel_path" == $pattern ]] || [[ "$rel_path" == $pattern/* ]]; then
should_exclude=true should_exclude=true
break break
fi fi
done done
if [ "$should_exclude" = false ]; then if [ "$should_exclude" = false ]; then
local target_dir local target_dir
target_dir=$(dirname "$rel_path") target_dir=$(dirname "$rel_path")
if [ "$target_dir" != "." ]; then if [ "$target_dir" != "." ]; then
mkdir -p "$target_dir" mkdir -p "$target_dir"
fi fi
if ! cp "$file" "$rel_path"; then if ! cp "$file" "$rel_path"; then
log_error "Failed to copy $rel_path" log_error "Failed to copy $rel_path"
rm -f "$file_list" rm -f "$file_list"
@@ -606,48 +612,47 @@ update_files() {
else else
files_excluded=$((files_excluded + 1)) files_excluded=$((files_excluded + 1))
fi fi
done < "$file_list" done <"$file_list"
# Clean up temporary file # Clean up temporary file
rm -f "$file_list" rm -f "$file_list"
# Verify critical files were copied # Verify critical files were copied
if [ ! -f "package.json" ]; then if [ ! -f "package.json" ]; then
log_error "package.json was not copied to target directory!" log_error "package.json was not copied to target directory!"
return 1 return 1
fi fi
if [ ! -f "package-lock.json" ]; then if [ ! -f "package-lock.json" ]; then
log_warning "package-lock.json was not copied!" log_warning "package-lock.json was not copied!"
fi fi
log_success "Application files updated successfully ($files_copied files)" log_success "Application files updated successfully ($files_copied files)"
} }
# Install dependencies and build # Install dependencies and build
install_and_build() { install_and_build() {
log "Installing dependencies..." log "Installing dependencies..."
# Verify package.json exists # Verify package.json exists
if [ ! -f "package.json" ]; then if [ ! -f "package.json" ]; then
log_error "package.json not found! Cannot install dependencies." log_error "package.json not found! Cannot install dependencies."
return 1 return 1
fi fi
if [ ! -f "package-lock.json" ]; then if [ ! -f "package-lock.json" ]; then
log_warning "No package-lock.json found, npm will generate one" log_warning "No package-lock.json found, npm will generate one"
fi fi
# Create temporary file for npm output # Create temporary file for npm output
local npm_log="/tmp/npm_install_$$.log" local npm_log="/tmp/npm_install_$$.log"
# Ensure NODE_ENV is not set to production during install (we need devDependencies for build) # Ensure NODE_ENV is not set to production during install (we need devDependencies for build)
local old_node_env="${NODE_ENV:-}" local old_node_env="${NODE_ENV:-}"
export NODE_ENV=development export NODE_ENV=development
# Run npm install to get ALL dependencies including devDependencies # Run npm install to get ALL dependencies including devDependencies
if ! npm install --include=dev > "$npm_log" 2>&1; then if ! npm install --include=dev >"$npm_log" 2>&1; then
log_error "Failed to install dependencies" log_error "Failed to install dependencies"
log_error "npm install output (last 30 lines):" log_error "npm install output (last 30 lines):"
tail -30 "$npm_log" | while read -r line; do tail -30 "$npm_log" | while read -r line; do
@@ -656,20 +661,20 @@ install_and_build() {
rm -f "$npm_log" rm -f "$npm_log"
return 1 return 1
fi fi
# Restore NODE_ENV # Restore NODE_ENV
if [ -n "$old_node_env" ]; then if [ -n "$old_node_env" ]; then
export NODE_ENV="$old_node_env" export NODE_ENV="$old_node_env"
else else
unset NODE_ENV unset NODE_ENV
fi fi
log_success "Dependencies installed successfully" log_success "Dependencies installed successfully"
rm -f "$npm_log" rm -f "$npm_log"
# Generate Prisma client # Generate Prisma client
log "Generating Prisma client..." log "Generating Prisma client..."
if ! npx prisma generate > "$npm_log" 2>&1; then if ! npx prisma generate >"$npm_log" 2>&1; then
log_error "Failed to generate Prisma client" log_error "Failed to generate Prisma client"
log_error "Prisma generate output:" log_error "Prisma generate output:"
cat "$npm_log" | while read -r line; do cat "$npm_log" | while read -r line; do
@@ -679,7 +684,7 @@ install_and_build() {
return 1 return 1
fi fi
log_success "Prisma client generated successfully" log_success "Prisma client generated successfully"
# Check if Prisma migrations exist and are compatible # Check if Prisma migrations exist and are compatible
if [ -d "prisma/migrations" ]; then if [ -d "prisma/migrations" ]; then
log "Existing migration history detected" log "Existing migration history detected"
@@ -688,10 +693,10 @@ install_and_build() {
else else
log_warning "No existing migration history found - this may be a fresh install" log_warning "No existing migration history found - this may be a fresh install"
fi fi
# Run Prisma migrations # Run Prisma migrations
log "Running Prisma migrations..." log "Running Prisma migrations..."
if ! npx prisma migrate deploy > "$npm_log" 2>&1; then if ! npx prisma migrate deploy >"$npm_log" 2>&1; then
log_warning "Prisma migrations failed or no migrations to run" log_warning "Prisma migrations failed or no migrations to run"
log "Prisma migrate output:" log "Prisma migrate output:"
cat "$npm_log" | while read -r line; do cat "$npm_log" | while read -r line; do
@@ -701,15 +706,18 @@ install_and_build() {
log_success "Prisma migrations completed successfully" log_success "Prisma migrations completed successfully"
fi fi
rm -f "$npm_log" rm -f "$npm_log"
log "Building application..." log "Building application..."
# Set NODE_ENV to production for build # Set NODE_ENV to production for build
export NODE_ENV=production export NODE_ENV=production
# Unset TURBOPACK to prevent "Multiple bundler flags" error with --webpack
unset TURBOPACK 2>/dev/null || true
export TURBOPACK=''
# Create temporary file for npm build output # Create temporary file for npm build output
local build_log="/tmp/npm_build_$$.log" local build_log="/tmp/npm_build_$$.log"
if ! npm run build > "$build_log" 2>&1; then if ! TURBOPACK='' npm run build >"$build_log" 2>&1; then
log_error "Failed to build application" log_error "Failed to build application"
log_error "npm run build output:" log_error "npm run build output:"
cat "$build_log" | while read -r line; do cat "$build_log" | while read -r line; do
@@ -718,18 +726,18 @@ install_and_build() {
rm -f "$build_log" rm -f "$build_log"
return 1 return 1
fi fi
# Log success and clean up # Log success and clean up
log_success "Application built successfully" log_success "Application built successfully"
rm -f "$build_log" rm -f "$build_log"
log_success "Dependencies installed and application built successfully" log_success "Dependencies installed and application built successfully"
} }
# Start the application after updating # Start the application after updating
start_application() { start_application() {
log "Starting application..." log "Starting application..."
# Use the global variable to determine how to start # Use the global variable to determine how to start
if [ "$SERVICE_WAS_RUNNING" = true ] && check_service; then if [ "$SERVICE_WAS_RUNNING" = true ] && check_service; then
log "Service was running before update, re-enabling and starting systemd service..." log "Service was running before update, re-enabling and starting systemd service..."
@@ -761,11 +769,11 @@ start_application() {
# Start application with npm # Start application with npm
start_with_npm() { start_with_npm() {
log "Starting application with npm start..." log "Starting application with npm start..."
# Start in background # Start in background
nohup npm start > server.log 2>&1 & nohup npm start >server.log 2>&1 &
local npm_pid=$! local npm_pid=$!
# Wait a moment and check if it started # Wait a moment and check if it started
sleep 3 sleep 3
if kill -0 $npm_pid 2>/dev/null; then if kill -0 $npm_pid 2>/dev/null; then
@@ -776,13 +784,30 @@ start_with_npm() {
fi fi
} }
# Re-enable the systemd service on failure to prevent users from being locked out
re_enable_service_on_failure() {
if check_service; then
log "Re-enabling systemd service after failure..."
if systemctl enable pvescriptslocal.service 2>/dev/null; then
log_success "Service re-enabled"
if systemctl start pvescriptslocal.service 2>/dev/null; then
log_success "Service started"
else
log_warning "Failed to start service - manual intervention may be required"
fi
else
log_warning "Failed to re-enable service - manual intervention may be required"
fi
fi
}
# Rollback function # Rollback function
rollback() { rollback() {
log_warning "Rolling back to previous version..." log_warning "Rolling back to previous version..."
if [ -d "$BACKUP_DIR" ]; then if [ -d "$BACKUP_DIR" ]; then
log "Restoring from backup directory: $BACKUP_DIR" log "Restoring from backup directory: $BACKUP_DIR"
# Restore data directory # Restore data directory
if [ -d "$BACKUP_DIR/data" ]; then if [ -d "$BACKUP_DIR/data" ]; then
log "Restoring data directory..." log "Restoring data directory..."
@@ -797,7 +822,7 @@ rollback() {
else else
log_warning "No data directory backup found" log_warning "No data directory backup found"
fi fi
# Restore .env file # Restore .env file
if [ -f "$BACKUP_DIR/.env" ]; then if [ -f "$BACKUP_DIR/.env" ]; then
log "Restoring .env file..." log "Restoring .env file..."
@@ -812,24 +837,24 @@ rollback() {
else else
log_warning "No .env file backup found" log_warning "No .env file backup found"
fi fi
# Restore scripts directories # Restore scripts directories
local scripts_dirs=("ct" "install" "tools" "vm") local scripts_dirs=("ct" "install" "tools" "vm")
for backup_name in "${scripts_dirs[@]}"; do for backup_name in "${scripts_dirs[@]}"; do
if [ -d "$BACKUP_DIR/$backup_name" ]; then if [ -d "$BACKUP_DIR/$backup_name" ]; then
local target_dir="scripts/$backup_name" local target_dir="scripts/$backup_name"
log "Restoring $target_dir directory from backup..." log "Restoring $target_dir directory from backup..."
# Ensure scripts directory exists # Ensure scripts directory exists
if [ ! -d "scripts" ]; then if [ ! -d "scripts" ]; then
mkdir -p "scripts" mkdir -p "scripts"
fi fi
# Remove existing directory if it exists # Remove existing directory if it exists
if [ -d "$target_dir" ]; then if [ -d "$target_dir" ]; then
rm -rf "$target_dir" rm -rf "$target_dir"
fi fi
if mv "$BACKUP_DIR/$backup_name" "$target_dir"; then if mv "$BACKUP_DIR/$backup_name" "$target_dir"; then
log_success "$target_dir directory restored from backup" log_success "$target_dir directory restored from backup"
else else
@@ -839,14 +864,17 @@ rollback() {
log_warning "No $backup_name directory backup found" log_warning "No $backup_name directory backup found"
fi fi
done done
# Clean up backup directory # Clean up backup directory
log "Cleaning up backup directory..." log "Cleaning up backup directory..."
rm -rf "$BACKUP_DIR" rm -rf "$BACKUP_DIR"
else else
log_error "No backup directory found for rollback" log_error "No backup directory found for rollback"
fi fi
# Re-enable the service so users aren't locked out
re_enable_service_on_failure
log_error "Update failed. Please check the logs and try again." log_error "Update failed. Please check the logs and try again."
exit 1 exit 1
} }
@@ -865,14 +893,14 @@ check_node_version() {
log "Detected Node.js version: $current" log "Detected Node.js version: $current"
if (( major_version < 24 )); then if ((major_version == 24)); then
log_success "Node.js 24 already installed"
elif ((major_version < 24)); then
log_warning "Node.js < 24 detected → upgrading to Node.js 24 LTS..." log_warning "Node.js < 24 detected → upgrading to Node.js 24 LTS..."
upgrade_node_to_24 upgrade_node_to_24
elif (( major_version > 24 )); then else
log_warning "Node.js > 24 detected → script tested only up to Node 24" log_warning "Node.js > 24 detected → script tested only up to Node 24"
log "Continuing anyway…" log "Continuing anyway…"
else
log_success "Node.js 24 already installed"
fi fi
} }
@@ -880,22 +908,39 @@ check_node_version() {
upgrade_node_to_24() { upgrade_node_to_24() {
log "Preparing Node.js 24 upgrade…" log "Preparing Node.js 24 upgrade…"
# Remove old nodesource repo if it exists # Remove old nodesource repo files if they exist
if [ -f /etc/apt/sources.list.d/nodesource.list ]; then if [ -f /etc/apt/sources.list.d/nodesource.list ]; then
log "Removing old nodesource.list file..."
rm -f /etc/apt/sources.list.d/nodesource.list rm -f /etc/apt/sources.list.d/nodesource.list
fi fi
if [ -f /etc/apt/sources.list.d/nodesource.sources ]; then
log "Removing old nodesource.sources file..."
rm -f /etc/apt/sources.list.d/nodesource.sources
fi
# Update apt cache first
log "Updating apt cache..."
apt-get update >>"$LOG_FILE" 2>&1 || true
# Install NodeSource repo for Node.js 24 # Install NodeSource repo for Node.js 24
curl -fsSL https://deb.nodesource.com/setup_24.x -o /tmp/node24_setup.sh log "Downloading Node.js 24 setup script..."
if ! bash /tmp/node24_setup.sh > /tmp/node24_setup.log 2>&1; then if ! curl -fsSL https://deb.nodesource.com/setup_24.x -o /tmp/node24_setup.sh; then
log_error "Failed to download Node.js 24 setup script"
re_enable_service_on_failure
exit 1
fi
if ! bash /tmp/node24_setup.sh >/tmp/node24_setup.log 2>&1; then
log_error "Failed to configure Node.js 24 repository" log_error "Failed to configure Node.js 24 repository"
tail -20 /tmp/node24_setup.log | while read -r line; do log_error "$line"; done tail -20 /tmp/node24_setup.log | while read -r line; do log_error "$line"; done
re_enable_service_on_failure
exit 1 exit 1
fi fi
log "Installing Node.js 24…" log "Installing Node.js 24…"
if ! apt-get install -y nodejs >> "$LOG_FILE" 2>&1; then if ! apt-get install -y nodejs >>"$LOG_FILE" 2>&1; then
log_error "Failed to install Node.js 24" log_error "Failed to install Node.js 24"
re_enable_service_on_failure
exit 1 exit 1
fi fi
@@ -912,21 +957,21 @@ main() {
init_log init_log
log "Running as detached process" log "Running as detached process"
sleep 3 sleep 3
else else
init_log init_log
fi fi
# Check if we're running from the application directory and not already relocated # Check if we're running from the application directory and not already relocated
if [ -z "${PVE_UPDATE_RELOCATED:-}" ] && [ -f "package.json" ] && [ -f "server.js" ]; then if [ -z "${PVE_UPDATE_RELOCATED:-}" ] && [ -f "package.json" ] && [ -f "server.js" ]; then
log "Detected running from application directory" log "Detected running from application directory"
bash "$0" --relocated bash "$0" --relocated
exit $? exit $?
fi fi
# Ensure we're in the application directory # Ensure we're in the application directory
local app_dir local app_dir
# First check if we're already in the right directory # First check if we're already in the right directory
if [ -f "package.json" ] && [ -f "server.js" ]; then if [ -f "package.json" ] && [ -f "server.js" ]; then
app_dir="$(pwd)" app_dir="$(pwd)"
@@ -943,79 +988,76 @@ main() {
exit 1 exit 1
fi fi
fi fi
# Check dependencies # Check dependencies
check_dependencies check_dependencies
# Load GitHub token for higher rate limits # Load GitHub token for higher rate limits
load_github_token load_github_token
# Check if service was running before update # Check if service was running before update
if check_service && systemctl is-active --quiet pvescriptslocal.service; then if check_service && systemctl is-active --quiet pvescriptslocal.service; then
SERVICE_WAS_RUNNING=true SERVICE_WAS_RUNNING=true
else else
SERVICE_WAS_RUNNING=false SERVICE_WAS_RUNNING=false
fi fi
# Get latest release info # Get latest release info
local release_info local release_info
release_info=$(get_latest_release) release_info=$(get_latest_release)
# Backup data directory # Backup data directory
backup_data backup_data
# Stop the application before updating # Stop the application before updating
stop_application stop_application
# Check Node.js version # Check Node.js version
check_node_version check_node_version
#Update Node.js to 24
upgrade_node_to_24
# Download and extract release # Download and extract release
local source_dir local source_dir
source_dir=$(download_release "$release_info") source_dir=$(download_release "$release_info")
# Clear the original directory before updating # Clear the original directory before updating
clear_original_directory clear_original_directory
# Update files # Update files
if ! update_files "$source_dir"; then if ! update_files "$source_dir"; then
log_error "File update failed, rolling back..." log_error "File update failed, rolling back..."
rollback rollback
fi fi
# Restore .env and data directory before building # Restore .env and data directory before building
restore_backup_files restore_backup_files
# Verify database was restored correctly # Verify database was restored correctly
if ! verify_database_restored; then if ! verify_database_restored; then
log_error "Database verification failed, rolling back..." log_error "Database verification failed, rolling back..."
rollback rollback
fi fi
# Ensure DATABASE_URL is set for Prisma # Ensure DATABASE_URL is set for Prisma
ensure_database_url ensure_database_url
# Install dependencies and build # Install dependencies and build
if ! install_and_build; then if ! install_and_build; then
log_error "Install and build failed, rolling back..." log_error "Install and build failed, rolling back..."
rollback rollback
fi fi
# Start the application # Start the application
if ! start_application; then if ! start_application; then
log_error "Failed to start application after update" log_error "Failed to start application after update"
rollback rollback
fi fi
# Cleanup only after successful start # Cleanup only after successful start
rm -rf "$source_dir" rm -rf "$source_dir"
rm -rf "/tmp/pve-update-$$" rm -rf "/tmp/pve-update-$$"
rm -rf "$BACKUP_DIR" rm -rf "$BACKUP_DIR"
log "Backup directory cleaned up" log "Backup directory cleaned up"
log_success "Update completed successfully!" log_success "Update completed successfully!"
} }
@@ -1023,4 +1065,4 @@ main() {
if ! main "$@"; then if ! main "$@"; then
log_error "Update script failed with exit code $?" log_error "Update script failed with exit code $?"
exit 1 exit 1
fi fi