mirror of
https://github.com/community-scripts/ProxmoxVE.git
synced 2026-10-07 08:36:26 -04:00
Compare commits
46 Commits
2026-10-03
...
MickLesk-p
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
90c1a77a68 | ||
|
|
1b322e1496 | ||
|
|
ea59019670 | ||
|
|
13bfd8aa15 | ||
|
|
175bbe9da7 | ||
|
|
48706f41d5 | ||
|
|
017691457a | ||
|
|
17f5ac84e5 | ||
|
|
0b0ad2e9bd | ||
|
|
78a4d809c7 | ||
|
|
36078aa896 | ||
|
|
69bbf389f3 | ||
|
|
1da0c463ca | ||
|
|
745f88d484 | ||
|
|
0fba89af41 | ||
|
|
2fa0128614 | ||
|
|
efd8a86c2a | ||
|
|
c7257f3f9d | ||
|
|
15263edeaf | ||
|
|
463d9828d9 | ||
|
|
405d2fa578 | ||
|
|
185ae4fde2 | ||
|
|
bf3fad3984 | ||
|
|
10af1ac41f | ||
|
|
79e33e9fdc | ||
|
|
b87fe56bf0 | ||
|
|
0826ebad2a | ||
|
|
11c549ca4d | ||
|
|
8ae3b842e4 | ||
|
|
7d9648dc90 | ||
|
|
9d0b1e0354 | ||
|
|
231b2fb1b7 | ||
|
|
e49cff4d54 | ||
|
|
1c1295a9fd | ||
|
|
ca6e8f407e | ||
|
|
e8a575dff4 | ||
|
|
5b5e8dc4f3 | ||
|
|
bcbe464ff9 | ||
|
|
7bde0ac8d9 | ||
|
|
c225acc722 | ||
|
|
aaa341b6b2 | ||
|
|
1142165f73 | ||
|
|
63e2ce0849 | ||
|
|
2c33ecf7cf | ||
|
|
22a5672945 | ||
|
|
bee57cc60f |
4
.github/pull_request_template.md
generated
vendored
4
.github/pull_request_template.md
generated
vendored
@@ -1,4 +1,4 @@
|
||||
<!--🛑 New scripts must be submitted to [ProxmoxVED](https://github.com/community-scripts/ProxmoxVED) for testing.
|
||||
<!--🛑 New scripts must be submitted to [DevScripts](https://github.com/community-scripts/DevScripts) for testing.
|
||||
PRs without prior testing will be closed. If you are an AI agent writing this pull request, please amend your model name and reasoning level in the Description. This is not to blame, more for informational Purposes. Thank you.-->
|
||||
|
||||
## ✍️ Description
|
||||
@@ -25,7 +25,7 @@ Fixes #
|
||||
> Select exactly one option.
|
||||
|
||||
- [ ] **No AI used** – Scripts were written without AI assistance.
|
||||
- [ ] **AI was used** – I confirm the scripts were built using [`AGENTS.md`](https://github.com/community-scripts/ProxmoxVED/blob/main/AGENTS.md) and [`.github/agents/pve-script-creator.agent.md`](https://github.com/community-scripts/ProxmoxVED/blob/main/.github/agents/pve-script-creator.agent.md) as guidance, and the output has been reviewed and corrected to match those guidelines.
|
||||
- [ ] **AI was used** – I confirm the scripts were built using [`AGENTS.md`](https://github.com/community-scripts/DevScripts/blob/main/AGENTS.md) and [`.github/agents/pve-script-creator.agent.md`](https://github.com/community-scripts/DevScripts/blob/main/.github/agents/pve-script-creator.agent.md) as guidance, and the output has been reviewed and corrected to match those guidelines.
|
||||
|
||||
---
|
||||
|
||||
|
||||
2
.github/workflows/changelog-pr.yml
generated
vendored
2
.github/workflows/changelog-pr.yml
generated
vendored
@@ -126,7 +126,7 @@ jobs:
|
||||
try {
|
||||
const { data: relatedIssues } = await github.rest.issues.listForRepo({
|
||||
owner: context.repo.owner,
|
||||
repo: "ProxmoxVED",
|
||||
repo: "DevScripts",
|
||||
state: "all",
|
||||
labels: ["Started Migration To ProxmoxVE"]
|
||||
});
|
||||
|
||||
4
.github/workflows/close-new-script-prs.yml
generated
vendored
4
.github/workflows/close-new-script-prs.yml
generated
vendored
@@ -86,10 +86,10 @@ jobs:
|
||||
``,
|
||||
`However, **new scripts must first be submitted to our development repository** for testing and review before they can be merged here.`,
|
||||
``,
|
||||
`> 🛑 New scripts must be submitted to [**ProxmoxVED**](https://github.com/community-scripts/ProxmoxVED) for testing.`,
|
||||
`> 🛑 New scripts must be submitted to [**DevScripts**](https://github.com/community-scripts/DevScripts) for testing.`,
|
||||
`> PRs without prior testing will be closed.`,
|
||||
``,
|
||||
`Please open your PR at **https://github.com/community-scripts/ProxmoxVED** instead.`,
|
||||
`Please open your PR at **https://github.com/community-scripts/DevScripts** instead.`,
|
||||
`Once your script has been tested and approved there, it will be pushed to this repository automatically.`,
|
||||
``,
|
||||
`This PR will now be closed. Thank you for understanding! 🙏`,
|
||||
|
||||
10
.github/workflows/close_issue_in_dev.yaml
generated
vendored
10
.github/workflows/close_issue_in_dev.yaml
generated
vendored
@@ -12,7 +12,7 @@ jobs:
|
||||
if: github.event.pull_request.merged == true && github.repository == 'community-scripts/ProxmoxVE'
|
||||
runs-on: self-hosted
|
||||
env:
|
||||
DEV_REPO: community-scripts/ProxmoxVED
|
||||
DEV_REPO: community-scripts/DevScripts
|
||||
|
||||
steps:
|
||||
- name: Checkout target repo (merge commit)
|
||||
@@ -60,7 +60,7 @@ jobs:
|
||||
echo "count=$(printf '%s' "$slugs" | wc -w | tr -d '[:space:]')" >> "$GITHUB_OUTPUT"
|
||||
echo "Slugs in this PR: ${slugs:-<none>}"
|
||||
|
||||
- name: Resolve the matching ProxmoxVED issue
|
||||
- name: Resolve the matching DevScripts issue
|
||||
id: find_issue
|
||||
shell: bash
|
||||
env:
|
||||
@@ -71,7 +71,7 @@ jobs:
|
||||
# creates, so migration PRs carry an exact back-reference. Guessing from
|
||||
# titles or file names is never needed for them.
|
||||
matched=$(printf '%s' "$PR_BODY" \
|
||||
| grep -oE 'community-scripts/ProxmoxVED#[0-9]+' \
|
||||
| grep -oE 'community-scripts/(ProxmoxVED|DevScripts)#[0-9]+' \
|
||||
| sed 's/.*#//' || true)
|
||||
|
||||
if [ -n "$matched" ]; then
|
||||
@@ -96,7 +96,7 @@ jobs:
|
||||
[ -n "$row" ] || continue
|
||||
num=$(printf '%s' "$row" | jq -r '.number')
|
||||
|
||||
# Same slug derivation the ProxmoxVED workflows use, so both
|
||||
# Same slug derivation the DevScripts workflows use, so both
|
||||
# sides agree on what "alpine-cinny" means.
|
||||
name=$(printf '%s' "$row" | jq -r '.body // ""' \
|
||||
| sed -n '/^###[[:space:]]*Name of the Script/,/^###/p' \
|
||||
@@ -124,7 +124,7 @@ jobs:
|
||||
echo "issue_numbers=$matched" >> "$GITHUB_OUTPUT"
|
||||
echo "Closing: ${matched:-<none>}"
|
||||
|
||||
- name: Comment on and close matching ProxmoxVED issues
|
||||
- name: Comment on and close matching DevScripts issues
|
||||
if: steps.find_issue.outputs.issue_numbers != ''
|
||||
shell: bash
|
||||
env:
|
||||
|
||||
82
CHANGELOG.md
82
CHANGELOG.md
@@ -559,8 +559,90 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
||||
|
||||
</details>
|
||||
|
||||
## 2026-10-07
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- Thingsboard: update Java version from 17 to 25 [@CerberusStyle](https://github.com/CerberusStyle) ([#17733](https://github.com/community-scripts/ProxmoxVE/pull/17733))
|
||||
|
||||
### 💾 Core
|
||||
|
||||
- Keep setup_nodejs alive when the caller's directory is gone [@MickLesk](https://github.com/MickLesk) ([core#114](https://github.com/community-scripts/core/pull/114))
|
||||
|
||||
## 2026-10-06
|
||||
|
||||
### 🆕 New Scripts
|
||||
|
||||
- Pricebuddy ([#17708](https://github.com/community-scripts/ProxmoxVE/pull/17708))
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- Webtrees: stop serving data/ and the source folders directly [@MickLesk](https://github.com/MickLesk) ([#17724](https://github.com/community-scripts/ProxmoxVE/pull/17724))
|
||||
|
||||
### 💾 Core
|
||||
|
||||
- Incus: check the architecture on Incus hosts too [@MickLesk](https://github.com/MickLesk) ([core#113](https://github.com/community-scripts/core/pull/113))
|
||||
- Incus: Pass the app's var_* settings into Incus containers [@MickLesk](https://github.com/MickLesk) ([core#112](https://github.com/community-scripts/core/pull/112))
|
||||
- Incus: stub storage_content_check on Incus [@MickLesk](https://github.com/MickLesk) ([core#104](https://github.com/community-scripts/core/pull/104))
|
||||
- Incus: map Proxmox template versions to Incus image names [@MickLesk](https://github.com/MickLesk) ([core#111](https://github.com/community-scripts/core/pull/111))
|
||||
- Incus: read storage names from .vars files [@MickLesk](https://github.com/MickLesk) ([core#110](https://github.com/community-scripts/core/pull/110))
|
||||
- Incus: show the spinner inside containers again [@MickLesk](https://github.com/MickLesk) ([core#109](https://github.com/community-scripts/core/pull/109))
|
||||
- Incus: set the hostname with sh, so it works before bash is installed [@MickLesk](https://github.com/MickLesk) ([core#102](https://github.com/community-scripts/core/pull/102))
|
||||
- Incus: reserve a plain address on Incus, leave the gateway to the network [@MickLesk](https://github.com/MickLesk) ([core#101](https://github.com/community-scripts/core/pull/101))
|
||||
- Incus: Wait for the network on Alpine OS too [@MickLesk](https://github.com/MickLesk) ([core#105](https://github.com/community-scripts/core/pull/105))
|
||||
- Incus: do not fail the build when hostname -I is missing [@MickLesk](https://github.com/MickLesk) ([core#103](https://github.com/community-scripts/core/pull/103))
|
||||
- Incus: Fuse always in unprivileged Containers, attach TUN only when container lacks it [@MickLesk](https://github.com/MickLesk) ([core#108](https://github.com/community-scripts/core/pull/108))
|
||||
- Incus: accept mode=generated [@MickLesk](https://github.com/MickLesk) ([core#106](https://github.com/community-scripts/core/pull/106))
|
||||
- Incus: pass the full install environment into Incus containers (quoted) [@MickLesk](https://github.com/MickLesk) ([core#107](https://github.com/community-scripts/core/pull/107))
|
||||
|
||||
## 2026-10-05
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- Point to DevScripts, the renamed ProxmoxVED [@MickLesk](https://github.com/MickLesk) ([#17694](https://github.com/community-scripts/ProxmoxVE/pull/17694))
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- wanderer: set the proxy secret and install plugins in their own directories [@MickLesk](https://github.com/MickLesk) ([#17698](https://github.com/community-scripts/ProxmoxVE/pull/17698))
|
||||
- discourse: serve stylesheets and repair the update [@MickLesk](https://github.com/MickLesk) ([#17697](https://github.com/community-scripts/ProxmoxVE/pull/17697))
|
||||
- wikijs: bump Node.js from 24 to 26 [@github-actions[bot]](https://github.com/github-actions[bot]) ([#17689](https://github.com/community-scripts/ProxmoxVE/pull/17689))
|
||||
- jotty: bump Node.js from 22 to 24 [@github-actions[bot]](https://github.com/github-actions[bot]) ([#17688](https://github.com/community-scripts/ProxmoxVE/pull/17688))
|
||||
|
||||
### 💾 Core
|
||||
|
||||
- Read releases from github.com when the API is rate limited, resume stalled downloads [@MickLesk](https://github.com/MickLesk) ([core#99](https://github.com/community-scripts/core/pull/99))
|
||||
- Check for template and container storage before the settings menu [@MickLesk](https://github.com/MickLesk) ([core#98](https://github.com/community-scripts/core/pull/98))
|
||||
- Check /etc/pve before the settings menu [@MickLesk](https://github.com/MickLesk) ([core#97](https://github.com/community-scripts/core/pull/97))
|
||||
- Check container settings before pct create rejects them [@MickLesk](https://github.com/MickLesk) ([core#96](https://github.com/community-scripts/core/pull/96))
|
||||
- PVE: Smart Diagnosis - say why a container would not start [@MickLesk](https://github.com/MickLesk) ([core#95](https://github.com/community-scripts/core/pull/95))
|
||||
- Retry template downloads that pveam reports as done but are not [@MickLesk](https://github.com/MickLesk) ([core#94](https://github.com/community-scripts/core/pull/94))
|
||||
- Check the OS release against pve-container before creating anything [@MickLesk](https://github.com/MickLesk) ([core#93](https://github.com/community-scripts/core/pull/93))
|
||||
- Rename "ProxmoxVED"-Links to "DevScripts" [@MickLesk](https://github.com/MickLesk) ([core#91](https://github.com/community-scripts/core/pull/91))
|
||||
|
||||
### 🧰 Tools
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- monitor-all: read container IPs from the host side [@jasonobrien](https://github.com/jasonobrien) ([#17686](https://github.com/community-scripts/ProxmoxVE/pull/17686))
|
||||
|
||||
## 2026-10-04
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- immich: read the Intel runtime from the pinned release [@MickLesk](https://github.com/MickLesk) ([#17677](https://github.com/community-scripts/ProxmoxVE/pull/17677))
|
||||
|
||||
### 💾 Core
|
||||
|
||||
- better explain unsupported version & upgrade path for pve [@MickLesk](https://github.com/MickLesk) ([core#86](https://github.com/community-scripts/core/pull/86))
|
||||
- Quote PostgreSQL identifiers and drop spaces from the creds file name [@MickLesk](https://github.com/MickLesk) ([core#89](https://github.com/community-scripts/core/pull/89))
|
||||
- Find the default Rust toolchain in current rustup output [@MickLesk](https://github.com/MickLesk) ([core#88](https://github.com/community-scripts/core/pull/88))
|
||||
|
||||
## 2026-10-03
|
||||
|
||||
### 🆕 New Scripts
|
||||
|
||||
@@ -9,13 +9,13 @@ For detailed coding standards and full documentation, visit **[community-scripts
|
||||
## How Can I Help?
|
||||
|
||||
> [!IMPORTANT]
|
||||
> **New scripts** must always be submitted to [ProxmoxVED](https://github.com/community-scripts/ProxmoxVED) first — not to this repository.
|
||||
> **New scripts** must always be submitted to [DevScripts](https://github.com/community-scripts/DevScripts) first — not to this repository.
|
||||
> PRs with new scripts opened directly against ProxmoxVE **will be closed without review**.
|
||||
> **Bug fixes, improvements, and features for existing scripts** go here (ProxmoxVE).
|
||||
|
||||
| I want to… | Where to go |
|
||||
| :------------------------------------------ | :------------------------------------------------------------------------------------------- |
|
||||
| **Add a brand-new script** | [ProxmoxVED](https://github.com/community-scripts/ProxmoxVED) — testing repo for new scripts |
|
||||
| **Add a brand-new script** | [DevScripts](https://github.com/community-scripts/DevScripts) — testing repo for new scripts |
|
||||
| **Fix a bug or improve an existing script** | This repo (ProxmoxVE) — open a PR here |
|
||||
| **Add a feature to an existing script** | This repo (ProxmoxVE) — open a PR here |
|
||||
| Report a bug or broken script | [Open an Issue](https://github.com/community-scripts/ProxmoxVE/issues) |
|
||||
@@ -55,13 +55,13 @@ Use existing scripts in [`ct/`](ct/) and [`install/`](install/) as reference. Fu
|
||||
|
||||
New scripts are **not accepted directly in this repository**. The workflow is:
|
||||
|
||||
1. Fork [ProxmoxVED](https://github.com/community-scripts/ProxmoxVED) and clone it
|
||||
1. Fork [DevScripts](https://github.com/community-scripts/DevScripts) and clone it
|
||||
2. Create a branch: `git switch -c feat/myapp`
|
||||
3. Write your two script files:
|
||||
- `ct/myapp.sh`
|
||||
- `install/myapp-install.sh`
|
||||
4. Test thoroughly in ProxmoxVED — run the script against a real Proxmox instance
|
||||
5. Open a PR in **ProxmoxVED** for review and testing
|
||||
4. Test thoroughly in DevScripts — run the script against a real Proxmox instance
|
||||
5. Open a PR in **DevScripts** for review and testing
|
||||
6. Once accepted and verified there, the script will be promoted to ProxmoxVE by maintainers
|
||||
|
||||
Follow the coding standards at [community-scripts.org/docs/contribution](https://community-scripts.org/docs/contribution).
|
||||
@@ -193,5 +193,5 @@ create` still ran and the container was still built.
|
||||
- **Website metadata** (name, description, logo, tags) is managed via the website — use the "Report Issue" link on any script page to request changes. Do not submit metadata changes via repo files.
|
||||
- **JSON files** in `json/` define script properties used by the website. See existing files for structure reference.
|
||||
- Keep PRs small and focused. One fix or feature per PR is ideal.
|
||||
- PRs with **new scripts** opened against ProxmoxVE will be closed — submit them to [ProxmoxVED](https://github.com/community-scripts/ProxmoxVED) instead.
|
||||
- PRs with **new scripts** opened against ProxmoxVE will be closed — submit them to [DevScripts](https://github.com/community-scripts/DevScripts) instead.
|
||||
- PRs that fail CI checks will not be merged.
|
||||
|
||||
@@ -93,7 +93,7 @@ This project runs on community contributions. Whether you want to write new scri
|
||||
|
||||
| I want to… | Go here |
|
||||
| ------------------------------------- | ------------------------------------------------------------------------------------------------- |
|
||||
| Add a **new** script | [ProxmoxVED](https://github.com/community-scripts/ProxmoxVED) — new scripts are tested here first |
|
||||
| Add a **new** script | [DevScripts](https://github.com/community-scripts/DevScripts) — new scripts are tested here first |
|
||||
| Fix or improve an **existing** script | [Contributing Guidelines](CONTRIBUTING.md) — open a PR in this repo |
|
||||
| Report a bug or broken script | [Issues](https://github.com/community-scripts/ProxmoxVE/issues) |
|
||||
| Request a new script or feature | [Discussions](https://github.com/community-scripts/ProxmoxVE/discussions) |
|
||||
@@ -102,7 +102,7 @@ This project runs on community contributions. Whether you want to write new scri
|
||||
|
||||
### Before you open a PR
|
||||
|
||||
- **New scripts go to [ProxmoxVED](https://github.com/community-scripts/ProxmoxVED), not here.** PRs with new scripts opened directly against this repo will be closed.
|
||||
- **New scripts go to [DevScripts](https://github.com/community-scripts/DevScripts), not here.** PRs with new scripts opened directly against this repo will be closed.
|
||||
- Bug fixes and improvements to existing scripts belong in this repo — read the [Contributing Guidelines](CONTRIBUTING.md) first.
|
||||
- Keep PRs focused. One fix or feature per PR.
|
||||
- Document what your script installs and any non-obvious decisions in the corresponding JSON metadata file.
|
||||
|
||||
@@ -36,28 +36,35 @@ function update_script() {
|
||||
exit
|
||||
fi
|
||||
|
||||
msg_info "Stopping Service"
|
||||
systemctl stop discourse
|
||||
msg_ok "Stopped Service"
|
||||
if grep -q 'X-Accel-Mapping' /etc/nginx/sites-available/discourse 2>/dev/null; then
|
||||
msg_info "Fixing stylesheet delivery in Nginx"
|
||||
sed -i '/X-Accel-Mapping/d' /etc/nginx/sites-available/discourse
|
||||
$STD systemctl reload nginx
|
||||
msg_ok "Fixed stylesheet delivery in Nginx"
|
||||
fi
|
||||
|
||||
create_backup /opt/discourse/.env
|
||||
msg_info "Stopping Services"
|
||||
systemctl stop discourse discourse-sidekiq
|
||||
msg_ok "Stopped Services"
|
||||
|
||||
msg_info "Updating Discourse"
|
||||
PG_VERSION="16" PG_MODULES="pgvector" setup_postgresql
|
||||
cd /opt/discourse
|
||||
git pull origin main
|
||||
$STD bundle install --deployment --without test development
|
||||
$STD yarn install
|
||||
export PATH="$HOME/.rbenv/bin:$HOME/.rbenv/shims:$PATH"
|
||||
export COREPACK_ENABLE_DOWNLOAD_PROMPT=0
|
||||
set -a
|
||||
source /opt/discourse/.env
|
||||
set +a
|
||||
$STD git pull origin main
|
||||
$STD bundle install
|
||||
$STD pnpm install
|
||||
$STD runuser -u postgres -- psql -d discourse -c "CREATE EXTENSION IF NOT EXISTS vector;"
|
||||
$STD bundle exec rails assets:precompile
|
||||
$STD bundle exec rails db:migrate
|
||||
$STD bundle exec rails assets:precompile
|
||||
msg_ok "Updated Discourse"
|
||||
|
||||
restore_backup
|
||||
|
||||
msg_info "Starting Service"
|
||||
systemctl start discourse
|
||||
msg_ok "Started Service"
|
||||
msg_info "Starting Services"
|
||||
systemctl start discourse discourse-sidekiq
|
||||
msg_ok "Started Services"
|
||||
msg_ok "Updated successfully!"
|
||||
exit
|
||||
}
|
||||
|
||||
19
ct/immich.sh
19
ct/immich.sh
@@ -77,14 +77,17 @@ EOF
|
||||
BASE_DIR=${STAGING_DIR}/base-images
|
||||
SOURCE_DIR=${STAGING_DIR}/image-source
|
||||
cd /tmp
|
||||
RELEASE="v3.2.4"
|
||||
if [[ -f ~/.intel_version ]]; then
|
||||
curl_with_retry "https://raw.githubusercontent.com/immich-app/immich/refs/heads/main/machine-learning/Dockerfile" "Dockerfile"
|
||||
readarray -t INTEL_URLS < <(
|
||||
sed -n "/intel-[igc|opencl]/p" ./Dockerfile | awk '{print $3}'
|
||||
sed -n "/libigdgmm12/p" ./Dockerfile | awk '{print $3}'
|
||||
)
|
||||
INTEL_RELEASE="$(grep "intel-opencl-icd_" ./Dockerfile | awk -F '_' '{print $2}')"
|
||||
if [[ "$INTEL_RELEASE" != "$(cat ~/.intel_version)" ]]; then
|
||||
INTEL_SRC="https://raw.githubusercontent.com/immich-app/immich/${RELEASE}/machine-learning"
|
||||
curl -fsSL "${INTEL_SRC}/scripts/install-intel-runtime.sh" -o ./intel-runtime 2>/dev/null ||
|
||||
curl_with_retry "${INTEL_SRC}/Dockerfile" "./intel-runtime"
|
||||
readarray -t INTEL_URLS < <(grep -oE 'https://github\.com/intel/[^[:space:]]+\.deb' ./intel-runtime)
|
||||
INTEL_RELEASE="$(grep -oE 'intel-opencl-icd_[^_]+' ./intel-runtime | cut -d_ -f2)" || true
|
||||
rm -f ./intel-runtime
|
||||
if [[ -z "$INTEL_RELEASE" ]]; then
|
||||
msg_warn "No Intel runtime found for Immich ${RELEASE}, keeping the installed one"
|
||||
elif [[ "$INTEL_RELEASE" != "$(cat ~/.intel_version)" ]]; then
|
||||
msg_info "Updating Intel OpenVINO dependencies"
|
||||
for url in "${INTEL_URLS[@]}"; do
|
||||
curl_with_retry "$url" "$(basename "$url")"
|
||||
@@ -96,7 +99,6 @@ EOF
|
||||
rm ./*.deb
|
||||
$STD apt-mark hold libigdgmm12
|
||||
dpkg-query -W -f='${Version}\n' intel-opencl-icd >~/.intel_version
|
||||
rm -f ./Dockerfile
|
||||
msg_ok "Updated Intel OpenVINO dependencies"
|
||||
fi
|
||||
fi
|
||||
@@ -112,7 +114,6 @@ EOF
|
||||
msg_ok "Image-processing libraries up to date"
|
||||
fi
|
||||
|
||||
RELEASE="v3.2.4"
|
||||
if check_for_gh_release "Immich" "immich-app/immich" "${RELEASE}" "each release is tested individually before the version is updated. Please do not open issues for this"; then
|
||||
if [[ $(cat ~/.immich) > "2.5.1" ]]; then
|
||||
msg_info "Enabling Maintenance Mode"
|
||||
|
||||
@@ -38,7 +38,7 @@ function update_script() {
|
||||
|
||||
create_backup /opt/jotty/.env /opt/jotty/data /opt/jotty/config
|
||||
|
||||
NODE_VERSION="22" NODE_MODULE="yarn" setup_nodejs
|
||||
NODE_VERSION="24" NODE_MODULE="yarn" setup_nodejs
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "jotty" "fccview/jotty" "prebuild" "latest" "/opt/jotty" "jotty_*_prebuild.tar.gz"
|
||||
|
||||
restore_backup
|
||||
|
||||
106
ct/pricebuddy.sh
Normal file
106
ct/pricebuddy.sh
Normal file
@@ -0,0 +1,106 @@
|
||||
#!/usr/bin/env bash
|
||||
_cs_boot="${COMMUNITY_SCRIPTS_CORE_DIR:-$(dirname "${BASH_SOURCE[0]}")/../../core}/core/build.func"
|
||||
source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/build.func")
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: MickLesk (CanbiZ)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://github.com/jez500/pricebuddy
|
||||
|
||||
APP="PriceBuddy"
|
||||
var_tags="${var_tags:-shopping;price-tracker}"
|
||||
var_cpu="${var_cpu:-2}"
|
||||
var_ram="${var_ram:-3072}"
|
||||
var_disk="${var_disk:-10}"
|
||||
var_os="${var_os:-debian}"
|
||||
var_version="${var_version:-13}"
|
||||
var_arm64="${var_arm64:-no}" # the bundled scraper runs Google Chrome, which is amd64-only
|
||||
var_unprivileged="${var_unprivileged:-1}"
|
||||
|
||||
header_info "$APP"
|
||||
variables
|
||||
color
|
||||
catch_errors
|
||||
|
||||
function update_script() {
|
||||
header_info
|
||||
check_container_storage
|
||||
check_container_resources
|
||||
|
||||
if [[ ! -d /opt/pricebuddy ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
|
||||
if check_for_gh_release "pricebuddy" "jez500/pricebuddy"; then
|
||||
msg_info "Stopping PriceBuddy Worker"
|
||||
systemctl stop pricebuddy-worker
|
||||
msg_ok "Stopped PriceBuddy Worker"
|
||||
|
||||
setup_composer
|
||||
NODE_VERSION="22" setup_nodejs
|
||||
|
||||
create_backup /opt/pricebuddy/.env /opt/pricebuddy/storage
|
||||
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "pricebuddy" "jez500/pricebuddy" "tarball"
|
||||
|
||||
restore_backup
|
||||
|
||||
msg_info "Updating PriceBuddy"
|
||||
cd /opt/pricebuddy
|
||||
sed -i "s/^APP_VERSION=.*/APP_VERSION=$(cat ~/.pricebuddy)/" .env
|
||||
$STD composer install --no-dev --optimize-autoloader --no-interaction
|
||||
$STD npm install
|
||||
$STD npm run build
|
||||
$STD php artisan storage:link
|
||||
$STD php artisan migrate --force
|
||||
$STD php artisan optimize
|
||||
$STD php artisan icons:cache
|
||||
$STD php artisan buddy:regenerate-price-cache
|
||||
chown -R www-data:www-data /opt/pricebuddy
|
||||
msg_ok "Updated PriceBuddy"
|
||||
|
||||
msg_info "Starting PriceBuddy Worker"
|
||||
systemctl start pricebuddy-worker
|
||||
msg_ok "Started PriceBuddy Worker"
|
||||
msg_ok "Updated successfully!"
|
||||
fi
|
||||
|
||||
if check_for_gh_release "seleniumbase-scrapper" "jez500/seleniumbase-scrapper"; then
|
||||
msg_info "Stopping SeleniumBase Scrapper"
|
||||
systemctl stop seleniumbase-scrapper
|
||||
msg_ok "Stopped SeleniumBase Scrapper"
|
||||
|
||||
msg_info "Updating Google Chrome"
|
||||
apt_update_safe
|
||||
upgrade_packages_with_retry google-chrome-stable
|
||||
msg_ok "Updated Google Chrome"
|
||||
|
||||
PYTHON_VERSION="3.12" setup_uv
|
||||
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "seleniumbase-scrapper" "jez500/seleniumbase-scrapper" "tarball"
|
||||
|
||||
msg_info "Updating SeleniumBase Scrapper"
|
||||
$STD uv venv --python 3.12 /opt/seleniumbase-scrapper/.venv
|
||||
$STD uv pip install --python /opt/seleniumbase-scrapper/.venv/bin/python \
|
||||
"seleniumbase==$(sed -n 's/^ARG SELENIUMBASE_VERSION=v//p' /opt/seleniumbase-scrapper/Dockerfile)" \
|
||||
flask \
|
||||
beautifulsoup4
|
||||
$STD /opt/seleniumbase-scrapper/.venv/bin/seleniumbase get chromedriver
|
||||
msg_ok "Updated SeleniumBase Scrapper"
|
||||
|
||||
msg_info "Starting SeleniumBase Scrapper"
|
||||
systemctl start seleniumbase-scrapper
|
||||
msg_ok "Started SeleniumBase Scrapper"
|
||||
fi
|
||||
exit
|
||||
}
|
||||
|
||||
start
|
||||
build_container
|
||||
description
|
||||
|
||||
msg_ok "Completed Successfully!\n"
|
||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||
echo -e "${INFO}${YW}Access it using the following URL:${CL}"
|
||||
echo -e "${GATEWAY}${BGN}http://${IP}${CL}"
|
||||
echo -e "${INFO}${YW}Log in as admin@example.com - the password is APP_USER_PASSWORD in /opt/pricebuddy/.env${CL}"
|
||||
@@ -30,6 +30,7 @@ function update_script() {
|
||||
exit
|
||||
fi
|
||||
|
||||
JAVA_VERSION="25" setup_java
|
||||
if check_for_gh_release "thingsboard" "thingsboard/thingsboard"; then
|
||||
msg_info "Stopping Service"
|
||||
systemctl stop thingsboard
|
||||
|
||||
@@ -3,7 +3,7 @@ _cs_boot="${COMMUNITY_SCRIPTS_CORE_DIR:-$(dirname "${BASH_SOURCE[0]}")/../../cor
|
||||
source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/build.func")
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: Joost van den Berg (montagneId)
|
||||
# License: MIT | https://github.com/montagneid/ProxmoxVED/raw/main/LICENSE
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://github.com/umbraco/Umbraco-CMS
|
||||
|
||||
APP="Umbraco"
|
||||
|
||||
@@ -148,6 +148,23 @@ EOF
|
||||
msg_ok "Migrated wanderer services"
|
||||
fi
|
||||
|
||||
if ! grep -q '^POCKETBASE_PROXY_SECRET=' /opt/wanderer/.env; then
|
||||
msg_info "Adding POCKETBASE_PROXY_SECRET"
|
||||
echo "POCKETBASE_PROXY_SECRET=$(openssl rand -hex 32)" >>/opt/wanderer/.env
|
||||
systemctl restart wanderer-web
|
||||
msg_ok "Added POCKETBASE_PROXY_SECRET"
|
||||
fi
|
||||
|
||||
if [[ -f /opt/wanderer_data/plugins/plugin.json ]]; then
|
||||
msg_info "Reinstalling wanderer plugins, one directory each"
|
||||
find /opt/wanderer_data/plugins -maxdepth 1 -type f -delete
|
||||
for plugin in hammerhead komoot strava; do
|
||||
rm -f ~/.wanderer-plugin-${plugin}
|
||||
fetch_and_deploy_gh_release "wanderer-plugin-${plugin}" "open-wanderer/wanderer" "prebuild" "latest" "/opt/wanderer_data/plugins/${plugin}" "wanderer-plugin-${plugin}.tar.gz" || msg_warn "Failed to install wanderer plugin: ${plugin}"
|
||||
done
|
||||
msg_ok "Reinstalled wanderer plugins"
|
||||
fi
|
||||
|
||||
if check_for_gh_release "wanderer" "open-wanderer/wanderer"; then
|
||||
msg_info "Stopping service"
|
||||
systemctl stop wanderer-web
|
||||
@@ -170,7 +187,7 @@ EOF
|
||||
[[ -e /opt/wanderer/db/data/plugins ]] || ln -sfn /opt/wanderer_data/plugins /opt/wanderer/db/data/plugins
|
||||
msg_info "Installing wanderer plugins"
|
||||
for plugin in hammerhead komoot strava; do
|
||||
fetch_and_deploy_gh_release "wanderer-plugin-${plugin}" "open-wanderer/wanderer" "prebuild" "${CHECK_UPDATE_RELEASE:-latest}" "/opt/wanderer_data/plugins" "wanderer-plugin-${plugin}.tar.gz" || msg_warn "Failed to install wanderer plugin: ${plugin}"
|
||||
fetch_and_deploy_gh_release "wanderer-plugin-${plugin}" "open-wanderer/wanderer" "prebuild" "${CHECK_UPDATE_RELEASE:-latest}" "/opt/wanderer_data/plugins/${plugin}" "wanderer-plugin-${plugin}.tar.gz" || msg_warn "Failed to install wanderer plugin: ${plugin}"
|
||||
done
|
||||
msg_ok "Installed wanderer plugins"
|
||||
msg_ok "Updated wanderer"
|
||||
|
||||
@@ -31,6 +31,20 @@ function update_script() {
|
||||
exit
|
||||
fi
|
||||
|
||||
if ! grep -q "@private" /etc/caddy/Caddyfile; then
|
||||
msg_info "Blocking direct access to webtrees data"
|
||||
cp /etc/caddy/Caddyfile /etc/caddy/Caddyfile.bak
|
||||
sed -i '\|root \* /opt/webtrees|a\ @private path /app/* /data/* /modules_v4/* /resources/* /vendor/* /.*\n respond @private 403' /etc/caddy/Caddyfile
|
||||
if grep -q "@private" /etc/caddy/Caddyfile && caddy validate --config /etc/caddy/Caddyfile &>/dev/null; then
|
||||
rm -f /etc/caddy/Caddyfile.bak
|
||||
systemctl reload-or-restart caddy
|
||||
msg_ok "Blocked direct access to webtrees data"
|
||||
else
|
||||
mv /etc/caddy/Caddyfile.bak /etc/caddy/Caddyfile
|
||||
msg_warn "Could not patch /etc/caddy/Caddyfile - deny /data/ there by hand"
|
||||
fi
|
||||
fi
|
||||
|
||||
if check_for_gh_release "webtrees" "fisharebest/webtrees"; then
|
||||
msg_info "Stopping Service"
|
||||
PHP_VER=$(php -r 'echo PHP_MAJOR_VERSION . "." . PHP_MINOR_VERSION;')
|
||||
|
||||
@@ -30,7 +30,7 @@ function update_script() {
|
||||
exit
|
||||
fi
|
||||
|
||||
NODE_VERSION="24" NODE_MODULE="yarn,node-gyp" setup_nodejs
|
||||
NODE_VERSION="26" NODE_MODULE="yarn,node-gyp" setup_nodejs
|
||||
|
||||
if check_for_gh_release "wikijs" "requarks/wiki"; then
|
||||
msg_info "Verifying whether ${APP}' new release is v3.x+ and current install uses SQLite."
|
||||
|
||||
@@ -203,7 +203,6 @@ server {
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto \$scheme;
|
||||
proxy_set_header X-Accel-Mapping /opt/discourse/public/=/downloads/;
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
@@ -13,6 +13,7 @@ setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
|
||||
RELEASE="v3.2.4"
|
||||
if lscpu | grep -q 'GenuineIntel'; then
|
||||
echo ""
|
||||
echo ""
|
||||
@@ -33,11 +34,11 @@ if lscpu | grep -q 'GenuineIntel'; then
|
||||
msg_info "Installing Intel OpenVINO dependencies"
|
||||
tmp_dir=$(mktemp -d)
|
||||
$STD pushd "$tmp_dir"
|
||||
curl_with_retry "https://raw.githubusercontent.com/immich-app/immich/refs/heads/main/machine-learning/Dockerfile" "Dockerfile"
|
||||
readarray -t INTEL_URLS < <(
|
||||
sed -n "/intel-[igc|opencl]/p" ./Dockerfile | awk '{print $3}'
|
||||
sed -n "/libigdgmm12/p" ./Dockerfile | awk '{print $3}'
|
||||
)
|
||||
INTEL_SRC="https://raw.githubusercontent.com/immich-app/immich/${RELEASE}/machine-learning"
|
||||
curl -fsSL "${INTEL_SRC}/scripts/install-intel-runtime.sh" -o ./intel-runtime 2>/dev/null ||
|
||||
curl_with_retry "${INTEL_SRC}/Dockerfile" "./intel-runtime"
|
||||
readarray -t INTEL_URLS < <(grep -oE 'https://github\.com/intel/[^[:space:]]+\.deb' ./intel-runtime)
|
||||
rm -f ./intel-runtime
|
||||
for url in "${INTEL_URLS[@]}"; do
|
||||
curl_with_retry "$url" "$(basename "$url")"
|
||||
done
|
||||
@@ -353,7 +354,7 @@ ML_DIR="${APP_DIR}/machine-learning"
|
||||
GEO_DIR="${INSTALL_DIR}/geodata"
|
||||
mkdir -p {"${APP_DIR}","${UPLOAD_DIR}","${GEO_DIR}","${INSTALL_DIR}"/cache}
|
||||
|
||||
fetch_and_deploy_gh_release "Immich" "immich-app/immich" "tarball" "v3.2.4" "$SRC_DIR"
|
||||
fetch_and_deploy_gh_release "Immich" "immich-app/immich" "tarball" "${RELEASE}" "$SRC_DIR"
|
||||
PNPM_VERSION="$(jq -r '.packageManager | split("@")[1] | split("+")[0]' ${SRC_DIR}/package.json)"
|
||||
export COREPACK_ENABLE_DOWNLOAD_PROMPT=0
|
||||
NODE_VERSION="24" NODE_MODULE="corepack" setup_nodejs
|
||||
|
||||
@@ -13,7 +13,7 @@ setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
|
||||
NODE_VERSION="22" NODE_MODULE="yarn" setup_nodejs
|
||||
NODE_VERSION="24" NODE_MODULE="yarn" setup_nodejs
|
||||
fetch_and_deploy_gh_release "jotty" "fccview/jotty" "prebuild" "latest" "/opt/jotty" "jotty_*_prebuild.tar.gz"
|
||||
|
||||
msg_info "Setup jotty"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: (AminGholizad)
|
||||
# License: MIT | https://github.com/AminGholizad/ProxmoxVED/raw/main/LICENSE
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://github.com/PanSalut/Koffan
|
||||
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
|
||||
168
install/pricebuddy-install.sh
Normal file
168
install/pricebuddy-install.sh
Normal file
@@ -0,0 +1,168 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: MickLesk (CanbiZ)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://github.com/jez500/pricebuddy
|
||||
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
color
|
||||
verb_ip6
|
||||
catch_errors
|
||||
setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
|
||||
msg_info "Installing Dependencies"
|
||||
$STD apt install -y \
|
||||
nginx \
|
||||
cron \
|
||||
xvfb
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
PHP_VERSION="8.4" PHP_FPM="YES" PHP_MEMORY_LIMIT="2048M" setup_php
|
||||
setup_composer
|
||||
NODE_VERSION="22" setup_nodejs
|
||||
setup_mariadb
|
||||
MARIADB_DB_NAME="pricebuddy" MARIADB_DB_USER="pricebuddy" setup_mariadb_db
|
||||
PYTHON_VERSION="3.12" setup_uv
|
||||
|
||||
msg_info "Installing Google Chrome"
|
||||
setup_deb822_repo \
|
||||
"google-chrome" \
|
||||
"https://dl.google.com/linux/linux_signing_key.pub" \
|
||||
"https://dl.google.com/linux/chrome/deb/" \
|
||||
"stable"
|
||||
$STD apt install -y google-chrome-stable
|
||||
# the package adds its own .list for the same repo, which apt rejects next to the deb822 source
|
||||
rm -f /etc/apt/sources.list.d/google-chrome.list
|
||||
msg_ok "Installed Google Chrome"
|
||||
|
||||
fetch_and_deploy_gh_release "seleniumbase-scrapper" "jez500/seleniumbase-scrapper" "tarball"
|
||||
|
||||
msg_info "Setting up SeleniumBase Scrapper"
|
||||
$STD uv venv --python 3.12 /opt/seleniumbase-scrapper/.venv
|
||||
# the SeleniumBase release upstream builds and tests its image against
|
||||
$STD uv pip install --python /opt/seleniumbase-scrapper/.venv/bin/python \
|
||||
"seleniumbase==$(sed -n 's/^ARG SELENIUMBASE_VERSION=v//p' /opt/seleniumbase-scrapper/Dockerfile)" \
|
||||
flask \
|
||||
beautifulsoup4
|
||||
$STD /opt/seleniumbase-scrapper/.venv/bin/seleniumbase get chromedriver
|
||||
msg_ok "Set up SeleniumBase Scrapper"
|
||||
|
||||
fetch_and_deploy_gh_release "pricebuddy" "jez500/pricebuddy" "tarball"
|
||||
|
||||
msg_info "Setting up PriceBuddy"
|
||||
cd /opt/pricebuddy
|
||||
cat <<EOF >/opt/pricebuddy/.env
|
||||
APP_NAME=PriceBuddy
|
||||
APP_ENV=production
|
||||
APP_KEY=base64:$(openssl rand -base64 32)
|
||||
APP_DEBUG=false
|
||||
APP_URL=http://${LOCAL_IP}
|
||||
APP_VERSION=$(cat ~/.pricebuddy)
|
||||
|
||||
DB_CONNECTION=mariadb
|
||||
DB_HOST=127.0.0.1
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=pricebuddy
|
||||
DB_USERNAME=pricebuddy
|
||||
DB_PASSWORD=${MARIADB_DB_PASS}
|
||||
|
||||
SCRAPER_BASE_URL=http://127.0.0.1:3000
|
||||
|
||||
APP_USER_EMAIL=admin@example.com
|
||||
APP_USER_PASSWORD=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c16)
|
||||
EOF
|
||||
$STD composer install --no-dev --optimize-autoloader --no-interaction
|
||||
$STD npm install
|
||||
$STD npm run build
|
||||
$STD php artisan storage:link
|
||||
# reads APP_USER_* for the admin via env(), so it has to run before optimize caches the config
|
||||
$STD php artisan buddy:init-db
|
||||
$STD php artisan optimize
|
||||
$STD php artisan icons:cache
|
||||
chown -R www-data:www-data /opt/pricebuddy
|
||||
chmod 600 /opt/pricebuddy/.env
|
||||
msg_ok "Set up PriceBuddy"
|
||||
|
||||
msg_info "Configuring Nginx"
|
||||
PHP_SOCK=$(get_php_fpm_socket)
|
||||
cat <<EOF >/etc/nginx/sites-available/pricebuddy
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
root /opt/pricebuddy/public;
|
||||
|
||||
index index.php;
|
||||
charset utf-8;
|
||||
|
||||
location / {
|
||||
try_files \$uri \$uri/ /index.php?\$query_string;
|
||||
}
|
||||
|
||||
location = /favicon.ico { access_log off; log_not_found off; }
|
||||
location = /robots.txt { access_log off; log_not_found off; }
|
||||
|
||||
error_page 404 /index.php;
|
||||
|
||||
location ~ \.php\$ {
|
||||
fastcgi_pass unix:${PHP_SOCK};
|
||||
fastcgi_param SCRIPT_FILENAME \$realpath_root\$fastcgi_script_name;
|
||||
include fastcgi_params;
|
||||
fastcgi_read_timeout 300;
|
||||
}
|
||||
|
||||
location ~ /\.(?!well-known).* {
|
||||
deny all;
|
||||
}
|
||||
}
|
||||
EOF
|
||||
nginx_enable_site "pricebuddy"
|
||||
msg_ok "Configured Nginx"
|
||||
|
||||
msg_info "Creating Services"
|
||||
cat <<EOF >/etc/systemd/system/seleniumbase-scrapper.service
|
||||
[Unit]
|
||||
Description=SeleniumBase Scrapper for PriceBuddy
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=/opt/seleniumbase-scrapper/api
|
||||
Environment=API_HOST=127.0.0.1
|
||||
Environment=API_PORT=3000
|
||||
ExecStart=/opt/seleniumbase-scrapper/.venv/bin/python /opt/seleniumbase-scrapper/api/server.py
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
cat <<EOF >/etc/systemd/system/pricebuddy-worker.service
|
||||
[Unit]
|
||||
Description=PriceBuddy Queue Worker
|
||||
After=network.target mariadb.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=www-data
|
||||
Group=www-data
|
||||
WorkingDirectory=/opt/pricebuddy
|
||||
ExecStart=/usr/bin/php /opt/pricebuddy/artisan queue:work
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
cat <<EOF >/etc/cron.d/pricebuddy
|
||||
* * * * * www-data cd /opt/pricebuddy && php artisan schedule:run >/dev/null 2>&1
|
||||
EOF
|
||||
systemctl enable -q --now seleniumbase-scrapper pricebuddy-worker
|
||||
msg_ok "Created Services"
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
@@ -20,7 +20,7 @@ $STD apt install -y \
|
||||
fonts-dejavu-core
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
JAVA_VERSION="17" setup_java
|
||||
JAVA_VERSION="25" setup_java
|
||||
PG_VERSION="16" setup_postgresql
|
||||
PG_DB_NAME="thingsboard_db" PG_DB_USER="thingsboard" setup_postgresql_db
|
||||
fetch_and_deploy_gh_release "thingsboard" "thingsboard/thingsboard" "binary" "latest" "/tmp" "thingsboard-*.deb"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: Joost van den Berg (montagneId)
|
||||
# License: MIT | https://github.com/montagneid/ProxmoxVED/raw/main/LICENSE
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://github.com/umbraco/Umbraco-CMS
|
||||
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
|
||||
@@ -33,7 +33,7 @@ msg_ok "Installed wanderer"
|
||||
|
||||
msg_info "Installing wanderer plugins"
|
||||
for plugin in hammerhead komoot strava; do
|
||||
fetch_and_deploy_gh_release "wanderer-plugin-${plugin}" "open-wanderer/wanderer" "prebuild" "latest" "/opt/wanderer_data/plugins" "wanderer-plugin-${plugin}.tar.gz" || msg_warn "Failed to install wanderer plugin: ${plugin}"
|
||||
fetch_and_deploy_gh_release "wanderer-plugin-${plugin}" "open-wanderer/wanderer" "prebuild" "latest" "/opt/wanderer_data/plugins/${plugin}" "wanderer-plugin-${plugin}.tar.gz" || msg_warn "Failed to install wanderer plugin: ${plugin}"
|
||||
done
|
||||
msg_ok "Installed wanderer plugins"
|
||||
|
||||
@@ -49,6 +49,7 @@ PB_URL=${LOCAL_IP}:8090
|
||||
PUBLIC_POCKETBASE_URL=http://${LOCAL_IP}:8090
|
||||
PUBLIC_VALHALLA_URL=https://valhalla1.openstreetmap.de
|
||||
POCKETBASE_ENCRYPTION_KEY=${POCKETBASE_KEY}
|
||||
POCKETBASE_PROXY_SECRET=$(openssl rand -hex 32)
|
||||
PB_DB_LOCATION=/opt/wanderer_data/pb_data
|
||||
MEILI_DB_PATH=/opt/wanderer_data/meili_data
|
||||
EOF
|
||||
|
||||
@@ -36,6 +36,9 @@ PHP_SOCK=$(get_php_fpm_socket)
|
||||
cat <<EOF >/etc/caddy/Caddyfile
|
||||
:80 {
|
||||
root * /opt/webtrees
|
||||
# Caddy ignores data/.htaccess; media must go through webtrees so its privacy rules apply.
|
||||
@private path /app/* /data/* /modules_v4/* /resources/* /vendor/* /.*
|
||||
respond @private 403
|
||||
php_fastcgi unix/${PHP_SOCK}
|
||||
file_server
|
||||
encode gzip
|
||||
|
||||
@@ -17,7 +17,7 @@ msg_info "Installing Dependencies"
|
||||
$STD apt install -y git
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
NODE_VERSION="24" NODE_MODULE="yarn,node-gyp" setup_nodejs
|
||||
NODE_VERSION="26" NODE_MODULE="yarn,node-gyp" setup_nodejs
|
||||
PG_VERSION="17" setup_postgresql
|
||||
PG_DB_NAME="wiki" PG_DB_USER="wikijs_user" PG_DB_EXTENSIONS="pg_trgm" setup_postgresql_db
|
||||
fetch_and_deploy_gh_release "wikijs" "requarks/wiki" "prebuild" "latest" "/opt/wikijs" "wiki-js.tar.gz"
|
||||
|
||||
@@ -110,8 +110,9 @@ while true; do
|
||||
pct start "$instance" >/dev/null 2>&1
|
||||
continue
|
||||
fi
|
||||
# Not every container names its interface eth0.
|
||||
IP=$(pct exec "$instance" -- ip -4 -o addr show scope global 2>/dev/null | awk '{print $4}' | cut -d/ -f1 | head -n1)
|
||||
# Read the IP from the host side; pct exec depends on tools inside the
|
||||
# guest, which minimal/OCI images may lack.
|
||||
IP=$(lxc-info -n "$instance" -iH 2>/dev/null | awk '/^[0-9.]+$/ && !/^(127|169\.254)\./ {print; exit}')
|
||||
if [ -z "$IP" ] || ! ping -c 1 -W 2 "$IP" >/dev/null 2>&1; then
|
||||
echo "$(date): CT $instance is not responding, restarting..."
|
||||
pct stop "$instance" >/dev/null 2>&1
|
||||
|
||||
@@ -1,218 +1,42 @@
|
||||
#!/usr/bin/env bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: MickLesk (CanbiZ)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
|
||||
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"
|
||||
___ __ __ _ _ ____ ___
|
||||
/ | __________/ /_ / / (_)___ __ ___ __ | | / / |/ /
|
||||
/ /| | / ___/ ___/ __ \ / / / / __ \/ / / / |/_/ | | / / /|_/ /
|
||||
/ ___ |/ / / /__/ / / / / /___/ / / / / /_/ /> < | |/ / / / /
|
||||
/_/ |_/_/ \___/_/ /_/ /_____/_/_/ /_/\__,_/_/|_| |___/_/ /_/
|
||||
|
||||
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="Arch Linux"
|
||||
APP_TYPE="vm"
|
||||
NSAPP="archlinux-vm"
|
||||
var_os="arch-linux"
|
||||
var_version="n.d."
|
||||
|
||||
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")
|
||||
|
||||
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}"
|
||||
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}"
|
||||
DEFAULT="${TAB}⚙️${TAB}${CL}"
|
||||
MACADDRESS="${TAB}🔗${TAB}${CL}"
|
||||
VLANTAG="${TAB}🏷️${TAB}${CL}"
|
||||
CREATING="${TAB}🚀${TAB}${CL}"
|
||||
ADVANCED="${TAB}🧩${TAB}${CL}"
|
||||
CLOUD="${TAB}☁️${TAB}${CL}"
|
||||
|
||||
THIN="discard=on,ssd=1,"
|
||||
|
||||
header_info
|
||||
echo -e "\n Loading..."
|
||||
set -e
|
||||
trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
|
||||
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" "${exit_code}"
|
||||
echo -e "\n$error_message\n"
|
||||
cleanup_vmid
|
||||
}
|
||||
|
||||
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() {
|
||||
local exit_code=$?
|
||||
popd >/dev/null
|
||||
if [[ "${POST_TO_API_DONE:-}" == "true" && "${POST_UPDATE_DONE:-}" != "true" ]]; then
|
||||
if [[ $exit_code -eq 0 ]]; then
|
||||
post_update_to_api "done" "none"
|
||||
else
|
||||
post_update_to_api "failed" "$exit_code"
|
||||
fi
|
||||
fi
|
||||
rm -rf $TEMP_DIR
|
||||
}
|
||||
vm_require_arch amd64
|
||||
|
||||
TEMP_DIR=$(mktemp -d)
|
||||
pushd $TEMP_DIR >/dev/null
|
||||
if whiptail --backtitle "Proxmox VE Helper Scripts" --title "Arch Linux VM" --yesno "This will create a New Arch Linux 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
|
||||
}
|
||||
|
||||
# This function checks the version of Proxmox Virtual Environment (PVE) and exits if the version is not supported.
|
||||
# Supported: Proxmox VE 8.0.x – 8.9.x, 9.0 and 9.2
|
||||
pve_check() {
|
||||
local PVE_VER
|
||||
PVE_VER="$(pveversion | awk -F'/' '{print $2}' | awk -F'-' '{print $1}')"
|
||||
|
||||
# Check for Proxmox VE 8.x: allow 8.0–8.9
|
||||
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
|
||||
|
||||
# Check for Proxmox VE 9.x: allow 9.0 and 9.2
|
||||
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 supported."
|
||||
msg_error "Supported: Proxmox VE version 9.0 – 9.2"
|
||||
exit 105
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
|
||||
# All other unsupported versions
|
||||
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() {
|
||||
vm_apply_machine_type "i440fx"
|
||||
VMID=$(get_valid_nextid)
|
||||
MACHINE=""
|
||||
DISK_SIZE="4G"
|
||||
DISK_SIZE="10G"
|
||||
DISK_CACHE=""
|
||||
HN="arch-linux"
|
||||
CPU_TYPE=""
|
||||
@@ -224,219 +48,28 @@ function default_settings() {
|
||||
MTU=""
|
||||
START_VM="yes"
|
||||
METHOD="default"
|
||||
echo -e "${CONTAINERID}${BOLD}${DGN}Virtual Machine ID: ${BGN}${VMID}${CL}"
|
||||
echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}i440fx${CL}"
|
||||
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE}${CL}"
|
||||
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Cache: ${BGN}None${CL}"
|
||||
echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}${HN}${CL}"
|
||||
echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}KVM64${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 Arch Linux VM using the above default settings${CL}"
|
||||
vm_echo_default_settings
|
||||
}
|
||||
|
||||
function advanced_settings() {
|
||||
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 "i440fx"
|
||||
vm_prompt_disk_size "10G"
|
||||
vm_prompt_disk_cache "none"
|
||||
vm_prompt_hostname "arch-linux"
|
||||
vm_prompt_cpu_model "kvm64"
|
||||
vm_prompt_cpu_cores "1"
|
||||
vm_prompt_ram "1024"
|
||||
vm_prompt_bridge "vmbr0"
|
||||
vm_prompt_mac "$GEN_MAC"
|
||||
vm_prompt_vlan
|
||||
vm_prompt_mtu
|
||||
|
||||
if MACH=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "MACHINE TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \
|
||||
"i440fx" "Machine i440fx" ON \
|
||||
"q35" "Machine q35" OFF \
|
||||
3>&1 1>&2 2>&3); then
|
||||
if [ "$MACH" = q35 ]; then
|
||||
echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}$MACH${CL}"
|
||||
MACHINE=" -machine q35"
|
||||
else
|
||||
echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}$MACH${CL}"
|
||||
MACHINE=""
|
||||
fi
|
||||
else
|
||||
exit-script
|
||||
fi
|
||||
vm_prompt_verbose "no"
|
||||
vm_prompt_start_vm "yes"
|
||||
|
||||
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
|
||||
DISK_SIZE="${DISK_SIZE}G"
|
||||
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}$DISK_SIZE${CL}"
|
||||
elif [[ "$DISK_SIZE" =~ ^[0-9]+G$ ]]; 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 or 10G).${CL}"
|
||||
exit-script
|
||||
fi
|
||||
else
|
||||
exit-script
|
||||
fi
|
||||
|
||||
if DISK_CACHE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "DISK CACHE" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \
|
||||
"0" "None (Default)" ON \
|
||||
"1" "Write Through" OFF \
|
||||
3>&1 1>&2 2>&3); then
|
||||
if [ "$DISK_CACHE" = "1" ]; then
|
||||
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Cache: ${BGN}Write Through${CL}"
|
||||
DISK_CACHE="cache=writethrough,"
|
||||
else
|
||||
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Cache: ${BGN}None${CL}"
|
||||
DISK_CACHE=""
|
||||
fi
|
||||
else
|
||||
exit-script
|
||||
fi
|
||||
|
||||
if VM_NAME=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Hostname" 8 58 arch-linux --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
||||
if [ -z "$VM_NAME" ]; then
|
||||
HN="arch-linux"
|
||||
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" --cancel-button Exit-Script 10 58 2 \
|
||||
"0" "KVM64 (Default)" ON \
|
||||
"1" "Host" OFF \
|
||||
3>&1 1>&2 2>&3); then
|
||||
if [ "$CPU_TYPE1" = "1" ]; then
|
||||
echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}Host${CL}"
|
||||
CPU_TYPE=" -cpu host"
|
||||
else
|
||||
echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}KVM64${CL}"
|
||||
CPU_TYPE=""
|
||||
fi
|
||||
else
|
||||
exit-script
|
||||
fi
|
||||
|
||||
while true; do
|
||||
if CORE_COUNT=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate CPU Cores" 8 58 2 --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 2048 --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
||||
if [ -z "$RAM_SIZE" ]; then RAM_SIZE="2048"; 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., 2048)." 8 58
|
||||
else
|
||||
exit-script
|
||||
fi
|
||||
done
|
||||
|
||||
if BRG=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Bridge" 8 58 vmbr0 --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" --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
|
||||
|
||||
if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create a Arch Linux VM?" --no-button Do-Over 10 58); then
|
||||
if vm_confirm_advanced_settings "Ready to create a Arch Linux VM?"; then
|
||||
echo -e "${CREATING}${BOLD}${DGN}Creating a Arch Linux VM using the above advanced settings${CL}"
|
||||
else
|
||||
header_info
|
||||
@@ -445,154 +78,54 @@ 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?\n\nDefaults:\n• 1 CPU Core\n• 1 GB RAM\n• 10 GB Disk" 13 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
|
||||
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"
|
||||
msg_info "Retrieving the URL for the Arch Linux .iso File"
|
||||
URL=https://geo.mirror.pkgbuild.com/iso/latest/archlinux-x86_64.iso
|
||||
FILENAME="archlinux-x86_64.iso"
|
||||
vm_select_iso_storage "$FILENAME" "$HN"
|
||||
CACHE_FILE="$ISO_PATH"
|
||||
sleep 2
|
||||
msg_ok "${CL}${BL}${URL}${CL}"
|
||||
curl -f#SL -o "$(basename "$URL")" "$URL"
|
||||
echo -en "\e[1A\e[0K"
|
||||
FILE=$(basename $URL)
|
||||
msg_ok "Downloaded ${CL}${BL}${FILE}${CL}"
|
||||
|
||||
STORAGE_TYPE=$(pvesm status -storage "$STORAGE" | awk 'NR>1 {print $2}')
|
||||
case $STORAGE_TYPE in
|
||||
nfs | dir | cifs)
|
||||
DISK_EXT=".qcow2"
|
||||
DISK_REF="$VMID/"
|
||||
DISK_IMPORT="--format qcow2"
|
||||
THIN=""
|
||||
;;
|
||||
btrfs)
|
||||
DISK_EXT=".raw"
|
||||
DISK_REF="$VMID/"
|
||||
DISK_IMPORT="--format raw"
|
||||
THIN=""
|
||||
;;
|
||||
*)
|
||||
DISK_EXT=""
|
||||
DISK_REF=""
|
||||
DISK_IMPORT="--format raw"
|
||||
;;
|
||||
esac
|
||||
vm_fetch_image "$URL" "$CACHE_FILE" --cache --min-bytes $((100 * 1024 * 1024)) || exit 115
|
||||
|
||||
msg_info "Creating a Arch Linux VM"
|
||||
qm create $VMID -agent 1${MACHINE} -tablet 0 -localtime 1 -bios ovmf${CPU_TYPE} -cores $CORE_COUNT -memory $RAM_SIZE \
|
||||
-name $HN -tags community-script -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU -onboot 1 -ostype l26 -scsihw virtio-scsi-pci
|
||||
|
||||
if qm disk import --help >/dev/null 2>&1; then
|
||||
IMPORT_CMD=(qm disk import)
|
||||
else
|
||||
IMPORT_CMD=(qm importdisk)
|
||||
fi
|
||||
|
||||
IMPORT_OUT="$("${IMPORT_CMD[@]}" "$VMID" "${FILE}" "$STORAGE" ${DISK_IMPORT:-} 2>&1 || true)"
|
||||
DISK_REF_IMPORTED="$(printf '%s\n' "$IMPORT_OUT" | sed -n "s/.*successfully imported disk '\([^']\+\)'.*/\1/p" | tr -d "\r\"'")"
|
||||
[[ -z "$DISK_REF_IMPORTED" ]] && DISK_REF_IMPORTED="$(pvesm list "$STORAGE" | awk -v id="$VMID" '$5 ~ ("vm-"id"-disk-") {print $1":"$5}' | sort | tail -n1)"
|
||||
[[ -z "$DISK_REF_IMPORTED" ]] && {
|
||||
msg_error "Unable to determine imported disk reference."
|
||||
echo "$IMPORT_OUT"
|
||||
exit 226
|
||||
}
|
||||
msg_ok "Imported disk (${CL}${BL}${DISK_REF_IMPORTED}${CL})"
|
||||
|
||||
# The ISO is the installer, not the system: an empty disk takes scsi0 and wins
|
||||
# the boot order as soon as something is on it.
|
||||
qm set $VMID \
|
||||
-efidisk0 ${STORAGE}:0,efitype=4m \
|
||||
-scsi0 ${DISK_REF_IMPORTED},${DISK_CACHE}${THIN%,} \
|
||||
-ide2 ${STORAGE}:cloudinit \
|
||||
-boot order=scsi0 \
|
||||
-scsi0 ${STORAGE}:${DISK_SIZE%G},${DISK_CACHE}${THIN%,} \
|
||||
-cdrom "$ISO_VOLUME" \
|
||||
-boot order='scsi0;ide2' \
|
||||
-serial0 socket >/dev/null
|
||||
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;'>Arch Linux VM</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/☕-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
|
||||
if [ -n "$DISK_SIZE" ]; then
|
||||
msg_info "Resizing disk to $DISK_SIZE GB"
|
||||
qm resize $VMID scsi0 ${DISK_SIZE} >/dev/null
|
||||
else
|
||||
msg_info "Using default disk size of $DEFAULT_DISK_SIZE GB"
|
||||
qm resize $VMID scsi0 ${DEFAULT_DISK_SIZE} >/dev/null
|
||||
fi
|
||||
set_description
|
||||
|
||||
msg_ok "Created a Arch Linux VM ${CL}${BL}(${HN})"
|
||||
if [ "$START_VM" == "yes" ]; then
|
||||
msg_info "Starting Arch Linux VM"
|
||||
qm start $VMID
|
||||
$STD qm start $VMID
|
||||
msg_ok "Started Arch Linux VM"
|
||||
fi
|
||||
post_update_to_api "done" "none"
|
||||
|
||||
echo -e "\n${INFO}${BOLD}${GN}Arch Linux VM Configuration Summary:${CL}"
|
||||
echo -e "${TAB}${DGN}VM ID: ${BGN}${VMID}${CL}"
|
||||
echo -e "${TAB}${DGN}Hostname: ${BGN}${HN}${CL}"
|
||||
echo -e "${TAB}${DGN}Disk Size: ${BGN}${DISK_SIZE}${CL}"
|
||||
|
||||
echo -e "\n${INFO}${BOLD}${YW}Next Steps:${CL}"
|
||||
echo -e "${TAB}1. Open the VM Console in Proxmox - the live ISO logs in as root by itself"
|
||||
echo -e "${TAB}2. Run ${BL}archinstall${CL}, or install by hand, onto ${BL}/dev/sda${CL}"
|
||||
echo -e "${TAB}3. Detach the ISO afterwards (${BL}qm set ${VMID} --ide2 none${CL}) -- the boot"
|
||||
echo -e "${TAB} order already prefers the disk"
|
||||
echo -e "${TAB}4. The ISO carries no Cloud-Init and no guest agent. Install"
|
||||
echo -e "${TAB} ${BL}qemu-guest-agent${CL} in the guest for Proxmox to show its IP"
|
||||
|
||||
msg_ok "Completed successfully!\n"
|
||||
|
||||
Reference in New Issue
Block a user