mirror of
https://github.com/community-scripts/ProxmoxVED.git
synced 2026-04-05 08:54:03 -04:00
Compare commits
1 Commits
87e29ad820
...
michelroeg
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5b9e55984b |
7
.gitattributes
vendored
7
.gitattributes
vendored
@@ -10,6 +10,11 @@
|
|||||||
# Treat Golang files as Go (for /api/)
|
# Treat Golang files as Go (for /api/)
|
||||||
api/**/*.go linguist-language=Go
|
api/**/*.go linguist-language=Go
|
||||||
|
|
||||||
|
# ---------------------------------------
|
||||||
|
# Treat frontend as JavaScript/TypeScript (optional)
|
||||||
|
frontend/**/*.ts linguist-language=TypeScript
|
||||||
|
frontend/**/*.js linguist-language=JavaScript
|
||||||
|
|
||||||
# ---------------------------------------
|
# ---------------------------------------
|
||||||
# Exclude documentation from stats
|
# Exclude documentation from stats
|
||||||
*.md linguist-documentation
|
*.md linguist-documentation
|
||||||
@@ -21,7 +26,7 @@ SECURITY.md linguist-documentation
|
|||||||
# ---------------------------------------
|
# ---------------------------------------
|
||||||
# Exclude generated/config files
|
# Exclude generated/config files
|
||||||
*.json linguist-generated
|
*.json linguist-generated
|
||||||
json/*.json linguist-generated=false
|
frontend/public/json/*.json linguist-generated=false
|
||||||
*.lock linguist-generated
|
*.lock linguist-generated
|
||||||
*.yml linguist-generated
|
*.yml linguist-generated
|
||||||
*.yaml linguist-generated
|
*.yaml linguist-generated
|
||||||
|
|||||||
78
.github/CONTRIBUTOR_AND_GUIDES/CONTRIBUTING.md
generated
vendored
78
.github/CONTRIBUTOR_AND_GUIDES/CONTRIBUTING.md
generated
vendored
@@ -14,7 +14,9 @@ Coding standards are crucial for several reasons:
|
|||||||
3. **Maintainability**: Code that follows a standard structure is easier to refactor and update. It ensures that changes can be made with minimal risk of introducing new bugs.
|
3. **Maintainability**: Code that follows a standard structure is easier to refactor and update. It ensures that changes can be made with minimal risk of introducing new bugs.
|
||||||
4. **Collaboration**: When everyone follows the same standards, it becomes easier to collaborate on code. It reduces friction and misunderstandings during code reviews and merges.
|
4. **Collaboration**: When everyone follows the same standards, it becomes easier to collaborate on code. It reduces friction and misunderstandings during code reviews and merges.
|
||||||
|
|
||||||
### Scope of These Docs
|
### Scope of These Documents
|
||||||
|
|
||||||
|
These documents cover the coding standards for the following types of files in our project:
|
||||||
|
|
||||||
- **`install/$AppName-install.sh` Scripts**: These scripts are responsible for the installation of applications.
|
- **`install/$AppName-install.sh` Scripts**: These scripts are responsible for the installation of applications.
|
||||||
- **`ct/$AppName.sh` Scripts**: These scripts handle the creation and updating of containers.
|
- **`ct/$AppName.sh` Scripts**: These scripts handle the creation and updating of containers.
|
||||||
@@ -29,4 +31,76 @@ Let's work together to keep our codebase clean, efficient, and maintainable!
|
|||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
Find all needed Information in our [Docs]([https://duckduckgo.com](https://community-scripts.org/docs)
|
Before contributing, please ensure that you have the following setup:
|
||||||
|
|
||||||
|
1. **Visual Studio Code** (recommended for script development)
|
||||||
|
2. **Recommended VS Code Extensions:**
|
||||||
|
- [Shell Syntax](https://marketplace.visualstudio.com/items?itemName=bmalehorn.shell-syntax)
|
||||||
|
- [ShellCheck](https://marketplace.visualstudio.com/items?itemName=timonwong.shellcheck)
|
||||||
|
- [Shell Format](https://marketplace.visualstudio.com/items?itemName=foxundermoon.shell-format)
|
||||||
|
|
||||||
|
### Important Notes
|
||||||
|
- Use [AppName.sh](https://github.com/community-scripts/ProxmoxVED/blob/main/.github/CONTRIBUTOR_AND_GUIDES/ct/AppName.sh) and [AppName-install.sh](https://github.com/community-scripts/ProxmoxVED/blob/main/.github/CONTRIBUTOR_AND_GUIDES/install/AppName-install.sh) as templates when creating new scripts.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 🚀 The Application Script (ct/AppName.sh)
|
||||||
|
|
||||||
|
- You can find all coding standards, as well as the structure for this file [here](https://github.com/community-scripts/ProxmoxVED/blob/main/.github/CONTRIBUTOR_AND_GUIDES/ct/AppName.md).
|
||||||
|
- These scripts are responsible for container creation, setting the necessary variables and handling the update of the application once installed.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 🛠 The Installation Script (install/AppName-install.sh)
|
||||||
|
|
||||||
|
- You can find all coding standards, as well as the structure for this file [here](https://github.com/community-scripts/ProxmoxVED/blob/main/.github/CONTRIBUTOR_AND_GUIDES/install/AppName-install.md).
|
||||||
|
- These scripts are responsible for the installation of the application.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Building Your Own Scripts
|
||||||
|
|
||||||
|
Start with the [template script](https://github.com/community-scripts/ProxmoxVED/blob/main/.github/CONTRIBUTOR_AND_GUIDES/install/AppName-install.sh)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🤝 Contribution Process
|
||||||
|
|
||||||
|
### 1. Fork the repository
|
||||||
|
Fork to your GitHub account
|
||||||
|
|
||||||
|
### 2. Clone your fork on your local environment
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/yourUserName/ForkName
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Create a new branch
|
||||||
|
```bash
|
||||||
|
git switch -c your-feature-branch
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Change paths in build.func install.func and AppName.sh
|
||||||
|
To be able to develop from your own branch you need to change `https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main` to `https://raw.githubusercontent.com/[USER]/[REPOSITORY]/refs/heads/[BRANCH]`. You need to make this change atleast in misc/build.func misc/install.func and in your ct/AppName.sh. This change is only for testing. Before opening a Pull Request you should change this line change all this back to point to `https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main`.
|
||||||
|
|
||||||
|
### 4. Commit changes (without build.func and install.func!)
|
||||||
|
```bash
|
||||||
|
git commit -m "Your commit message"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. Push to your fork
|
||||||
|
```bash
|
||||||
|
git push origin your-feature-branch
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6. Create a Pull Request
|
||||||
|
Open a Pull Request from your feature branch to the main repository branch. You must only include your **$AppName.sh**, **$AppName-install.sh** and **$AppName.json** files in the pull request.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📚 Pages
|
||||||
|
|
||||||
|
- [CT Template: AppName.sh](https://github.com/community-scripts/ProxmoxVED/blob/main/.github/CONTRIBUTOR_AND_GUIDES/ct/AppName.sh)
|
||||||
|
- [Install Template: AppName-install.sh](https://github.com/community-scripts/ProxmoxVED/blob/main/.github/CONTRIBUTOR_AND_GUIDES/install/AppName-install.sh)
|
||||||
|
- [JSON Template: AppName.json](https://github.com/community-scripts/ProxmoxVED/blob/main/.github/CONTRIBUTOR_AND_GUIDES/json/AppName.json)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
286
.github/CONTRIBUTOR_AND_GUIDES/ct/AppName.md
generated
vendored
Normal file
286
.github/CONTRIBUTOR_AND_GUIDES/ct/AppName.md
generated
vendored
Normal file
@@ -0,0 +1,286 @@
|
|||||||
|
# **AppName<span></span>.sh Scripts**
|
||||||
|
|
||||||
|
`AppName.sh` scripts found in the `/ct` directory. These scripts are responsible for the installation of the desired application. For this guide we take `/ct/snipeit.sh` as example.
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
|
||||||
|
- [**AppName.sh Scripts**](#appnamesh-scripts)
|
||||||
|
- [Table of Contents](#table-of-contents)
|
||||||
|
- [1. **File Header**](#1-file-header)
|
||||||
|
- [1.1 **Shebang**](#11-shebang)
|
||||||
|
- [1.2 **Import Functions**](#12-import-functions)
|
||||||
|
- [1.3 **Metadata**](#13-metadata)
|
||||||
|
- [2 **Variables and function import**](#2-variables-and-function-import)
|
||||||
|
- [2.1 **Default Values**](#21-default-values)
|
||||||
|
- [2.2 **📋 App output \& base settings**](#22--app-output--base-settings)
|
||||||
|
- [2.3 **🛠 Core functions**](#23--core-functions)
|
||||||
|
- [3 **Update function**](#3-update-function)
|
||||||
|
- [3.1 **Function Header**](#31-function-header)
|
||||||
|
- [3.2 **Check APP**](#32-check-app)
|
||||||
|
- [3.3 **Check version**](#33-check-version)
|
||||||
|
- [3.4 **Verbosity**](#34-verbosity)
|
||||||
|
- [3.5 **Backups**](#35-backups)
|
||||||
|
- [3.6 **Cleanup**](#36-cleanup)
|
||||||
|
- [3.7 **No update function**](#37-no-update-function)
|
||||||
|
- [4 **End of the script**](#4-end-of-the-script)
|
||||||
|
- [5. **Contribution checklist**](#5-contribution-checklist)
|
||||||
|
|
||||||
|
## 1. **File Header**
|
||||||
|
|
||||||
|
### 1.1 **Shebang**
|
||||||
|
|
||||||
|
- Use `#!/usr/bin/env bash` as the shebang.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.2 **Import Functions**
|
||||||
|
|
||||||
|
- Import the build.func file.
|
||||||
|
- When developing your own script, change the URL to your own repository.
|
||||||
|
|
||||||
|
> [!IMPORTANT]
|
||||||
|
> You also need to change all apperances of this URL in `misc/build.func` and `misc/install.func`
|
||||||
|
|
||||||
|
Example for development:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
source <(curl -s https://raw.githubusercontent.com/[USER]/[REPO]/refs/heads/[BRANCH]/misc/build.func)
|
||||||
|
```
|
||||||
|
|
||||||
|
Final script:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
||||||
|
```
|
||||||
|
|
||||||
|
> [!CAUTION]
|
||||||
|
> Before opening a Pull Request, change the URLs to point to the community-scripts repo.
|
||||||
|
|
||||||
|
### 1.3 **Metadata**
|
||||||
|
|
||||||
|
- Add clear comments for script metadata, including author, copyright, and license information.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
|
# Author: [YourUserName]
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
||||||
|
# Source: [SOURCE_URL]
|
||||||
|
```
|
||||||
|
|
||||||
|
> [!NOTE]:
|
||||||
|
>
|
||||||
|
> - Add your username and source URL
|
||||||
|
> - For existing scripts, add "| Co-Author [YourUserName]" after the current author
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2 **Variables and function import**
|
||||||
|
>
|
||||||
|
> [!NOTE]
|
||||||
|
> You need to have all this set in your script, otherwise it will not work!
|
||||||
|
|
||||||
|
### 2.1 **Default Values**
|
||||||
|
|
||||||
|
- This section sets the default values for the container.
|
||||||
|
- `APP` needs to be set to the application name and must be equal to the filenames of your scripts.
|
||||||
|
- `var_tags`: You can set Tags for the CT wich show up in the Proxmox UI. Don´t overdo it!
|
||||||
|
|
||||||
|
>[!NOTE]
|
||||||
|
>Description for all Default Values
|
||||||
|
>
|
||||||
|
>| Variable | Description | Notes |
|
||||||
|
>|----------|-------------|-------|
|
||||||
|
>| `APP` | Application name | Must match ct\AppName.sh |
|
||||||
|
>| `var_tags` | Proxmox display tags without Spaces, only ; | Limit the number |
|
||||||
|
>| `var_cpu` | CPU cores | Number of cores |
|
||||||
|
>| `var_ram` | RAM | In MB |
|
||||||
|
>| `var_disk` | Disk capacity | In GB |
|
||||||
|
>| `var_os` | Operating system | alpine, debian, ubuntu |
|
||||||
|
>| `var_version` | OS version | e.g., 3.20, 11, 12, 20.04 |
|
||||||
|
>| `var_unprivileged` | Container type | 1 = Unprivileged, 0 = Privileged |
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
APP="SnipeIT"
|
||||||
|
var_tags="asset-management;foss"
|
||||||
|
var_cpu="2"
|
||||||
|
var_ram="2048"
|
||||||
|
var_disk="4"
|
||||||
|
var_os="debian"
|
||||||
|
var_version="12"
|
||||||
|
var_unprivileged="1"
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2.2 **📋 App output & base settings**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
header_info "$APP"
|
||||||
|
```
|
||||||
|
- `header_info`: Generates ASCII header for APP
|
||||||
|
|
||||||
|
## 2.3 **🛠 Core functions**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
variables
|
||||||
|
color
|
||||||
|
catch_errors
|
||||||
|
```
|
||||||
|
|
||||||
|
- `variables`: Processes input and prepares variables
|
||||||
|
- `color`: Sets icons, colors, and formatting
|
||||||
|
- `catch_errors`: Enables error handling
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3 **Update function**
|
||||||
|
|
||||||
|
### 3.1 **Function Header**
|
||||||
|
|
||||||
|
- If applicable write a function that updates the application and the OS in the container.
|
||||||
|
- Each update function starts with the same code:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
function update_script() {
|
||||||
|
header_info
|
||||||
|
check_container_storage
|
||||||
|
check_container_resources
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.2 **Check APP**
|
||||||
|
|
||||||
|
- Before doing anything update-wise, check if the app is installed in the container.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
if [[ ! -d /opt/snipe-it ]]; then
|
||||||
|
msg_error "No ${APP} Installation Found!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.3 **Check version**
|
||||||
|
|
||||||
|
- Before updating, check if a new version exists.
|
||||||
|
- We use the `${APPLICATION}_version.txt` file created in `/opt` during the install to compare new versions against the currently installed version.
|
||||||
|
|
||||||
|
Example with a Github Release:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
RELEASE=$(curl -fsSL https://api.github.com/repos/snipe/snipe-it/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
|
||||||
|
if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then
|
||||||
|
msg_info "Updating ${APP} to v${RELEASE}"
|
||||||
|
#DO UPDATE
|
||||||
|
else
|
||||||
|
msg_ok "No update required. ${APP} is already at v${RELEASE}."
|
||||||
|
fi
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.4 **Verbosity**
|
||||||
|
|
||||||
|
- Use the appropriate flag (**-q** in the examples) for a command to suppress its output.
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -fsSL
|
||||||
|
unzip -q
|
||||||
|
```
|
||||||
|
|
||||||
|
- If a command does not come with this functionality use `$STD` to suppress it's output.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$STD php artisan migrate --force
|
||||||
|
$STD php artisan config:clear
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.5 **Backups**
|
||||||
|
|
||||||
|
- Backup user data if necessary.
|
||||||
|
- Move all user data back in the directory when the update is finished.
|
||||||
|
|
||||||
|
>[!NOTE]
|
||||||
|
>This is not meant to be a permanent backup
|
||||||
|
|
||||||
|
Example backup:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mv /opt/snipe-it /opt/snipe-it-backup
|
||||||
|
```
|
||||||
|
|
||||||
|
Example config restore:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cp /opt/snipe-it-backup/.env /opt/snipe-it/.env
|
||||||
|
cp -r /opt/snipe-it-backup/public/uploads/ /opt/snipe-it/public/uploads/
|
||||||
|
cp -r /opt/snipe-it-backup/storage/private_uploads /opt/snipe-it/storage/private_uploads
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.6 **Cleanup**
|
||||||
|
|
||||||
|
- Do not forget to remove any temporary files/folders such as zip-files or temporary backups.
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
rm -rf /opt/v${RELEASE}.zip
|
||||||
|
rm -rf /opt/snipe-it-backup
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.7 **No update function**
|
||||||
|
|
||||||
|
- In case you can not provide an update function use the following code to provide user feedback.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
function update_script() {
|
||||||
|
header_info
|
||||||
|
check_container_storage
|
||||||
|
check_container_resources
|
||||||
|
if [[ ! -d /opt/snipeit ]]; then
|
||||||
|
msg_error "No ${APP} Installation Found!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
msg_error "Currently we don't provide an update function for this ${APP}."
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4 **End of the script**
|
||||||
|
|
||||||
|
- `start`: Launches Whiptail dialogue
|
||||||
|
- `build_container`: Collects and integrates user settings
|
||||||
|
- `description`: Sets LXC container description
|
||||||
|
- With `echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"` you can point the user to the IP:PORT/folder needed to access the app.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
start
|
||||||
|
build_container
|
||||||
|
description
|
||||||
|
|
||||||
|
msg_ok "Completed successfully!\n"
|
||||||
|
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||||
|
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
||||||
|
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. **Contribution checklist**
|
||||||
|
|
||||||
|
- [ ] Shebang is correctly set (`#!/usr/bin/env bash`).
|
||||||
|
- [ ] Correct link to *build.func*
|
||||||
|
- [ ] Metadata (author, license) is included at the top.
|
||||||
|
- [ ] Variables follow naming conventions.
|
||||||
|
- [ ] Update function exists.
|
||||||
|
- [ ] Update functions checks if app is installed and for new version.
|
||||||
|
- [ ] Update function cleans up temporary files.
|
||||||
|
- [ ] Script ends with a helpful message for the user to reach the application.
|
||||||
86
.github/CONTRIBUTOR_AND_GUIDES/ct/AppName.sh
generated
vendored
Normal file
86
.github/CONTRIBUTOR_AND_GUIDES/ct/AppName.sh
generated
vendored
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
||||||
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
|
# Author: [YourUserName]
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
||||||
|
# Source: [SOURCE_URL]
|
||||||
|
|
||||||
|
# App Default Values
|
||||||
|
APP="[APP_NAME]"
|
||||||
|
# Name of the app (e.g. Google, Adventurelog, Apache-Guacamole"
|
||||||
|
var_tags="[TAGS]"
|
||||||
|
# Tags for Proxmox VE, maximum 2 pcs., no spaces allowed, separated by a semicolon ; (e.g. database | adblock;dhcp)
|
||||||
|
var_cpu="[CPU]"
|
||||||
|
# Number of cores (1-X) (e.g. 4) - default are 2
|
||||||
|
var_ram="[RAM]"
|
||||||
|
# Amount of used RAM in MB (e.g. 2048 or 4096)
|
||||||
|
var_disk="[DISK]"
|
||||||
|
# Amount of used disk space in GB (e.g. 4 or 10)
|
||||||
|
var_os="[OS]"
|
||||||
|
# Default OS (e.g. debian, ubuntu, alpine)
|
||||||
|
var_version="[VERSION]"
|
||||||
|
# Default OS version (e.g. 12 for debian, 24.04 for ubuntu, 3.20 for alpine)
|
||||||
|
var_unprivileged="[UNPRIVILEGED]"
|
||||||
|
# 1 = unprivileged container, 0 = privileged container
|
||||||
|
|
||||||
|
header_info "$APP"
|
||||||
|
variables
|
||||||
|
color
|
||||||
|
catch_errors
|
||||||
|
|
||||||
|
function update_script() {
|
||||||
|
header_info
|
||||||
|
check_container_storage
|
||||||
|
check_container_resources
|
||||||
|
|
||||||
|
# Check if installation is present | -f for file, -d for folder
|
||||||
|
if [[ ! -f [INSTALLATION_CHECK_PATH] ]]; then
|
||||||
|
msg_error "No ${APP} Installation Found!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Crawling the new version and checking whether an update is required
|
||||||
|
RELEASE=$(curl -fsSL [RELEASE_URL] | [PARSE_RELEASE_COMMAND])
|
||||||
|
if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then
|
||||||
|
# Stopping Services
|
||||||
|
msg_info "Stopping $APP"
|
||||||
|
systemctl stop [SERVICE_NAME]
|
||||||
|
msg_ok "Stopped $APP"
|
||||||
|
|
||||||
|
# Creating Backup
|
||||||
|
msg_info "Creating Backup"
|
||||||
|
tar -czf "/opt/${APP}_backup_$(date +%F).tar.gz" [IMPORTANT_PATHS]
|
||||||
|
msg_ok "Backup Created"
|
||||||
|
|
||||||
|
# Execute Update
|
||||||
|
msg_info "Updating $APP to v${RELEASE}"
|
||||||
|
[UPDATE_COMMANDS]
|
||||||
|
msg_ok "Updated $APP to v${RELEASE}"
|
||||||
|
|
||||||
|
# Starting Services
|
||||||
|
msg_info "Starting $APP"
|
||||||
|
systemctl start [SERVICE_NAME]
|
||||||
|
msg_ok "Started $APP"
|
||||||
|
|
||||||
|
# Cleaning up
|
||||||
|
msg_info "Cleaning Up"
|
||||||
|
rm -rf [TEMP_FILES]
|
||||||
|
msg_ok "Cleanup Completed"
|
||||||
|
|
||||||
|
# Last Action
|
||||||
|
echo "${RELEASE}" >/opt/${APP}_version.txt
|
||||||
|
msg_ok "Update Successful"
|
||||||
|
else
|
||||||
|
msg_ok "No update required. ${APP} is already at v${RELEASE}"
|
||||||
|
fi
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
start
|
||||||
|
build_container
|
||||||
|
description
|
||||||
|
|
||||||
|
msg_ok "Completed successfully!\n"
|
||||||
|
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||||
|
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
||||||
|
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:[PORT]${CL}"
|
||||||
353
.github/CONTRIBUTOR_AND_GUIDES/install/AppName-install.md
generated
vendored
Normal file
353
.github/CONTRIBUTOR_AND_GUIDES/install/AppName-install.md
generated
vendored
Normal file
@@ -0,0 +1,353 @@
|
|||||||
|
|
||||||
|
# **AppName<span></span>-install.sh Scripts**
|
||||||
|
|
||||||
|
`AppName-install.sh` scripts found in the `/install` directory. These scripts are responsible for the installation of the application. For this guide we take `/install/snipeit-install.sh` as example.
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
|
||||||
|
- [**AppName-install.sh Scripts**](#appname-installsh-scripts)
|
||||||
|
- [Table of Contents](#table-of-contents)
|
||||||
|
- [1. **File header**](#1-file-header)
|
||||||
|
- [1.1 **Shebang**](#11-shebang)
|
||||||
|
- [1.2 **Comments**](#12-comments)
|
||||||
|
- [1.3 **Variables and function import**](#13-variables-and-function-import)
|
||||||
|
- [2. **Variable naming and management**](#2-variable-naming-and-management)
|
||||||
|
- [2.1 **Naming conventions**](#21-naming-conventions)
|
||||||
|
- [3. **Dependencies**](#3-dependencies)
|
||||||
|
- [3.1 **Install all at once**](#31-install-all-at-once)
|
||||||
|
- [3.2 **Collapse dependencies**](#32-collapse-dependencies)
|
||||||
|
- [4. **Paths to application files**](#4-paths-to-application-files)
|
||||||
|
- [5. **Version management**](#5-version-management)
|
||||||
|
- [5.1 **Install the latest release**](#51-install-the-latest-release)
|
||||||
|
- [5.2 **Save the version for update checks**](#52-save-the-version-for-update-checks)
|
||||||
|
- [6. **Input and output management**](#6-input-and-output-management)
|
||||||
|
- [6.1 **User feedback**](#61-user-feedback)
|
||||||
|
- [6.2 **Verbosity**](#62-verbosity)
|
||||||
|
- [7. **String/File Manipulation**](#7-stringfile-manipulation)
|
||||||
|
- [7.1 **File Manipulation**](#71-file-manipulation)
|
||||||
|
- [8. **Security practices**](#8-security-practices)
|
||||||
|
- [8.1 **Password generation**](#81-password-generation)
|
||||||
|
- [8.2 **File permissions**](#82-file-permissions)
|
||||||
|
- [9. **Service Configuration**](#9-service-configuration)
|
||||||
|
- [9.1 **Configuration files**](#91-configuration-files)
|
||||||
|
- [9.2 **Credential management**](#92-credential-management)
|
||||||
|
- [9.3 **Enviroment files**](#93-enviroment-files)
|
||||||
|
- [9.4 **Services**](#94-services)
|
||||||
|
- [10. **Cleanup**](#10-cleanup)
|
||||||
|
- [10.1 **Remove temporary files**](#101-remove-temporary-files)
|
||||||
|
- [10.2 **Autoremove and autoclean**](#102-autoremove-and-autoclean)
|
||||||
|
- [11. **Best Practices Checklist**](#11-best-practices-checklist)
|
||||||
|
- [Example: High-Level Script Flow](#example-high-level-script-flow)
|
||||||
|
|
||||||
|
## 1. **File header**
|
||||||
|
|
||||||
|
### 1.1 **Shebang**
|
||||||
|
|
||||||
|
- Use `#!/usr/bin/env bash` as the shebang.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.2 **Comments**
|
||||||
|
|
||||||
|
- Add clear comments for script metadata, including author, copyright, and license information.
|
||||||
|
- Use meaningful inline comments to explain complex commands or logic.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
|
# Author: [YourUserName]
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
||||||
|
# Source: [SOURCE_URL]
|
||||||
|
```
|
||||||
|
|
||||||
|
> [!NOTE]:
|
||||||
|
>
|
||||||
|
> - Add your username
|
||||||
|
> - When updating/reworking scripts, add "| Co-Author [YourUserName]"
|
||||||
|
|
||||||
|
### 1.3 **Variables and function import**
|
||||||
|
|
||||||
|
- This sections adds the support for all needed functions and variables.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||||
|
color
|
||||||
|
verb_ip6
|
||||||
|
catch_errors
|
||||||
|
setting_up_container
|
||||||
|
network_check
|
||||||
|
update_os
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. **Variable naming and management**
|
||||||
|
|
||||||
|
### 2.1 **Naming conventions**
|
||||||
|
|
||||||
|
- Use uppercase names for constants and environment variables.
|
||||||
|
- Use lowercase names for local script variables.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
DB_NAME=snipeit_db # Environment-like variable (constant)
|
||||||
|
db_user="snipeit" # Local variable
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. **Dependencies**
|
||||||
|
|
||||||
|
### 3.1 **Install all at once**
|
||||||
|
|
||||||
|
- Install all dependencies with a single command if possible
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$STD apt-get install -y \
|
||||||
|
curl \
|
||||||
|
composer \
|
||||||
|
git \
|
||||||
|
sudo \
|
||||||
|
mc \
|
||||||
|
nginx
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.2 **Collapse dependencies**
|
||||||
|
|
||||||
|
Collapse dependencies to keep the code readable.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
Use
|
||||||
|
|
||||||
|
```bash
|
||||||
|
php8.2-{bcmath,common,ctype}
|
||||||
|
```
|
||||||
|
|
||||||
|
instead of
|
||||||
|
|
||||||
|
```bash
|
||||||
|
php8.2-bcmath php8.2-common php8.2-ctype
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. **Paths to application files**
|
||||||
|
|
||||||
|
If possible install the app and all necessary files in `/opt/`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. **Version management**
|
||||||
|
|
||||||
|
### 5.1 **Install the latest release**
|
||||||
|
|
||||||
|
- Always try and install the latest release
|
||||||
|
- Do not hardcode any version if not absolutely necessary
|
||||||
|
|
||||||
|
Example for a git release:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
RELEASE=$(curl -fsSL https://api.github.com/repos/snipe/snipe-it/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
|
||||||
|
curl -fsSL "https://github.com/snipe/snipe-it/archive/refs/tags/v${RELEASE}.zip"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.2 **Save the version for update checks**
|
||||||
|
|
||||||
|
- Write the installed version into a file.
|
||||||
|
- This is used for the update function in **AppName.sh** to check for if a Update is needed.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
echo "${RELEASE}" >"/opt/AppName_version.txt"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. **Input and output management**
|
||||||
|
|
||||||
|
### 6.1 **User feedback**
|
||||||
|
|
||||||
|
- Use standard functions like `msg_info`, `msg_ok` or `msg_error` to print status messages.
|
||||||
|
- Each `msg_info` must be followed with a `msg_ok` before any other output is made.
|
||||||
|
- Display meaningful progress messages at key stages.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
msg_info "Installing Dependencies"
|
||||||
|
$STD apt-get install -y ...
|
||||||
|
msg_ok "Installed Dependencies"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6.2 **Verbosity**
|
||||||
|
|
||||||
|
- Use the appropiate flag (**-q** in the examples) for a command to suppres its output
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -fsSL
|
||||||
|
unzip -q
|
||||||
|
```
|
||||||
|
|
||||||
|
- If a command dose not come with such a functionality use `$STD` (a custom standard redirection variable) for managing output verbosity.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$STD apt-get install -y nginx
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. **String/File Manipulation**
|
||||||
|
|
||||||
|
### 7.1 **File Manipulation**
|
||||||
|
|
||||||
|
- Use `sed` to replace placeholder values in configuration files.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sed -i -e "s|^DB_DATABASE=.*|DB_DATABASE=$DB_NAME|" \
|
||||||
|
-e "s|^DB_USERNAME=.*|DB_USERNAME=$DB_USER|" \
|
||||||
|
-e "s|^DB_PASSWORD=.*|DB_PASSWORD=$DB_PASS|" .env
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. **Security practices**
|
||||||
|
|
||||||
|
### 8.1 **Password generation**
|
||||||
|
|
||||||
|
- Use `openssl` to generate random passwords.
|
||||||
|
- Use only alphanumeric values to not introduce unknown behaviour.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 8.2 **File permissions**
|
||||||
|
|
||||||
|
Explicitly set secure ownership and permissions for sensitive files.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
chown -R www-data: /opt/snipe-it
|
||||||
|
chmod -R 755 /opt/snipe-it
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. **Service Configuration**
|
||||||
|
|
||||||
|
### 9.1 **Configuration files**
|
||||||
|
|
||||||
|
Use `cat <<EOF` to write configuration files in a clean and readable way.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cat <<EOF >/etc/nginx/conf.d/snipeit.conf
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
root /opt/snipe-it/public;
|
||||||
|
index index.php;
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
### 9.2 **Credential management**
|
||||||
|
|
||||||
|
Store the generated credentials in a file.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
USERNAME=username
|
||||||
|
PASSWORD=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
|
||||||
|
{
|
||||||
|
echo "Application-Credentials"
|
||||||
|
echo "Username: $USERNAME"
|
||||||
|
echo "Password: $PASSWORD"
|
||||||
|
} >> ~/application.creds
|
||||||
|
```
|
||||||
|
|
||||||
|
### 9.3 **Enviroment files**
|
||||||
|
|
||||||
|
Use `cat <<EOF` to write enviromental files in a clean and readable way.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cat <<EOF >/path/to/.env
|
||||||
|
VARIABLE="value"
|
||||||
|
PORT=3000
|
||||||
|
DB_NAME="${DB_NAME}"
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
### 9.4 **Services**
|
||||||
|
|
||||||
|
Enable affected services after configuration changes and start them right away.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl enable -q --now nginx
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10. **Cleanup**
|
||||||
|
|
||||||
|
### 10.1 **Remove temporary files**
|
||||||
|
|
||||||
|
Remove temporary files and downloads after use.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
rm -rf /opt/v${RELEASE}.zip
|
||||||
|
```
|
||||||
|
|
||||||
|
### 10.2 **Autoremove and autoclean**
|
||||||
|
|
||||||
|
Remove unused dependencies to reduce disk space usage.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
apt-get -y autoremove
|
||||||
|
apt-get -y autoclean
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 11. **Best Practices Checklist**
|
||||||
|
|
||||||
|
- [ ] Shebang is correctly set (`#!/usr/bin/env bash`).
|
||||||
|
- [ ] Metadata (author, license) is included at the top.
|
||||||
|
- [ ] Variables follow naming conventions.
|
||||||
|
- [ ] Sensitive values are dynamically generated.
|
||||||
|
- [ ] Files and services have proper permissions.
|
||||||
|
- [ ] Script cleans up temporary files.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Example: High-Level Script Flow
|
||||||
|
|
||||||
|
1. Dependencies installation
|
||||||
|
2. Database setup
|
||||||
|
3. Download and configure application
|
||||||
|
4. Service configuration
|
||||||
|
5. Final cleanup
|
||||||
83
.github/CONTRIBUTOR_AND_GUIDES/install/AppName-install.sh
generated
vendored
Normal file
83
.github/CONTRIBUTOR_AND_GUIDES/install/AppName-install.sh
generated
vendored
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
|
# Author: [YourUserName]
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
||||||
|
# Source: [SOURCE_URL]
|
||||||
|
|
||||||
|
# Import Functions und Setup
|
||||||
|
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||||
|
color
|
||||||
|
verb_ip6
|
||||||
|
catch_errors
|
||||||
|
setting_up_container
|
||||||
|
network_check
|
||||||
|
update_os
|
||||||
|
|
||||||
|
# Installing Dependencies with the 3 core dependencies (curl;sudo;mc)
|
||||||
|
msg_info "Installing Dependencies"
|
||||||
|
$STD apt-get install -y \
|
||||||
|
curl \
|
||||||
|
sudo \
|
||||||
|
mc \
|
||||||
|
[PACKAGE_1] \
|
||||||
|
[PACKAGE_2] \
|
||||||
|
[PACKAGE_3]
|
||||||
|
msg_ok "Installed Dependencies"
|
||||||
|
|
||||||
|
# Template: MySQL Database
|
||||||
|
msg_info "Setting up Database"
|
||||||
|
DB_NAME=[DB_NAME]
|
||||||
|
DB_USER=[DB_USER]
|
||||||
|
DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
|
||||||
|
$STD mysql -u root -e "CREATE DATABASE $DB_NAME;"
|
||||||
|
$STD mysql -u root -e "CREATE USER '$DB_USER'@'localhost' IDENTIFIED WITH mysql_native_password AS PASSWORD('$DB_PASS');"
|
||||||
|
$STD mysql -u root -e "GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost'; FLUSH PRIVILEGES;"
|
||||||
|
{
|
||||||
|
echo "${APPLICATION} Credentials"
|
||||||
|
echo "Database User: $DB_USER"
|
||||||
|
echo "Database Password: $DB_PASS"
|
||||||
|
echo "Database Name: $DB_NAME"
|
||||||
|
} >>~/$APP_NAME.creds
|
||||||
|
msg_ok "Set up Database"
|
||||||
|
|
||||||
|
# Temp
|
||||||
|
|
||||||
|
# Setup App
|
||||||
|
msg_info "Setup ${APPLICATION}"
|
||||||
|
RELEASE=$(curl -s https://api.github.com/repos/[REPO]/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
|
||||||
|
curl -fsSL "https://github.com/[REPO]/archive/refs/tags/${RELEASE}.zip"
|
||||||
|
unzip -q ${RELEASE}.zip
|
||||||
|
mv ${APPLICATION}-${RELEASE}/ /opt/${APPLICATION}
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
echo "${RELEASE}" >/opt/${APPLICATION}_version.txt
|
||||||
|
msg_ok "Setup ${APPLICATION}"
|
||||||
|
|
||||||
|
# Creating Service (if needed)
|
||||||
|
msg_info "Creating Service"
|
||||||
|
cat <<EOF >/etc/systemd/system/${APPLICATION}.service
|
||||||
|
[Unit]
|
||||||
|
Description=${APPLICATION} Service
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
ExecStart=[START_COMMAND]
|
||||||
|
Restart=always
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
systemctl enable -q --now ${APPLICATION}.service
|
||||||
|
msg_ok "Created Service"
|
||||||
|
|
||||||
|
motd_ssh
|
||||||
|
customize
|
||||||
|
|
||||||
|
# Cleanup
|
||||||
|
msg_info "Cleaning up"
|
||||||
|
rm -f ${RELEASE}.zip
|
||||||
|
$STD apt-get -y autoremove
|
||||||
|
$STD apt-get -y autoclean
|
||||||
|
msg_ok "Cleaned"
|
||||||
34
.github/CONTRIBUTOR_AND_GUIDES/json/AppName.json
generated
vendored
Normal file
34
.github/CONTRIBUTOR_AND_GUIDES/json/AppName.json
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"name": "AppName",
|
||||||
|
"slug": "appname",
|
||||||
|
"categories": [
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"date_created": "DATE CREATED",
|
||||||
|
"type": "ct",
|
||||||
|
"updateable": true,
|
||||||
|
"privileged": false,
|
||||||
|
"interface_port": DEFAULT-PORT,
|
||||||
|
"documentation": null,
|
||||||
|
"website": "LINK TO WEBSITE",
|
||||||
|
"logo": "LINK TO LOGO",
|
||||||
|
"description": "Description of the app",
|
||||||
|
"install_methods": [
|
||||||
|
{
|
||||||
|
"type": "default",
|
||||||
|
"script": "ct/AppName.sh",
|
||||||
|
"resources": {
|
||||||
|
"cpu": 2,
|
||||||
|
"ram": 2048,
|
||||||
|
"hdd": 4,
|
||||||
|
"os": "debian",
|
||||||
|
"version": "12"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default_credentials": {
|
||||||
|
"username": null,
|
||||||
|
"password": null
|
||||||
|
},
|
||||||
|
"notes": []
|
||||||
|
}
|
||||||
13
.github/CONTRIBUTOR_AND_GUIDES/json/AppName.md
generated
vendored
Normal file
13
.github/CONTRIBUTOR_AND_GUIDES/json/AppName.md
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
# **AppName<span></span>.json Files**
|
||||||
|
|
||||||
|
`AppName.json` files found in the `/json` directory. These files are used to provide informations for the website. For this guide we take `/json/snipeit.json` as example.
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
|
||||||
|
- [**AppName.json Files**](#appnamejson-files)
|
||||||
|
- [Table of Contents](#table-of-contents)
|
||||||
|
- [1. JSON Generator](#1-json-generator)
|
||||||
|
|
||||||
|
## 1. JSON Generator
|
||||||
|
|
||||||
|
Use the [JSON Generator](https://community-scripts.github.io/ProxmoxVED/json-editor) to create this file for your application.
|
||||||
2
.github/autolabeler-config.json
generated
vendored
2
.github/autolabeler-config.json
generated
vendored
@@ -97,7 +97,7 @@
|
|||||||
{
|
{
|
||||||
"fileStatus": "modified",
|
"fileStatus": "modified",
|
||||||
"includeGlobs": [
|
"includeGlobs": [
|
||||||
"json/**"
|
"frontend/public/json/**"
|
||||||
],
|
],
|
||||||
"excludeGlobs": []
|
"excludeGlobs": []
|
||||||
}
|
}
|
||||||
|
|||||||
3
.github/pull_request_template.md
generated
vendored
3
.github/pull_request_template.md
generated
vendored
@@ -49,6 +49,3 @@ Link: #
|
|||||||
- [ ] The application has **600+ GitHub stars**
|
- [ ] The application has **600+ GitHub stars**
|
||||||
- [ ] Official **release tarballs** are published
|
- [ ] Official **release tarballs** are published
|
||||||
- [ ] I understand that not all scripts will be accepted due to various reasons and criteria by the community-scripts ORG
|
- [ ] I understand that not all scripts will be accepted due to various reasons and criteria by the community-scripts ORG
|
||||||
|
|
||||||
## 🌐 Source
|
|
||||||
<!-- Add any sources and github links. -->
|
|
||||||
|
|||||||
2
.github/workflows/bak/get-versions-from-gh.yaml
generated
vendored
2
.github/workflows/bak/get-versions-from-gh.yaml
generated
vendored
@@ -47,7 +47,7 @@ jobs:
|
|||||||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||||||
git config --global user.name "GitHub Actions[bot]"
|
git config --global user.name "GitHub Actions[bot]"
|
||||||
git checkout -b update_versions || git checkout update_versions
|
git checkout -b update_versions || git checkout update_versions
|
||||||
git add json/versions.json
|
git add frontend/public/json/versions.json
|
||||||
if git diff --cached --quiet; then
|
if git diff --cached --quiet; then
|
||||||
echo "No changes detected."
|
echo "No changes detected."
|
||||||
echo "changed=false" >> "$GITHUB_ENV"
|
echo "changed=false" >> "$GITHUB_ENV"
|
||||||
|
|||||||
4
.github/workflows/bak/get-versions-from-newreleases.yaml
generated
vendored
4
.github/workflows/bak/get-versions-from-newreleases.yaml
generated
vendored
@@ -46,7 +46,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
page=1
|
page=1
|
||||||
projects_file="project_json"
|
projects_file="project_json"
|
||||||
output_file="json/versions.json"
|
output_file="frontend/public/json/versions.json"
|
||||||
|
|
||||||
echo "[]" > $output_file
|
echo "[]" > $output_file
|
||||||
|
|
||||||
@@ -95,7 +95,7 @@ jobs:
|
|||||||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||||||
git config --global user.name "GitHub Actions[bot]"
|
git config --global user.name "GitHub Actions[bot]"
|
||||||
git checkout -b update_versions || git checkout update_versions
|
git checkout -b update_versions || git checkout update_versions
|
||||||
git add json/versions.json
|
git add frontend/public/json/versions.json
|
||||||
if git diff --cached --quiet; then
|
if git diff --cached --quiet; then
|
||||||
echo "No changes detected."
|
echo "No changes detected."
|
||||||
echo "changed=false" >> "$GITHUB_ENV"
|
echo "changed=false" >> "$GITHUB_ENV"
|
||||||
|
|||||||
4
.github/workflows/bak/update-versions-github.yml
generated
vendored
4
.github/workflows/bak/update-versions-github.yml
generated
vendored
@@ -11,8 +11,8 @@ permissions:
|
|||||||
pull-requests: write
|
pull-requests: write
|
||||||
|
|
||||||
env:
|
env:
|
||||||
SOURCES_FILE: json/version-sources.json
|
SOURCES_FILE: frontend/public/json/version-sources.json
|
||||||
VERSIONS_FILE: json/versions.json
|
VERSIONS_FILE: frontend/public/json/versions.json
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
update-versions:
|
update-versions:
|
||||||
|
|||||||
16
.github/workflows/create-ready-for-testing-message.yml
generated
vendored
16
.github/workflows/create-ready-for-testing-message.yml
generated
vendored
@@ -7,7 +7,6 @@ on:
|
|||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
issues: write
|
issues: write
|
||||||
actions: write
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
post_to_discord:
|
post_to_discord:
|
||||||
@@ -60,19 +59,19 @@ jobs:
|
|||||||
FILES=(
|
FILES=(
|
||||||
"ct/${TITLE}.sh"
|
"ct/${TITLE}.sh"
|
||||||
"install/${TITLE}-install.sh"
|
"install/${TITLE}-install.sh"
|
||||||
"json/${TITLE}.json"
|
"frontend/public/json/${TITLE}.json"
|
||||||
)
|
)
|
||||||
;;
|
;;
|
||||||
vm)
|
vm)
|
||||||
FILES=(
|
FILES=(
|
||||||
"vm/${TITLE}.sh"
|
"vm/${TITLE}.sh"
|
||||||
"json/${TITLE}.json"
|
"frontend/public/json/${TITLE}.json"
|
||||||
)
|
)
|
||||||
;;
|
;;
|
||||||
addon)
|
addon)
|
||||||
FILES=(
|
FILES=(
|
||||||
"tools/addon/${TITLE}.sh"
|
"tools/addon/${TITLE}.sh"
|
||||||
"json/${TITLE}.json"
|
"frontend/public/json/${TITLE}.json"
|
||||||
)
|
)
|
||||||
;;
|
;;
|
||||||
pve)
|
pve)
|
||||||
@@ -123,7 +122,7 @@ jobs:
|
|||||||
JSON_FILE=""
|
JSON_FILE=""
|
||||||
case "$SCRIPT_TYPE" in
|
case "$SCRIPT_TYPE" in
|
||||||
ct|vm|addon)
|
ct|vm|addon)
|
||||||
JSON_FILE="json/${TITLE}.json"
|
JSON_FILE="frontend/public/json/${TITLE}.json"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
@@ -218,10 +217,3 @@ jobs:
|
|||||||
echo -e "$MESSAGE" > comment.txt
|
echo -e "$MESSAGE" > comment.txt
|
||||||
sed -i '/Discussion & issue tracking:/,$d' comment.txt
|
sed -i '/Discussion & issue tracking:/,$d' comment.txt
|
||||||
gh issue comment ${{ github.event.issue.number }} --repo ${{ github.repository }} --body-file comment.txt
|
gh issue comment ${{ github.event.issue.number }} --repo ${{ github.repository }} --body-file comment.txt
|
||||||
|
|
||||||
- name: Push script JSON to PocketBase
|
|
||||||
if: env.SCRIPT_TYPE == 'ct' || env.SCRIPT_TYPE == 'vm' || env.SCRIPT_TYPE == 'addon'
|
|
||||||
env:
|
|
||||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
run: |
|
|
||||||
gh workflow run push_json_to_pocketbase.yml --repo ${{ github.repository }} -f script_slug=${{ env.TITLE }}
|
|
||||||
|
|||||||
8
.github/workflows/delete_new_script.yaml
generated
vendored
8
.github/workflows/delete_new_script.yaml
generated
vendored
@@ -124,20 +124,20 @@ jobs:
|
|||||||
rm -f "ct/${TITLE}.sh"
|
rm -f "ct/${TITLE}.sh"
|
||||||
rm -f "ct/headers/${TITLE}"
|
rm -f "ct/headers/${TITLE}"
|
||||||
rm -f "install/${TITLE}-install.sh"
|
rm -f "install/${TITLE}-install.sh"
|
||||||
rm -f "json/${TITLE}.json"
|
rm -f "frontend/public/json/${TITLE}.json"
|
||||||
# Also try alpine variant
|
# Also try alpine variant
|
||||||
if [[ "$TITLE" == alpine-* ]]; then
|
if [[ "$TITLE" == alpine-* ]]; then
|
||||||
stripped="${TITLE#alpine-}"
|
stripped="${TITLE#alpine-}"
|
||||||
rm -f "json/${stripped}.json"
|
rm -f "frontend/public/json/${stripped}.json"
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
vm)
|
vm)
|
||||||
rm -f "vm/${TITLE}.sh"
|
rm -f "vm/${TITLE}.sh"
|
||||||
rm -f "json/${TITLE}.json"
|
rm -f "frontend/public/json/${TITLE}.json"
|
||||||
;;
|
;;
|
||||||
addon)
|
addon)
|
||||||
rm -f "tools/addon/${TITLE}.sh"
|
rm -f "tools/addon/${TITLE}.sh"
|
||||||
rm -f "json/${TITLE}.json"
|
rm -f "frontend/public/json/${TITLE}.json"
|
||||||
;;
|
;;
|
||||||
pve)
|
pve)
|
||||||
rm -f "tools/pve/${TITLE}.sh"
|
rm -f "tools/pve/${TITLE}.sh"
|
||||||
|
|||||||
77
.github/workflows/frontend-cicd.yml
generated
vendored
Normal file
77
.github/workflows/frontend-cicd.yml
generated
vendored
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
# Based on https://github.com/actions/starter-workflows/blob/main/pages/nextjs.yml
|
||||||
|
|
||||||
|
name: Frontend CI/CD
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: ["main"]
|
||||||
|
paths:
|
||||||
|
- frontend/**
|
||||||
|
|
||||||
|
pull_request:
|
||||||
|
branches: ["main"]
|
||||||
|
types: [opened, synchronize, reopened, edited]
|
||||||
|
paths:
|
||||||
|
- frontend/**
|
||||||
|
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: pages-${{ github.ref }}
|
||||||
|
cancel-in-progress: false
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
if: github.repository == 'community-scripts/ProxmoxVED'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
working-directory: frontend # Set default working directory for all run steps
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Node
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: "20"
|
||||||
|
cache: npm
|
||||||
|
cache-dependency-path: frontend/package-lock.json
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm ci --prefer-offline --legacy-peer-deps
|
||||||
|
|
||||||
|
- name: Run tests
|
||||||
|
run: npm run test
|
||||||
|
|
||||||
|
- name: Configure Next.js for pages
|
||||||
|
uses: actions/configure-pages@v5
|
||||||
|
with:
|
||||||
|
static_site_generator: next
|
||||||
|
|
||||||
|
- name: Build with Next.js
|
||||||
|
run: npm run build
|
||||||
|
|
||||||
|
- name: Upload artifact
|
||||||
|
if: github.ref == 'refs/heads/main'
|
||||||
|
uses: actions/upload-pages-artifact@v3
|
||||||
|
with:
|
||||||
|
path: frontend/out
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: build
|
||||||
|
if: github.ref == 'refs/heads/main' && github.repository == 'community-scripts/ProxmoxVED'
|
||||||
|
permissions:
|
||||||
|
pages: write
|
||||||
|
id-token: write
|
||||||
|
environment:
|
||||||
|
name: github-pages
|
||||||
|
url: ${{ steps.deployment.outputs.page_url }}
|
||||||
|
steps:
|
||||||
|
- name: Deploy to GitHub Pages
|
||||||
|
id: deployment
|
||||||
|
uses: actions/deploy-pages@v4
|
||||||
60
.github/workflows/move-to-main-repo.yaml
generated
vendored
60
.github/workflows/move-to-main-repo.yaml
generated
vendored
@@ -38,24 +38,12 @@ jobs:
|
|||||||
id: list_issues
|
id: list_issues
|
||||||
env:
|
env:
|
||||||
GH_TOKEN: ${{ github.token }}
|
GH_TOKEN: ${{ github.token }}
|
||||||
ISSUE_JSON: ${{ toJson(github.event.issue) }}
|
|
||||||
run: |
|
run: |
|
||||||
echo "Resolving issue with label Migration To ProxmoxVE"
|
echo "Filtering Issues with Label Migration To ProxmoxVE"
|
||||||
|
raw_output=$(gh issue list --json title,labels,number,body)
|
||||||
|
filtered_issue=$(echo "$raw_output" | jq -r '[.[] | select(.labels[]?.name == "Migration To ProxmoxVE")][0]')
|
||||||
|
|
||||||
if [[ "${{ github.event_name }}" == "issues" ]]; then
|
if [ "$filtered_issue" == "null" ] || [ -z "$filtered_issue" ]; then
|
||||||
# For labeled issue events, use the exact issue from event payload.
|
|
||||||
filtered_issue="$ISSUE_JSON"
|
|
||||||
else
|
|
||||||
# Fallback for workflow_dispatch: query explicitly by label and raise limit.
|
|
||||||
raw_output=$(gh issue list \
|
|
||||||
--label "Migration To ProxmoxVE" \
|
|
||||||
--state open \
|
|
||||||
--limit 500 \
|
|
||||||
--json title,labels,number,body)
|
|
||||||
filtered_issue=$(echo "$raw_output" | jq -c '.[0]')
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$filtered_issue" == "null" ]] || [[ -z "$filtered_issue" ]]; then
|
|
||||||
echo "No issues found with label 'Migration To ProxmoxVE'."
|
echo "No issues found with label 'Migration To ProxmoxVE'."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
@@ -112,6 +100,26 @@ jobs:
|
|||||||
files_found="false"
|
files_found="false"
|
||||||
missing_files+="install/${script_name}-install.sh "
|
missing_files+="install/${script_name}-install.sh "
|
||||||
fi
|
fi
|
||||||
|
# JSON check with alpine fallback
|
||||||
|
json_file="frontend/public/json/${script_name}.json"
|
||||||
|
if [[ ! -f "$json_file" ]]; then
|
||||||
|
if [[ "$script_name" == alpine-* ]]; then
|
||||||
|
stripped_name="${script_name#alpine-}"
|
||||||
|
alt_json="frontend/public/json/${stripped_name}.json"
|
||||||
|
if [[ -f "$alt_json" ]]; then
|
||||||
|
echo "Using alpine fallback JSON: $alt_json"
|
||||||
|
echo "json_fallback=$alt_json" >> $GITHUB_OUTPUT
|
||||||
|
else
|
||||||
|
echo "json file not found: $json_file"
|
||||||
|
files_found="false"
|
||||||
|
missing_files+="$json_file "
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "json file not found: $json_file"
|
||||||
|
files_found="false"
|
||||||
|
missing_files+="$json_file "
|
||||||
|
fi
|
||||||
|
fi
|
||||||
;;
|
;;
|
||||||
vm)
|
vm)
|
||||||
if [[ ! -f "vm/${script_name}.sh" ]]; then
|
if [[ ! -f "vm/${script_name}.sh" ]]; then
|
||||||
@@ -119,6 +127,11 @@ jobs:
|
|||||||
files_found="false"
|
files_found="false"
|
||||||
missing_files+="vm/${script_name}.sh "
|
missing_files+="vm/${script_name}.sh "
|
||||||
fi
|
fi
|
||||||
|
# JSON is optional for VMs but check anyway
|
||||||
|
json_file="frontend/public/json/${script_name}.json"
|
||||||
|
if [[ ! -f "$json_file" ]]; then
|
||||||
|
echo "json file not found (optional): $json_file"
|
||||||
|
fi
|
||||||
;;
|
;;
|
||||||
addon)
|
addon)
|
||||||
if [[ ! -f "tools/addon/${script_name}.sh" ]]; then
|
if [[ ! -f "tools/addon/${script_name}.sh" ]]; then
|
||||||
@@ -126,6 +139,11 @@ jobs:
|
|||||||
files_found="false"
|
files_found="false"
|
||||||
missing_files+="tools/addon/${script_name}.sh "
|
missing_files+="tools/addon/${script_name}.sh "
|
||||||
fi
|
fi
|
||||||
|
# JSON is optional for addons
|
||||||
|
json_file="frontend/public/json/${script_name}.json"
|
||||||
|
if [[ ! -f "$json_file" ]]; then
|
||||||
|
echo "json file not found (optional): $json_file"
|
||||||
|
fi
|
||||||
;;
|
;;
|
||||||
pve)
|
pve)
|
||||||
if [[ ! -f "tools/pve/${script_name}.sh" ]]; then
|
if [[ ! -f "tools/pve/${script_name}.sh" ]]; then
|
||||||
@@ -172,6 +190,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
script_name="${{ steps.list_issues.outputs.script_name }}"
|
script_name="${{ steps.list_issues.outputs.script_name }}"
|
||||||
script_type="${{ steps.list_issues.outputs.script_type }}"
|
script_type="${{ steps.list_issues.outputs.script_type }}"
|
||||||
|
json_fallback="${{ steps.check_files.outputs.json_fallback }}"
|
||||||
|
|
||||||
git clone https://x-access-token:${{ steps.app-token.outputs.token }}@github.com/community-scripts/ProxmoxVE.git ProxmoxVE
|
git clone https://x-access-token:${{ steps.app-token.outputs.token }}@github.com/community-scripts/ProxmoxVE.git ProxmoxVE
|
||||||
cd ProxmoxVE
|
cd ProxmoxVE
|
||||||
@@ -208,6 +227,13 @@ jobs:
|
|||||||
cp ../ct/headers/${script_name} ct/headers/ 2>/dev/null || true
|
cp ../ct/headers/${script_name} ct/headers/ 2>/dev/null || true
|
||||||
cp ../install/${script_name}-install.sh install/
|
cp ../install/${script_name}-install.sh install/
|
||||||
|
|
||||||
|
# Handle JSON with alpine fallback
|
||||||
|
if [[ -n "$json_fallback" ]]; then
|
||||||
|
cp ../${json_fallback} frontend/public/json/ || true
|
||||||
|
else
|
||||||
|
cp ../frontend/public/json/${script_name}.json frontend/public/json/ 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
# Update URLs in ct script
|
# Update URLs in ct script
|
||||||
sed -i "s|https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func|https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func|" ct/${script_name}.sh
|
sed -i "s|https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func|https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func|" ct/${script_name}.sh
|
||||||
sed -i "s|https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/build.func|https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func|" ct/${script_name}.sh
|
sed -i "s|https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/build.func|https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func|" ct/${script_name}.sh
|
||||||
@@ -216,6 +242,7 @@ jobs:
|
|||||||
;;
|
;;
|
||||||
vm)
|
vm)
|
||||||
cp ../vm/${script_name}.sh vm/
|
cp ../vm/${script_name}.sh vm/
|
||||||
|
cp ../frontend/public/json/${script_name}.json frontend/public/json/ 2>/dev/null || true
|
||||||
|
|
||||||
# Update URLs in vm script
|
# Update URLs in vm script
|
||||||
sed -i "s|https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func|https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func|" vm/${script_name}.sh
|
sed -i "s|https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func|https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func|" vm/${script_name}.sh
|
||||||
@@ -224,6 +251,7 @@ jobs:
|
|||||||
addon)
|
addon)
|
||||||
mkdir -p tools/addon
|
mkdir -p tools/addon
|
||||||
cp ../tools/addon/${script_name}.sh tools/addon/
|
cp ../tools/addon/${script_name}.sh tools/addon/
|
||||||
|
cp ../frontend/public/json/${script_name}.json frontend/public/json/ 2>/dev/null || true
|
||||||
|
|
||||||
# Update URLs in addon script
|
# Update URLs in addon script
|
||||||
sed -i "s|community-scripts/ProxmoxVED|community-scripts/ProxmoxVE|g" tools/addon/${script_name}.sh
|
sed -i "s|community-scripts/ProxmoxVED|community-scripts/ProxmoxVE|g" tools/addon/${script_name}.sh
|
||||||
|
|||||||
676
.github/workflows/pocketbase-bot.yml
generated
vendored
676
.github/workflows/pocketbase-bot.yml
generated
vendored
@@ -1,676 +0,0 @@
|
|||||||
name: PocketBase Bot
|
|
||||||
|
|
||||||
on:
|
|
||||||
issue_comment:
|
|
||||||
types: [created]
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
issues: write
|
|
||||||
pull-requests: write
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
pocketbase-bot:
|
|
||||||
runs-on: self-hosted
|
|
||||||
|
|
||||||
# Only act on /pocketbase commands
|
|
||||||
if: startsWith(github.event.comment.body, '/pocketbase')
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Execute PocketBase bot command
|
|
||||||
env:
|
|
||||||
POCKETBASE_URL: ${{ secrets.POCKETBASE_URL }}
|
|
||||||
POCKETBASE_COLLECTION: ${{ secrets.POCKETBASE_COLLECTION }}
|
|
||||||
POCKETBASE_ADMIN_EMAIL: ${{ secrets.POCKETBASE_ADMIN_EMAIL }}
|
|
||||||
POCKETBASE_ADMIN_PASSWORD: ${{ secrets.POCKETBASE_ADMIN_PASSWORD }}
|
|
||||||
COMMENT_BODY: ${{ github.event.comment.body }}
|
|
||||||
COMMENT_ID: ${{ github.event.comment.id }}
|
|
||||||
ISSUE_NUMBER: ${{ github.event.issue.number }}
|
|
||||||
REPO_OWNER: ${{ github.repository_owner }}
|
|
||||||
REPO_NAME: ${{ github.event.repository.name }}
|
|
||||||
ACTOR: ${{ github.event.comment.user.login }}
|
|
||||||
ACTOR_ASSOCIATION: ${{ github.event.comment.author_association }}
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
run: |
|
|
||||||
node << 'ENDSCRIPT'
|
|
||||||
(async function () {
|
|
||||||
const https = require('https');
|
|
||||||
const http = require('http');
|
|
||||||
const url = require('url');
|
|
||||||
|
|
||||||
// ── HTTP helper with redirect following ────────────────────────────
|
|
||||||
function request(fullUrl, opts, redirectCount) {
|
|
||||||
redirectCount = redirectCount || 0;
|
|
||||||
return new Promise(function (resolve, reject) {
|
|
||||||
const u = url.parse(fullUrl);
|
|
||||||
const isHttps = u.protocol === 'https:';
|
|
||||||
const body = opts.body;
|
|
||||||
const options = {
|
|
||||||
hostname: u.hostname,
|
|
||||||
port: u.port || (isHttps ? 443 : 80),
|
|
||||||
path: u.path,
|
|
||||||
method: opts.method || 'GET',
|
|
||||||
headers: opts.headers || {}
|
|
||||||
};
|
|
||||||
if (body) options.headers['Content-Length'] = Buffer.byteLength(body);
|
|
||||||
const lib = isHttps ? https : http;
|
|
||||||
const req = lib.request(options, function (res) {
|
|
||||||
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
|
||||||
if (redirectCount >= 5) return reject(new Error('Too many redirects from ' + fullUrl));
|
|
||||||
const redirectUrl = url.resolve(fullUrl, res.headers.location);
|
|
||||||
res.resume();
|
|
||||||
resolve(request(redirectUrl, opts, redirectCount + 1));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let data = '';
|
|
||||||
res.on('data', function (chunk) { data += chunk; });
|
|
||||||
res.on('end', function () {
|
|
||||||
resolve({ ok: res.statusCode >= 200 && res.statusCode < 300, statusCode: res.statusCode, body: data });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
req.on('error', reject);
|
|
||||||
if (body) req.write(body);
|
|
||||||
req.end();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// ── GitHub API helpers ─────────────────────────────────────────────
|
|
||||||
const owner = process.env.REPO_OWNER;
|
|
||||||
const repo = process.env.REPO_NAME;
|
|
||||||
const issueNumber = parseInt(process.env.ISSUE_NUMBER, 10);
|
|
||||||
const commentId = parseInt(process.env.COMMENT_ID, 10);
|
|
||||||
const actor = process.env.ACTOR;
|
|
||||||
|
|
||||||
function ghRequest(path, method, body) {
|
|
||||||
const headers = {
|
|
||||||
'Authorization': 'Bearer ' + process.env.GITHUB_TOKEN,
|
|
||||||
'Accept': 'application/vnd.github+json',
|
|
||||||
'X-GitHub-Api-Version': '2022-11-28',
|
|
||||||
'User-Agent': 'PocketBase-Bot'
|
|
||||||
};
|
|
||||||
const bodyStr = body ? JSON.stringify(body) : undefined;
|
|
||||||
if (bodyStr) headers['Content-Type'] = 'application/json';
|
|
||||||
return request('https://api.github.com' + path, { method: method || 'GET', headers, body: bodyStr });
|
|
||||||
}
|
|
||||||
|
|
||||||
async function addReaction(content) {
|
|
||||||
try {
|
|
||||||
await ghRequest(
|
|
||||||
'/repos/' + owner + '/' + repo + '/issues/comments/' + commentId + '/reactions',
|
|
||||||
'POST', { content }
|
|
||||||
);
|
|
||||||
} catch (e) {
|
|
||||||
console.warn('Could not add reaction:', e.message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function postComment(text) {
|
|
||||||
const res = await ghRequest(
|
|
||||||
'/repos/' + owner + '/' + repo + '/issues/' + issueNumber + '/comments',
|
|
||||||
'POST', { body: text }
|
|
||||||
);
|
|
||||||
if (!res.ok) console.warn('Could not post comment:', res.body);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ── Permission check ───────────────────────────────────────────────
|
|
||||||
// author_association: OWNER = repo/org owner, MEMBER = org member (includes Contributors team)
|
|
||||||
const association = process.env.ACTOR_ASSOCIATION;
|
|
||||||
if (association !== 'OWNER' && association !== 'MEMBER') {
|
|
||||||
await addReaction('-1');
|
|
||||||
await postComment(
|
|
||||||
'❌ **PocketBase Bot**: @' + actor + ' is not authorized to use this command.\n' +
|
|
||||||
'Only org members (Contributors team) can use `/pocketbase`.'
|
|
||||||
);
|
|
||||||
process.exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ── Acknowledge ────────────────────────────────────────────────────
|
|
||||||
await addReaction('eyes');
|
|
||||||
|
|
||||||
// ── Parse command ──────────────────────────────────────────────────
|
|
||||||
// Formats (first line of comment):
|
|
||||||
// /pocketbase <slug> field=value [field=value ...] ← field updates (simple values)
|
|
||||||
// /pocketbase <slug> set <field> ← value from code block below
|
|
||||||
// /pocketbase <slug> note list|add|edit|remove ... ← note management
|
|
||||||
// /pocketbase <slug> method list ← list install methods
|
|
||||||
// /pocketbase <slug> method <type> cpu=N ram=N hdd=N ← edit install method resources
|
|
||||||
const commentBody = process.env.COMMENT_BODY || '';
|
|
||||||
const lines = commentBody.trim().split('\n');
|
|
||||||
const firstLine = lines[0].trim();
|
|
||||||
const withoutCmd = firstLine.replace(/^\/pocketbase\s+/, '').trim();
|
|
||||||
|
|
||||||
// Extract code block content from comment body (```...``` or ```lang\n...```)
|
|
||||||
function extractCodeBlock(body) {
|
|
||||||
const m = body.match(/```[^\n]*\n([\s\S]*?)```/);
|
|
||||||
return m ? m[1].trim() : null;
|
|
||||||
}
|
|
||||||
const codeBlockValue = extractCodeBlock(commentBody);
|
|
||||||
|
|
||||||
const HELP_TEXT =
|
|
||||||
'**Field update (simple):** `/pocketbase <slug> field=value [field=value ...]`\n\n' +
|
|
||||||
'**Field update (HTML/multiline) — value from code block:**\n' +
|
|
||||||
'````\n' +
|
|
||||||
'/pocketbase <slug> set description\n' +
|
|
||||||
'```html\n' +
|
|
||||||
'<p>Your <b>HTML</b> or multi-line content here</p>\n' +
|
|
||||||
'```\n' +
|
|
||||||
'````\n\n' +
|
|
||||||
'**Note management:**\n' +
|
|
||||||
'```\n' +
|
|
||||||
'/pocketbase <slug> note list\n' +
|
|
||||||
'/pocketbase <slug> note add <type> "<text>"\n' +
|
|
||||||
'/pocketbase <slug> note edit <type> "<old text>" "<new text>"\n' +
|
|
||||||
'/pocketbase <slug> note remove <type> "<text>"\n' +
|
|
||||||
'```\n\n' +
|
|
||||||
'**Install method resources:**\n' +
|
|
||||||
'```\n' +
|
|
||||||
'/pocketbase <slug> method list\n' +
|
|
||||||
'/pocketbase <slug> method <type> hdd=10\n' +
|
|
||||||
'/pocketbase <slug> method <type> cpu=4 ram=2048 hdd=20\n' +
|
|
||||||
'```\n\n' +
|
|
||||||
'**Editable fields:** `name` `description` `logo` `documentation` `website` `project_url` `github` ' +
|
|
||||||
'`config_path` `port` `default_user` `default_passwd` ' +
|
|
||||||
'`updateable` `privileged` `has_arm` `is_dev` ' +
|
|
||||||
'`is_disabled` `disable_message` `is_deleted` `deleted_message`';
|
|
||||||
|
|
||||||
if (!withoutCmd) {
|
|
||||||
await addReaction('-1');
|
|
||||||
await postComment('❌ **PocketBase Bot**: No slug or command specified.\n\n' + HELP_TEXT);
|
|
||||||
process.exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
const spaceIdx = withoutCmd.indexOf(' ');
|
|
||||||
const slug = (spaceIdx === -1 ? withoutCmd : withoutCmd.substring(0, spaceIdx)).trim();
|
|
||||||
const rest = spaceIdx === -1 ? '' : withoutCmd.substring(spaceIdx + 1).trim();
|
|
||||||
|
|
||||||
if (!rest) {
|
|
||||||
await addReaction('-1');
|
|
||||||
await postComment('❌ **PocketBase Bot**: No command specified for slug `' + slug + '`.\n\n' + HELP_TEXT);
|
|
||||||
process.exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ── Allowed fields and their types ─────────────────────────────────
|
|
||||||
// ── PocketBase: authenticate (shared by all paths) ─────────────────
|
|
||||||
const raw = process.env.POCKETBASE_URL.replace(/\/$/, '');
|
|
||||||
const apiBase = /\/api$/i.test(raw) ? raw : raw + '/api';
|
|
||||||
const coll = process.env.POCKETBASE_COLLECTION;
|
|
||||||
|
|
||||||
const authRes = await request(apiBase + '/collections/users/auth-with-password', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: { 'Content-Type': 'application/json' },
|
|
||||||
body: JSON.stringify({
|
|
||||||
identity: process.env.POCKETBASE_ADMIN_EMAIL,
|
|
||||||
password: process.env.POCKETBASE_ADMIN_PASSWORD
|
|
||||||
})
|
|
||||||
});
|
|
||||||
if (!authRes.ok) {
|
|
||||||
await addReaction('-1');
|
|
||||||
await postComment('❌ **PocketBase Bot**: PocketBase authentication failed. CC @' + owner + '/maintainers');
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
const token = JSON.parse(authRes.body).token;
|
|
||||||
|
|
||||||
// ── PocketBase: find record by slug (shared by all paths) ──────────
|
|
||||||
const recordsUrl = apiBase + '/collections/' + encodeURIComponent(coll) + '/records';
|
|
||||||
const filter = "(slug='" + slug.replace(/'/g, "''") + "')";
|
|
||||||
const listRes = await request(recordsUrl + '?filter=' + encodeURIComponent(filter) + '&perPage=1', {
|
|
||||||
headers: { 'Authorization': token }
|
|
||||||
});
|
|
||||||
const list = JSON.parse(listRes.body);
|
|
||||||
const record = list.items && list.items[0];
|
|
||||||
|
|
||||||
if (!record) {
|
|
||||||
await addReaction('-1');
|
|
||||||
await postComment(
|
|
||||||
'❌ **PocketBase Bot**: No record found for slug `' + slug + '`.\n\n' +
|
|
||||||
'Make sure the script was already pushed to PocketBase (JSON must exist and have been synced).'
|
|
||||||
);
|
|
||||||
process.exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ── Route: dispatch to subcommand handler ──────────────────────────
|
|
||||||
const noteMatch = rest.match(/^note\s+(list|add|edit|remove)\b/i);
|
|
||||||
const methodMatch = rest.match(/^method\b/i);
|
|
||||||
const setMatch = rest.match(/^set\s+(\S+)/i);
|
|
||||||
|
|
||||||
if (noteMatch) {
|
|
||||||
// ── NOTE SUBCOMMAND (reads/writes notes_json on script record) ────
|
|
||||||
const noteAction = noteMatch[1].toLowerCase();
|
|
||||||
const noteArgsStr = rest.substring(noteMatch[0].length).trim();
|
|
||||||
|
|
||||||
// Parse notes_json from the already-fetched script record
|
|
||||||
// PocketBase may return JSON fields as already-parsed objects
|
|
||||||
let notesArr = [];
|
|
||||||
try {
|
|
||||||
const rawNotes = record.notes_json;
|
|
||||||
notesArr = Array.isArray(rawNotes) ? rawNotes : JSON.parse(rawNotes || '[]');
|
|
||||||
} catch (e) { notesArr = []; }
|
|
||||||
|
|
||||||
// Token parser: unquoted-word OR "quoted string" (supports \" escapes)
|
|
||||||
function parseNoteTokens(str) {
|
|
||||||
const tokens = [];
|
|
||||||
let pos = 0;
|
|
||||||
while (pos < str.length) {
|
|
||||||
while (pos < str.length && /\s/.test(str[pos])) pos++;
|
|
||||||
if (pos >= str.length) break;
|
|
||||||
if (str[pos] === '"') {
|
|
||||||
pos++;
|
|
||||||
let start = pos;
|
|
||||||
while (pos < str.length && str[pos] !== '"') {
|
|
||||||
if (str[pos] === '\\') pos++;
|
|
||||||
pos++;
|
|
||||||
}
|
|
||||||
tokens.push(str.substring(start, pos).replace(/\\"/g, '"'));
|
|
||||||
if (pos < str.length) pos++;
|
|
||||||
} else {
|
|
||||||
let start = pos;
|
|
||||||
while (pos < str.length && !/\s/.test(str[pos])) pos++;
|
|
||||||
tokens.push(str.substring(start, pos));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return tokens;
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatNotesList(arr) {
|
|
||||||
if (arr.length === 0) return '*None*';
|
|
||||||
return arr.map(function (n, i) {
|
|
||||||
return (i + 1) + '. **`' + (n.type || '?') + '`**: ' + (n.text || '');
|
|
||||||
}).join('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
async function patchNotesJson(arr) {
|
|
||||||
const res = await request(recordsUrl + '/' + record.id, {
|
|
||||||
method: 'PATCH',
|
|
||||||
headers: { 'Authorization': token, 'Content-Type': 'application/json' },
|
|
||||||
body: JSON.stringify({ notes_json: JSON.stringify(arr) })
|
|
||||||
});
|
|
||||||
if (!res.ok) {
|
|
||||||
await addReaction('-1');
|
|
||||||
await postComment('❌ **PocketBase Bot**: Failed to update `notes_json`:\n```\n' + res.body + '\n```');
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (noteAction === 'list') {
|
|
||||||
await addReaction('+1');
|
|
||||||
await postComment(
|
|
||||||
'ℹ️ **PocketBase Bot**: Notes for **`' + slug + '`** (' + notesArr.length + ' total)\n\n' +
|
|
||||||
formatNotesList(notesArr)
|
|
||||||
);
|
|
||||||
|
|
||||||
} else if (noteAction === 'add') {
|
|
||||||
const tokens = parseNoteTokens(noteArgsStr);
|
|
||||||
if (tokens.length < 2) {
|
|
||||||
await addReaction('-1');
|
|
||||||
await postComment(
|
|
||||||
'❌ **PocketBase Bot**: `note add` requires `<type>` and `"<text>"`.\n\n' +
|
|
||||||
'**Usage:** `/pocketbase ' + slug + ' note add <type> "<text>"`'
|
|
||||||
);
|
|
||||||
process.exit(0);
|
|
||||||
}
|
|
||||||
const noteType = tokens[0].toLowerCase();
|
|
||||||
const noteText = tokens.slice(1).join(' ');
|
|
||||||
notesArr.push({ type: noteType, text: noteText });
|
|
||||||
await patchNotesJson(notesArr);
|
|
||||||
await addReaction('+1');
|
|
||||||
await postComment(
|
|
||||||
'✅ **PocketBase Bot**: Added note to **`' + slug + '`**\n\n' +
|
|
||||||
'- **Type:** `' + noteType + '`\n' +
|
|
||||||
'- **Text:** ' + noteText + '\n\n' +
|
|
||||||
'*Executed by @' + actor + '*'
|
|
||||||
);
|
|
||||||
|
|
||||||
} else if (noteAction === 'edit') {
|
|
||||||
const tokens = parseNoteTokens(noteArgsStr);
|
|
||||||
if (tokens.length < 3) {
|
|
||||||
await addReaction('-1');
|
|
||||||
await postComment(
|
|
||||||
'❌ **PocketBase Bot**: `note edit` requires `<type>`, `"<old text>"`, and `"<new text>"`.\n\n' +
|
|
||||||
'**Usage:** `/pocketbase ' + slug + ' note edit <type> "<old text>" "<new text>"`\n\n' +
|
|
||||||
'Use `/pocketbase ' + slug + ' note list` to see current notes.'
|
|
||||||
);
|
|
||||||
process.exit(0);
|
|
||||||
}
|
|
||||||
const noteType = tokens[0].toLowerCase();
|
|
||||||
const oldText = tokens[1];
|
|
||||||
const newText = tokens[2];
|
|
||||||
const idx = notesArr.findIndex(function (n) {
|
|
||||||
return n.type.toLowerCase() === noteType && n.text === oldText;
|
|
||||||
});
|
|
||||||
if (idx === -1) {
|
|
||||||
await addReaction('-1');
|
|
||||||
await postComment(
|
|
||||||
'❌ **PocketBase Bot**: No `' + noteType + '` note found with that exact text.\n\n' +
|
|
||||||
'**Current notes for `' + slug + '`:**\n' + formatNotesList(notesArr)
|
|
||||||
);
|
|
||||||
process.exit(0);
|
|
||||||
}
|
|
||||||
notesArr[idx].text = newText;
|
|
||||||
await patchNotesJson(notesArr);
|
|
||||||
await addReaction('+1');
|
|
||||||
await postComment(
|
|
||||||
'✅ **PocketBase Bot**: Edited note in **`' + slug + '`**\n\n' +
|
|
||||||
'- **Type:** `' + noteType + '`\n' +
|
|
||||||
'- **Old:** ' + oldText + '\n' +
|
|
||||||
'- **New:** ' + newText + '\n\n' +
|
|
||||||
'*Executed by @' + actor + '*'
|
|
||||||
);
|
|
||||||
|
|
||||||
} else if (noteAction === 'remove') {
|
|
||||||
const tokens = parseNoteTokens(noteArgsStr);
|
|
||||||
if (tokens.length < 2) {
|
|
||||||
await addReaction('-1');
|
|
||||||
await postComment(
|
|
||||||
'❌ **PocketBase Bot**: `note remove` requires `<type>` and `"<text>"`.\n\n' +
|
|
||||||
'**Usage:** `/pocketbase ' + slug + ' note remove <type> "<text>"`\n\n' +
|
|
||||||
'Use `/pocketbase ' + slug + ' note list` to see current notes.'
|
|
||||||
);
|
|
||||||
process.exit(0);
|
|
||||||
}
|
|
||||||
const noteType = tokens[0].toLowerCase();
|
|
||||||
const noteText = tokens[1];
|
|
||||||
const before = notesArr.length;
|
|
||||||
notesArr = notesArr.filter(function (n) {
|
|
||||||
return !(n.type.toLowerCase() === noteType && n.text === noteText);
|
|
||||||
});
|
|
||||||
if (notesArr.length === before) {
|
|
||||||
await addReaction('-1');
|
|
||||||
await postComment(
|
|
||||||
'❌ **PocketBase Bot**: No `' + noteType + '` note found with that exact text.\n\n' +
|
|
||||||
'**Current notes for `' + slug + '`:**\n' + formatNotesList(notesArr)
|
|
||||||
);
|
|
||||||
process.exit(0);
|
|
||||||
}
|
|
||||||
await patchNotesJson(notesArr);
|
|
||||||
await addReaction('+1');
|
|
||||||
await postComment(
|
|
||||||
'✅ **PocketBase Bot**: Removed note from **`' + slug + '`**\n\n' +
|
|
||||||
'- **Type:** `' + noteType + '`\n' +
|
|
||||||
'- **Text:** ' + noteText + '\n\n' +
|
|
||||||
'*Executed by @' + actor + '*'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (methodMatch) {
|
|
||||||
// ── METHOD SUBCOMMAND (reads/writes install_methods_json on script record) ──
|
|
||||||
const methodArgs = rest.replace(/^method\s*/i, '').trim();
|
|
||||||
const methodListMode = !methodArgs || methodArgs.toLowerCase() === 'list';
|
|
||||||
|
|
||||||
// Parse install_methods_json from the already-fetched script record
|
|
||||||
// PocketBase may return JSON fields as already-parsed objects
|
|
||||||
let methodsArr = [];
|
|
||||||
try {
|
|
||||||
const rawMethods = record.install_methods_json;
|
|
||||||
methodsArr = Array.isArray(rawMethods) ? rawMethods : JSON.parse(rawMethods || '[]');
|
|
||||||
} catch (e) { methodsArr = []; }
|
|
||||||
|
|
||||||
function formatMethodsList(arr) {
|
|
||||||
if (arr.length === 0) return '*None*';
|
|
||||||
return arr.map(function (im, i) {
|
|
||||||
const r = im.resources || {};
|
|
||||||
return (i + 1) + '. **`' + (im.type || '?') + '`** — CPU: `' + (r.cpu != null ? r.cpu : '?') +
|
|
||||||
'` · RAM: `' + (r.ram != null ? r.ram : '?') + ' MB` · HDD: `' + (r.hdd != null ? r.hdd : '?') + ' GB`';
|
|
||||||
}).join('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
async function patchInstallMethodsJson(arr) {
|
|
||||||
const res = await request(recordsUrl + '/' + record.id, {
|
|
||||||
method: 'PATCH',
|
|
||||||
headers: { 'Authorization': token, 'Content-Type': 'application/json' },
|
|
||||||
body: JSON.stringify({ install_methods_json: JSON.stringify(arr) })
|
|
||||||
});
|
|
||||||
if (!res.ok) {
|
|
||||||
await addReaction('-1');
|
|
||||||
await postComment('❌ **PocketBase Bot**: Failed to update `install_methods_json`:\n```\n' + res.body + '\n```');
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (methodListMode) {
|
|
||||||
await addReaction('+1');
|
|
||||||
await postComment(
|
|
||||||
'ℹ️ **PocketBase Bot**: Install methods for **`' + slug + '`** (' + methodsArr.length + ' total)\n\n' +
|
|
||||||
formatMethodsList(methodsArr)
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
// Parse: <type> cpu=N ram=N hdd=N
|
|
||||||
const methodParts = methodArgs.match(/^(\S+)\s+(.+)$/);
|
|
||||||
if (!methodParts) {
|
|
||||||
await addReaction('-1');
|
|
||||||
await postComment(
|
|
||||||
'❌ **PocketBase Bot**: Invalid `method` syntax.\n\n' +
|
|
||||||
'**Usage:**\n```\n/pocketbase ' + slug + ' method list\n/pocketbase ' + slug + ' method <type> hdd=10\n/pocketbase ' + slug + ' method <type> cpu=4 ram=2048 hdd=20\n```'
|
|
||||||
);
|
|
||||||
process.exit(0);
|
|
||||||
}
|
|
||||||
const targetType = methodParts[1].toLowerCase();
|
|
||||||
const resourcesStr = methodParts[2];
|
|
||||||
|
|
||||||
// Parse resource fields (only cpu/ram/hdd allowed)
|
|
||||||
const RESOURCE_FIELDS = { cpu: true, ram: true, hdd: true };
|
|
||||||
const resourceChanges = {};
|
|
||||||
const rePairs = /([a-z]+)=(\d+)/gi;
|
|
||||||
let m;
|
|
||||||
while ((m = rePairs.exec(resourcesStr)) !== null) {
|
|
||||||
const key = m[1].toLowerCase();
|
|
||||||
if (RESOURCE_FIELDS[key]) resourceChanges[key] = parseInt(m[2], 10);
|
|
||||||
}
|
|
||||||
if (Object.keys(resourceChanges).length === 0) {
|
|
||||||
await addReaction('-1');
|
|
||||||
await postComment('❌ **PocketBase Bot**: No valid resource fields found. Use `cpu=N`, `ram=N`, `hdd=N`.');
|
|
||||||
process.exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find matching method by type name (case-insensitive)
|
|
||||||
const idx = methodsArr.findIndex(function (im) {
|
|
||||||
return (im.type || '').toLowerCase() === targetType;
|
|
||||||
});
|
|
||||||
if (idx === -1) {
|
|
||||||
await addReaction('-1');
|
|
||||||
const availableTypes = methodsArr.map(function (im) { return im.type || '?'; });
|
|
||||||
await postComment(
|
|
||||||
'❌ **PocketBase Bot**: No install method with type `' + targetType + '` found for `' + slug + '`.\n\n' +
|
|
||||||
'**Available types:** `' + (availableTypes.length ? availableTypes.join('`, `') : '(none)') + '`\n\n' +
|
|
||||||
'Use `/pocketbase ' + slug + ' method list` to see all methods.'
|
|
||||||
);
|
|
||||||
process.exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!methodsArr[idx].resources) methodsArr[idx].resources = {};
|
|
||||||
if (resourceChanges.cpu != null) methodsArr[idx].resources.cpu = resourceChanges.cpu;
|
|
||||||
if (resourceChanges.ram != null) methodsArr[idx].resources.ram = resourceChanges.ram;
|
|
||||||
if (resourceChanges.hdd != null) methodsArr[idx].resources.hdd = resourceChanges.hdd;
|
|
||||||
|
|
||||||
await patchInstallMethodsJson(methodsArr);
|
|
||||||
|
|
||||||
const changesLines = Object.entries(resourceChanges)
|
|
||||||
.map(function ([k, v]) { return '- `' + k + '` → `' + v + (k === 'ram' ? ' MB' : k === 'hdd' ? ' GB' : '') + '`'; })
|
|
||||||
.join('\n');
|
|
||||||
await addReaction('+1');
|
|
||||||
await postComment(
|
|
||||||
'✅ **PocketBase Bot**: Updated install method **`' + methodsArr[idx].type + '`** for **`' + slug + '`**\n\n' +
|
|
||||||
'**Changes applied:**\n' + changesLines + '\n\n' +
|
|
||||||
'*Executed by @' + actor + '*'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (setMatch) {
|
|
||||||
// ── SET SUBCOMMAND (multi-line / HTML / special chars via code block) ──
|
|
||||||
const fieldName = setMatch[1].toLowerCase();
|
|
||||||
const SET_ALLOWED = {
|
|
||||||
name: 'string', description: 'string', logo: 'string',
|
|
||||||
documentation: 'string', website: 'string', project_url: 'string', github: 'string',
|
|
||||||
config_path: 'string', disable_message: 'string', deleted_message: 'string'
|
|
||||||
};
|
|
||||||
if (!SET_ALLOWED[fieldName]) {
|
|
||||||
await addReaction('-1');
|
|
||||||
await postComment(
|
|
||||||
'❌ **PocketBase Bot**: `set` only supports text fields.\n\n' +
|
|
||||||
'**Allowed:** `' + Object.keys(SET_ALLOWED).join('`, `') + '`\n\n' +
|
|
||||||
'For boolean/number fields use `field=value` syntax instead.'
|
|
||||||
);
|
|
||||||
process.exit(0);
|
|
||||||
}
|
|
||||||
if (!codeBlockValue) {
|
|
||||||
await addReaction('-1');
|
|
||||||
await postComment(
|
|
||||||
'❌ **PocketBase Bot**: `set` requires a code block with the value.\n\n' +
|
|
||||||
'**Usage:**\n````\n/pocketbase ' + slug + ' set ' + fieldName + '\n```\nYour content here (HTML, multiline, special chars all fine)\n```\n````'
|
|
||||||
);
|
|
||||||
process.exit(0);
|
|
||||||
}
|
|
||||||
const setPayload = {};
|
|
||||||
setPayload[fieldName] = codeBlockValue;
|
|
||||||
const setPatchRes = await request(recordsUrl + '/' + record.id, {
|
|
||||||
method: 'PATCH',
|
|
||||||
headers: { 'Authorization': token, 'Content-Type': 'application/json' },
|
|
||||||
body: JSON.stringify(setPayload)
|
|
||||||
});
|
|
||||||
if (!setPatchRes.ok) {
|
|
||||||
await addReaction('-1');
|
|
||||||
await postComment('❌ **PocketBase Bot**: PATCH failed for `' + slug + '`:\n```\n' + setPatchRes.body + '\n```');
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
const preview = codeBlockValue.length > 300 ? codeBlockValue.substring(0, 300) + '…' : codeBlockValue;
|
|
||||||
await addReaction('+1');
|
|
||||||
await postComment(
|
|
||||||
'✅ **PocketBase Bot**: Set `' + fieldName + '` for **`' + slug + '`**\n\n' +
|
|
||||||
'**Value set:**\n```\n' + preview + '\n```\n\n' +
|
|
||||||
'*Executed by @' + actor + '*'
|
|
||||||
);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// ── FIELD=VALUE PATH ─────────────────────────────────────────────
|
|
||||||
const fieldsStr = rest;
|
|
||||||
|
|
||||||
// Skipped: slug, script_created/updated, created (auto), categories/
|
|
||||||
// install_methods/notes/type (relations), github_data/install_methods_json/
|
|
||||||
// notes_json (auto-generated), execute_in (select relation), last_update_commit (auto)
|
|
||||||
const ALLOWED_FIELDS = {
|
|
||||||
name: 'string',
|
|
||||||
description: 'string',
|
|
||||||
logo: 'string',
|
|
||||||
documentation: 'string',
|
|
||||||
website: 'string',
|
|
||||||
project_url: 'string',
|
|
||||||
github: 'string',
|
|
||||||
config_path: 'string',
|
|
||||||
port: 'number',
|
|
||||||
default_user: 'nullable_string',
|
|
||||||
default_passwd: 'nullable_string',
|
|
||||||
updateable: 'boolean',
|
|
||||||
privileged: 'boolean',
|
|
||||||
has_arm: 'boolean',
|
|
||||||
is_dev: 'boolean',
|
|
||||||
is_disabled: 'boolean',
|
|
||||||
disable_message: 'string',
|
|
||||||
is_deleted: 'boolean',
|
|
||||||
deleted_message: 'string',
|
|
||||||
version: 'string',
|
|
||||||
};
|
|
||||||
|
|
||||||
// Field=value parser (handles quoted values and empty=null)
|
|
||||||
function parseFields(str) {
|
|
||||||
const fields = {};
|
|
||||||
let pos = 0;
|
|
||||||
while (pos < str.length) {
|
|
||||||
while (pos < str.length && /\s/.test(str[pos])) pos++;
|
|
||||||
if (pos >= str.length) break;
|
|
||||||
let keyStart = pos;
|
|
||||||
while (pos < str.length && str[pos] !== '=' && !/\s/.test(str[pos])) pos++;
|
|
||||||
const key = str.substring(keyStart, pos).trim();
|
|
||||||
if (!key || pos >= str.length || str[pos] !== '=') { pos++; continue; }
|
|
||||||
pos++;
|
|
||||||
let value;
|
|
||||||
if (str[pos] === '"') {
|
|
||||||
pos++;
|
|
||||||
let valStart = pos;
|
|
||||||
while (pos < str.length && str[pos] !== '"') {
|
|
||||||
if (str[pos] === '\\') pos++;
|
|
||||||
pos++;
|
|
||||||
}
|
|
||||||
value = str.substring(valStart, pos).replace(/\\"/g, '"');
|
|
||||||
if (pos < str.length) pos++;
|
|
||||||
} else {
|
|
||||||
let valStart = pos;
|
|
||||||
while (pos < str.length && !/\s/.test(str[pos])) pos++;
|
|
||||||
value = str.substring(valStart, pos);
|
|
||||||
}
|
|
||||||
fields[key] = value;
|
|
||||||
}
|
|
||||||
return fields;
|
|
||||||
}
|
|
||||||
|
|
||||||
const parsedFields = parseFields(fieldsStr);
|
|
||||||
|
|
||||||
const unknownFields = Object.keys(parsedFields).filter(function (f) { return !ALLOWED_FIELDS[f]; });
|
|
||||||
if (unknownFields.length > 0) {
|
|
||||||
await addReaction('-1');
|
|
||||||
await postComment(
|
|
||||||
'❌ **PocketBase Bot**: Unknown field(s): `' + unknownFields.join('`, `') + '`\n\n' +
|
|
||||||
'**Allowed fields:** `' + Object.keys(ALLOWED_FIELDS).join('`, `') + '`'
|
|
||||||
);
|
|
||||||
process.exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Object.keys(parsedFields).length === 0) {
|
|
||||||
await addReaction('-1');
|
|
||||||
await postComment('❌ **PocketBase Bot**: Could not parse any valid `field=value` pairs.\n\n' + HELP_TEXT);
|
|
||||||
process.exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cast values to correct types
|
|
||||||
const payload = {};
|
|
||||||
for (const [key, rawVal] of Object.entries(parsedFields)) {
|
|
||||||
const type = ALLOWED_FIELDS[key];
|
|
||||||
if (type === 'boolean') {
|
|
||||||
if (rawVal === 'true') payload[key] = true;
|
|
||||||
else if (rawVal === 'false') payload[key] = false;
|
|
||||||
else {
|
|
||||||
await addReaction('-1');
|
|
||||||
await postComment('❌ **PocketBase Bot**: `' + key + '` must be `true` or `false`, got: `' + rawVal + '`');
|
|
||||||
process.exit(0);
|
|
||||||
}
|
|
||||||
} else if (type === 'number') {
|
|
||||||
const n = parseInt(rawVal, 10);
|
|
||||||
if (isNaN(n)) {
|
|
||||||
await addReaction('-1');
|
|
||||||
await postComment('❌ **PocketBase Bot**: `' + key + '` must be a number, got: `' + rawVal + '`');
|
|
||||||
process.exit(0);
|
|
||||||
}
|
|
||||||
payload[key] = n;
|
|
||||||
} else if (type === 'nullable_string') {
|
|
||||||
payload[key] = rawVal === '' ? null : rawVal;
|
|
||||||
} else {
|
|
||||||
payload[key] = rawVal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const patchRes = await request(recordsUrl + '/' + record.id, {
|
|
||||||
method: 'PATCH',
|
|
||||||
headers: { 'Authorization': token, 'Content-Type': 'application/json' },
|
|
||||||
body: JSON.stringify(payload)
|
|
||||||
});
|
|
||||||
if (!patchRes.ok) {
|
|
||||||
await addReaction('-1');
|
|
||||||
await postComment('❌ **PocketBase Bot**: PATCH failed for `' + slug + '`:\n```\n' + patchRes.body + '\n```');
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
await addReaction('+1');
|
|
||||||
const changesLines = Object.entries(payload)
|
|
||||||
.map(function ([k, v]) { return '- `' + k + '` → `' + JSON.stringify(v) + '`'; })
|
|
||||||
.join('\n');
|
|
||||||
await postComment(
|
|
||||||
'✅ **PocketBase Bot**: Updated **`' + slug + '`** successfully!\n\n' +
|
|
||||||
'**Changes applied:**\n' + changesLines + '\n\n' +
|
|
||||||
'*Executed by @' + actor + '*'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('Done.');
|
|
||||||
})().catch(function (e) {
|
|
||||||
console.error('Fatal error:', e.message || e);
|
|
||||||
process.exit(1);
|
|
||||||
});
|
|
||||||
ENDSCRIPT
|
|
||||||
shell: bash
|
|
||||||
39
.github/workflows/push-to-gitea.yml
generated
vendored
Normal file
39
.github/workflows/push-to-gitea.yml
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
name: Sync to Gitea
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
sync:
|
||||||
|
if: github.repository == 'community-scripts/ProxmoxVED'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout source repo
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- name: Set Git identity for actions
|
||||||
|
run: |
|
||||||
|
git config --global user.name "Push From Github"
|
||||||
|
git config --global user.email "actions@github.com"
|
||||||
|
- name: Add Gitea remote
|
||||||
|
run: git remote add gitea https://$GITEA_USER:$GITEA_TOKEN@git.community-scripts.org/community-scripts/ProxmoxVED.git
|
||||||
|
env:
|
||||||
|
GITEA_USER: ${{ secrets.GITEA_USERNAME }}
|
||||||
|
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||||
|
- name: Pull Gitea changes
|
||||||
|
run: |
|
||||||
|
git fetch gitea
|
||||||
|
git merge --strategy=ours gitea/main
|
||||||
|
env:
|
||||||
|
GITEA_USER: ${{ secrets.GITEA_USERNAME }}
|
||||||
|
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||||
|
|
||||||
|
- name: Push to Gitea
|
||||||
|
run: git push gitea main --force
|
||||||
|
env:
|
||||||
|
GITEA_USER: ${{ secrets.GITEA_USERNAME }}
|
||||||
|
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||||
160
.github/workflows/push_json_to_pocketbase.yml
generated
vendored
160
.github/workflows/push_json_to_pocketbase.yml
generated
vendored
@@ -5,13 +5,7 @@ on:
|
|||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
paths:
|
paths:
|
||||||
- "json/*.json"
|
- "frontend/public/json/**"
|
||||||
workflow_dispatch:
|
|
||||||
inputs:
|
|
||||||
script_slug:
|
|
||||||
description: "Script slug (e.g. my-app)"
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
push-json:
|
push-json:
|
||||||
@@ -22,55 +16,23 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Get JSON file for script
|
- name: Get changed JSON files with slug
|
||||||
id: changed
|
id: changed
|
||||||
run: |
|
run: |
|
||||||
: > changed_app_jsons.txt
|
changed=$(git diff --name-only "${{ github.event.before }}" "${{ github.event.after }}" -- frontend/public/json/ | grep '\.json$' || true)
|
||||||
|
with_slug=""
|
||||||
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
|
for f in $changed; do
|
||||||
script_slug="${{ github.event.inputs.script_slug }}"
|
[[ -f "$f" ]] || continue
|
||||||
file="json/${script_slug}.json"
|
jq -e '.slug' "$f" >/dev/null 2>&1 && with_slug="$with_slug $f"
|
||||||
if [[ ! -f "$file" ]]; then
|
|
||||||
echo "No JSON file at $file."
|
|
||||||
echo "count=0" >> "$GITHUB_OUTPUT"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
if ! jq -e '.slug' "$file" >/dev/null 2>&1; then
|
|
||||||
echo "File $file has no .slug."
|
|
||||||
echo "count=0" >> "$GITHUB_OUTPUT"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
echo "$file" > changed_app_jsons.txt
|
|
||||||
echo "count=1" >> "$GITHUB_OUTPUT"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
changed=$(git diff --name-only "${{ github.event.before }}" "${{ github.event.after }}" -- json/*.json || true)
|
|
||||||
if [[ -z "$changed" ]]; then
|
|
||||||
echo "No JSON files changed under json/*.json."
|
|
||||||
echo "count=0" >> "$GITHUB_OUTPUT"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
count=0
|
|
||||||
for file in $changed; do
|
|
||||||
[[ -f "$file" ]] || continue
|
|
||||||
if [[ "$file" == "json/metadata.json" || "$file" == "json/update-apps.json" || "$file" == "json/versions.json" ]]; then
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
if jq -e '.slug' "$file" >/dev/null 2>&1; then
|
|
||||||
echo "$file" >> changed_app_jsons.txt
|
|
||||||
count=$((count + 1))
|
|
||||||
fi
|
|
||||||
done
|
done
|
||||||
|
with_slug=$(echo $with_slug | xargs -n1)
|
||||||
if [[ $count -eq 0 ]]; then
|
if [[ -z "$with_slug" ]]; then
|
||||||
echo "No app JSON files with .slug found in this push."
|
echo "No app JSON files changed (or no files with slug)."
|
||||||
echo "count=0" >> "$GITHUB_OUTPUT"
|
echo "count=0" >> "$GITHUB_OUTPUT"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
echo "$with_slug" > changed_app_jsons.txt
|
||||||
echo "count=$count" >> "$GITHUB_OUTPUT"
|
echo "count=$(echo "$with_slug" | wc -w)" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
- name: Push to PocketBase
|
- name: Push to PocketBase
|
||||||
if: steps.changed.outputs.count != '0'
|
if: steps.changed.outputs.count != '0'
|
||||||
@@ -86,8 +48,7 @@ jobs:
|
|||||||
const https = require('https');
|
const https = require('https');
|
||||||
const http = require('http');
|
const http = require('http');
|
||||||
const url = require('url');
|
const url = require('url');
|
||||||
function request(fullUrl, opts, redirectCount) {
|
function request(fullUrl, opts) {
|
||||||
redirectCount = redirectCount || 0;
|
|
||||||
return new Promise(function(resolve, reject) {
|
return new Promise(function(resolve, reject) {
|
||||||
const u = url.parse(fullUrl);
|
const u = url.parse(fullUrl);
|
||||||
const isHttps = u.protocol === 'https:';
|
const isHttps = u.protocol === 'https:';
|
||||||
@@ -102,13 +63,6 @@ jobs:
|
|||||||
if (body) options.headers['Content-Length'] = Buffer.byteLength(body);
|
if (body) options.headers['Content-Length'] = Buffer.byteLength(body);
|
||||||
const lib = isHttps ? https : http;
|
const lib = isHttps ? https : http;
|
||||||
const req = lib.request(options, function(res) {
|
const req = lib.request(options, function(res) {
|
||||||
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
|
||||||
if (redirectCount >= 5) return reject(new Error('Too many redirects from ' + fullUrl));
|
|
||||||
const redirectUrl = url.resolve(fullUrl, res.headers.location);
|
|
||||||
res.resume();
|
|
||||||
resolve(request(redirectUrl, opts, redirectCount + 1));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let data = '';
|
let data = '';
|
||||||
res.on('data', function(chunk) { data += chunk; });
|
res.on('data', function(chunk) { data += chunk; });
|
||||||
res.on('end', function() {
|
res.on('end', function() {
|
||||||
@@ -142,7 +96,7 @@ jobs:
|
|||||||
const recordsUrl = apiBase + '/collections/' + encodeURIComponent(coll) + '/records';
|
const recordsUrl = apiBase + '/collections/' + encodeURIComponent(coll) + '/records';
|
||||||
let categoryIdToName = {};
|
let categoryIdToName = {};
|
||||||
try {
|
try {
|
||||||
const metadata = JSON.parse(fs.readFileSync('json/metadata.json', 'utf8'));
|
const metadata = JSON.parse(fs.readFileSync('frontend/public/json/metadata.json', 'utf8'));
|
||||||
(metadata.categories || []).forEach(function(cat) { categoryIdToName[cat.id] = cat.name; });
|
(metadata.categories || []).forEach(function(cat) { categoryIdToName[cat.id] = cat.name; });
|
||||||
} catch (e) { console.warn('Could not load metadata.json:', e.message); }
|
} catch (e) { console.warn('Could not load metadata.json:', e.message); }
|
||||||
let typeValueToId = {};
|
let typeValueToId = {};
|
||||||
@@ -171,32 +125,22 @@ jobs:
|
|||||||
var osVersionToId = {};
|
var osVersionToId = {};
|
||||||
try {
|
try {
|
||||||
const res = await request(apiBase + '/collections/z_ref_note_types/records?perPage=500', { headers: { 'Authorization': token } });
|
const res = await request(apiBase + '/collections/z_ref_note_types/records?perPage=500', { headers: { 'Authorization': token } });
|
||||||
if (res.ok) JSON.parse(res.body).items?.forEach(function(item) {
|
if (res.ok) JSON.parse(res.body).items?.forEach(function(item) { if (item.type != null) noteTypeToId[item.type] = item.id; });
|
||||||
if (item.type != null) { noteTypeToId[item.type] = item.id; noteTypeToId[item.type.toLowerCase()] = item.id; }
|
|
||||||
});
|
|
||||||
} catch (e) { console.warn('z_ref_note_types:', e.message); }
|
} catch (e) { console.warn('z_ref_note_types:', e.message); }
|
||||||
try {
|
try {
|
||||||
const res = await request(apiBase + '/collections/z_ref_install_method_types/records?perPage=500', { headers: { 'Authorization': token } });
|
const res = await request(apiBase + '/collections/z_ref_install_method_types/records?perPage=500', { headers: { 'Authorization': token } });
|
||||||
if (res.ok) JSON.parse(res.body).items?.forEach(function(item) {
|
if (res.ok) JSON.parse(res.body).items?.forEach(function(item) { if (item.type != null) installMethodTypeToId[item.type] = item.id; });
|
||||||
if (item.type != null) { installMethodTypeToId[item.type] = item.id; installMethodTypeToId[item.type.toLowerCase()] = item.id; }
|
|
||||||
});
|
|
||||||
} catch (e) { console.warn('z_ref_install_method_types:', e.message); }
|
} catch (e) { console.warn('z_ref_install_method_types:', e.message); }
|
||||||
try {
|
try {
|
||||||
const res = await request(apiBase + '/collections/z_ref_os/records?perPage=500', { headers: { 'Authorization': token } });
|
const res = await request(apiBase + '/collections/z_ref_os/records?perPage=500', { headers: { 'Authorization': token } });
|
||||||
if (res.ok) JSON.parse(res.body).items?.forEach(function(item) {
|
if (res.ok) JSON.parse(res.body).items?.forEach(function(item) { if (item.os != null) osToId[item.os] = item.id; });
|
||||||
if (item.os != null) { osToId[item.os] = item.id; osToId[item.os.toLowerCase()] = item.id; }
|
|
||||||
});
|
|
||||||
} catch (e) { console.warn('z_ref_os:', e.message); }
|
} catch (e) { console.warn('z_ref_os:', e.message); }
|
||||||
try {
|
try {
|
||||||
const res = await request(apiBase + '/collections/z_ref_os_version/records?perPage=500&expand=os', { headers: { 'Authorization': token } });
|
const res = await request(apiBase + '/collections/z_ref_os_version/records?perPage=500&expand=os', { headers: { 'Authorization': token } });
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
(JSON.parse(res.body).items || []).forEach(function(item) {
|
(JSON.parse(res.body).items || []).forEach(function(item) {
|
||||||
var osName = item.expand && item.expand.os && item.expand.os.os != null ? item.expand.os.os : null;
|
var osName = item.expand && item.expand.os && item.expand.os.os != null ? item.expand.os.os : null;
|
||||||
if (osName != null && item.version != null) {
|
if (osName != null && item.version != null) osVersionToId[osName + '|' + item.version] = item.id;
|
||||||
var key = osName + '|' + item.version;
|
|
||||||
osVersionToId[key] = item.id;
|
|
||||||
osVersionToId[osName.toLowerCase() + '|' + item.version] = item.id;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch (e) { console.warn('z_ref_os_version:', e.message); }
|
} catch (e) { console.warn('z_ref_os_version:', e.message); }
|
||||||
@@ -206,40 +150,11 @@ jobs:
|
|||||||
if (!fs.existsSync(file)) continue;
|
if (!fs.existsSync(file)) continue;
|
||||||
const data = JSON.parse(fs.readFileSync(file, 'utf8'));
|
const data = JSON.parse(fs.readFileSync(file, 'utf8'));
|
||||||
if (!data.slug) { console.log('Skipping', file, '(no slug)'); continue; }
|
if (!data.slug) { console.log('Skipping', file, '(no slug)'); continue; }
|
||||||
// execute_in: map type to canonical value (addon runs on both lxc and vm)
|
|
||||||
var executeInMap = { ct: 'lxc', lxc: 'lxc', turnkey: 'turnkey', pve: 'pve', vm: 'vm', addon: ['lxc', 'vm'] };
|
|
||||||
var executeIn = data.type ? (executeInMap[data.type.toLowerCase()] || null) : null;
|
|
||||||
// github: extract owner/repo from full GitHub URL
|
|
||||||
var githubField = null;
|
|
||||||
var projectUrl = data.github || null;
|
|
||||||
if (data.github) {
|
|
||||||
var ghMatch = data.github.match(/github\.com\/([^/]+\/[^/?#]+)/);
|
|
||||||
if (ghMatch) githubField = ghMatch[1].replace(/\.git$/, '');
|
|
||||||
}
|
|
||||||
// last_update_commit: last commit touching the actual script files (ct/slug.sh, install/slug-install.sh, vm/slug.sh, etc.)
|
|
||||||
var lastCommit = null;
|
|
||||||
try {
|
|
||||||
var cp = require('child_process');
|
|
||||||
var scriptFiles = [];
|
|
||||||
// primary script from install_methods[].script (e.g. "ct/teleport.sh", "vm/teleport.sh")
|
|
||||||
(data.install_methods || []).forEach(function(im) {
|
|
||||||
if (im.script) scriptFiles.push(im.script);
|
|
||||||
});
|
|
||||||
// derive install script from slug (install/slug-install.sh)
|
|
||||||
scriptFiles.push('install/' + data.slug + '-install.sh');
|
|
||||||
// filter to only files that actually exist in git
|
|
||||||
var existingFiles = scriptFiles.filter(function(f) {
|
|
||||||
try { cp.execSync('git ls-files --error-unmatch ' + f, { stdio: 'ignore' }); return true; } catch(e) { return false; }
|
|
||||||
});
|
|
||||||
if (existingFiles.length > 0) {
|
|
||||||
lastCommit = cp.execSync('git log -1 --format=%H -- ' + existingFiles.join(' ')).toString().trim() || null;
|
|
||||||
}
|
|
||||||
} catch(e) { console.warn('Could not get last commit:', e.message); }
|
|
||||||
var payload = {
|
var payload = {
|
||||||
name: data.name,
|
name: data.name,
|
||||||
slug: data.slug,
|
slug: data.slug,
|
||||||
script_created: data.date_created || data.script_created,
|
script_created: data.date_created || data.script_created,
|
||||||
script_updated: new Date().toISOString().split('T')[0],
|
script_updated: data.date_created || data.script_updated,
|
||||||
updateable: data.updateable,
|
updateable: data.updateable,
|
||||||
privileged: data.privileged,
|
privileged: data.privileged,
|
||||||
port: data.interface_port != null ? data.interface_port : data.port,
|
port: data.interface_port != null ? data.interface_port : data.port,
|
||||||
@@ -248,16 +163,10 @@ jobs:
|
|||||||
logo: data.logo,
|
logo: data.logo,
|
||||||
description: data.description,
|
description: data.description,
|
||||||
config_path: data.config_path,
|
config_path: data.config_path,
|
||||||
default_user: (data.default_credentials && data.default_credentials.username) || data.default_user || null,
|
default_user: (data.default_credentials && data.default_credentials.username) || data.default_user,
|
||||||
default_passwd: (data.default_credentials && data.default_credentials.password) || data.default_passwd || null,
|
default_passwd: (data.default_credentials && data.default_credentials.password) || data.default_passwd,
|
||||||
notes_json: JSON.stringify(data.notes || []),
|
|
||||||
install_methods_json: JSON.stringify(data.install_methods || []),
|
|
||||||
is_dev: true
|
is_dev: true
|
||||||
};
|
};
|
||||||
if (executeIn) payload.execute_in = executeIn;
|
|
||||||
if (githubField) payload.github = githubField;
|
|
||||||
if (projectUrl) payload.project_url = projectUrl;
|
|
||||||
if (lastCommit) payload.last_update_commit = lastCommit;
|
|
||||||
var resolvedType = typeValueToId[data.type];
|
var resolvedType = typeValueToId[data.type];
|
||||||
if (resolvedType == null && data.type === 'ct') resolvedType = typeValueToId['lxc'];
|
if (resolvedType == null && data.type === 'ct') resolvedType = typeValueToId['lxc'];
|
||||||
if (resolvedType) payload.type = resolvedType;
|
if (resolvedType) payload.type = resolvedType;
|
||||||
@@ -276,27 +185,23 @@ jobs:
|
|||||||
var noteIds = [];
|
var noteIds = [];
|
||||||
for (var i = 0; i < (data.notes || []).length; i++) {
|
for (var i = 0; i < (data.notes || []).length; i++) {
|
||||||
var note = data.notes[i];
|
var note = data.notes[i];
|
||||||
var typeId = noteTypeToId[note.type] || (note.type && noteTypeToId[note.type.toLowerCase()]);
|
var typeId = noteTypeToId[note.type];
|
||||||
if (typeId == null) {
|
if (typeId == null) continue;
|
||||||
console.warn('Note type not in z_ref_note_types:', note.type);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
var postRes = await request(notesCollUrl, {
|
var postRes = await request(notesCollUrl, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'Authorization': token, 'Content-Type': 'application/json' },
|
headers: { 'Authorization': token, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ text: note.text || '', type: typeId, script: scriptId })
|
body: JSON.stringify({ text: note.text || '', type: typeId })
|
||||||
});
|
});
|
||||||
if (postRes.ok) noteIds.push(JSON.parse(postRes.body).id);
|
if (postRes.ok) noteIds.push(JSON.parse(postRes.body).id);
|
||||||
else console.error('script_notes POST failed:', postRes.statusCode, postRes.body);
|
|
||||||
}
|
}
|
||||||
var installMethodIds = [];
|
var installMethodIds = [];
|
||||||
for (var j = 0; j < (data.install_methods || []).length; j++) {
|
for (var j = 0; j < (data.install_methods || []).length; j++) {
|
||||||
var im = data.install_methods[j];
|
var im = data.install_methods[j];
|
||||||
var typeId = installMethodTypeToId[im.type] || (im.type && installMethodTypeToId[im.type.toLowerCase()]);
|
var typeId = installMethodTypeToId[im.type];
|
||||||
var res = im.resources || {};
|
var res = im.resources || {};
|
||||||
var osId = osToId[res.os] || (res.os && osToId[res.os.toLowerCase()]);
|
var osId = osToId[res.os];
|
||||||
var osVersionKey = (res.os != null && res.version != null) ? res.os + '|' + res.version : null;
|
var osVersionKey = (res.os != null && res.version != null) ? res.os + '|' + res.version : null;
|
||||||
var osVersionId = osVersionKey ? (osVersionToId[osVersionKey] || osVersionToId[res.os.toLowerCase() + '|' + res.version]) : null;
|
var osVersionId = osVersionKey ? osVersionToId[osVersionKey] : null;
|
||||||
var imBody = {
|
var imBody = {
|
||||||
script: scriptId,
|
script: scriptId,
|
||||||
resources_cpu: res.cpu != null ? res.cpu : 0,
|
resources_cpu: res.cpu != null ? res.cpu : 0,
|
||||||
@@ -312,7 +217,6 @@ jobs:
|
|||||||
body: JSON.stringify(imBody)
|
body: JSON.stringify(imBody)
|
||||||
});
|
});
|
||||||
if (imPostRes.ok) installMethodIds.push(JSON.parse(imPostRes.body).id);
|
if (imPostRes.ok) installMethodIds.push(JSON.parse(imPostRes.body).id);
|
||||||
else console.error('script_install_methods POST failed:', imPostRes.statusCode, imPostRes.body);
|
|
||||||
}
|
}
|
||||||
return { noteIds: noteIds, installMethodIds: installMethodIds };
|
return { noteIds: noteIds, installMethodIds: installMethodIds };
|
||||||
}
|
}
|
||||||
@@ -321,7 +225,6 @@ jobs:
|
|||||||
payload.notes = resolved.noteIds;
|
payload.notes = resolved.noteIds;
|
||||||
payload.install_methods = resolved.installMethodIds;
|
payload.install_methods = resolved.installMethodIds;
|
||||||
console.log('Updating', file, '(slug=' + data.slug + ')');
|
console.log('Updating', file, '(slug=' + data.slug + ')');
|
||||||
console.log('Created', resolved.noteIds.length, 'notes,', resolved.installMethodIds.length, 'install_methods for slug=' + data.slug);
|
|
||||||
const r = await request(recordsUrl + '/' + existingId, {
|
const r = await request(recordsUrl + '/' + existingId, {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: { 'Authorization': token, 'Content-Type': 'application/json' },
|
headers: { 'Authorization': token, 'Content-Type': 'application/json' },
|
||||||
@@ -338,19 +241,12 @@ jobs:
|
|||||||
if (!r.ok) throw new Error('POST failed: ' + r.body);
|
if (!r.ok) throw new Error('POST failed: ' + r.body);
|
||||||
var scriptId = JSON.parse(r.body).id;
|
var scriptId = JSON.parse(r.body).id;
|
||||||
var resolved = await resolveNotesAndInstallMethods(scriptId);
|
var resolved = await resolveNotesAndInstallMethods(scriptId);
|
||||||
console.log('Created', resolved.noteIds.length, 'notes,', resolved.installMethodIds.length, 'install_methods for slug=' + data.slug);
|
|
||||||
var patchPayload = {};
|
|
||||||
for (var k in payload) patchPayload[k] = payload[k];
|
|
||||||
patchPayload.notes = resolved.noteIds;
|
|
||||||
patchPayload.install_methods = resolved.installMethodIds;
|
|
||||||
var patchRes = await request(recordsUrl + '/' + scriptId, {
|
var patchRes = await request(recordsUrl + '/' + scriptId, {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: { 'Authorization': token, 'Content-Type': 'application/json' },
|
headers: { 'Authorization': token, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify(patchPayload)
|
body: JSON.stringify({ install_methods: resolved.installMethodIds, notes: resolved.noteIds })
|
||||||
});
|
});
|
||||||
if (!patchRes.ok) throw new Error('PATCH relations failed: ' + patchRes.body);
|
if (!patchRes.ok) throw new Error('PATCH relations failed: ' + patchRes.body);
|
||||||
var patched = JSON.parse(patchRes.body);
|
|
||||||
console.log('Script linked: notes=' + (patched.notes && patched.notes.length) + ', install_methods=' + (patched.install_methods && patched.install_methods.length));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log('Done.');
|
console.log('Done.');
|
||||||
|
|||||||
2
.github/workflows/scripts/get-gh-release.sh
generated
vendored
2
.github/workflows/scripts/get-gh-release.sh
generated
vendored
@@ -1,7 +1,7 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
INPUT_FILE=".github/workflows/scripts/repos.txt"
|
INPUT_FILE=".github/workflows/scripts/repos.txt"
|
||||||
OUTPUT_FILE="json/versions.json"
|
OUTPUT_FILE="frontend/public/json/versions.json"
|
||||||
TMP_FILE="releases_tmp.json"
|
TMP_FILE="releases_tmp.json"
|
||||||
|
|
||||||
if [ -f "$OUTPUT_FILE" ]; then
|
if [ -f "$OUTPUT_FILE" ]; then
|
||||||
|
|||||||
81
.github/workflows/stale_pr_close.yml
generated
vendored
81
.github/workflows/stale_pr_close.yml
generated
vendored
@@ -22,7 +22,7 @@ jobs:
|
|||||||
const now = new Date();
|
const now = new Date();
|
||||||
const owner = context.repo.owner;
|
const owner = context.repo.owner;
|
||||||
const repo = context.repo.repo;
|
const repo = context.repo.repo;
|
||||||
|
|
||||||
// --- When stale label is added, comment immediately ---
|
// --- When stale label is added, comment immediately ---
|
||||||
if (context.eventName === "pull_request_target" && context.payload.action === "labeled") {
|
if (context.eventName === "pull_request_target" && context.payload.action === "labeled") {
|
||||||
const label = context.payload.label?.name;
|
const label = context.payload.label?.name;
|
||||||
@@ -37,74 +37,19 @@ jobs:
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Scheduled run: fetch all open PRs ---
|
// --- Scheduled run: check all stale PRs ---
|
||||||
const { data: prs } = await github.rest.pulls.list({
|
const { data: prs } = await github.rest.pulls.list({
|
||||||
owner,
|
owner,
|
||||||
repo,
|
repo,
|
||||||
state: "open",
|
state: "open",
|
||||||
per_page: 100
|
per_page: 100
|
||||||
});
|
});
|
||||||
|
|
||||||
for (const pr of prs) {
|
for (const pr of prs) {
|
||||||
const labels = pr.labels.map(l => l.name);
|
const hasStale = pr.labels.some(l => l.name === "stale");
|
||||||
const hasStale = labels.includes("stale");
|
if (!hasStale) continue;
|
||||||
const hasKeepOpen = labels.includes("keep-open");
|
|
||||||
|
|
||||||
// -------------------------------------------------------
|
|
||||||
// NEW: Auto-label PRs with no activity in the last 14 days
|
|
||||||
// -------------------------------------------------------
|
|
||||||
if (!hasStale && !hasKeepOpen) {
|
|
||||||
// Find the most recent commit date
|
|
||||||
const { data: commits } = await github.rest.pulls.listCommits({
|
|
||||||
owner,
|
|
||||||
repo,
|
|
||||||
pull_number: pr.number
|
|
||||||
});
|
|
||||||
const lastCommitDate = commits.length > 0
|
|
||||||
? new Date(commits[commits.length - 1].commit.author.date)
|
|
||||||
: new Date(pr.created_at);
|
|
||||||
|
|
||||||
// Find the most recent non-bot comment date
|
|
||||||
const { data: comments } = await github.rest.issues.listComments({
|
|
||||||
owner,
|
|
||||||
repo,
|
|
||||||
issue_number: pr.number,
|
|
||||||
per_page: 100
|
|
||||||
});
|
|
||||||
const humanComments = comments.filter(c => c.user?.type !== "Bot");
|
|
||||||
const lastCommentDate = humanComments.length > 0
|
|
||||||
? new Date(humanComments[humanComments.length - 1].created_at)
|
|
||||||
: null;
|
|
||||||
|
|
||||||
// Most recent activity across commits and comments
|
|
||||||
const lastActivityDate = lastCommentDate && lastCommentDate > lastCommitDate
|
|
||||||
? lastCommentDate
|
|
||||||
: lastCommitDate;
|
|
||||||
|
|
||||||
const daysSinceActivity = (now - lastActivityDate) / (1000 * 60 * 60 * 24);
|
|
||||||
|
|
||||||
if (daysSinceActivity > 14) {
|
|
||||||
await github.rest.issues.addLabels({
|
|
||||||
owner,
|
|
||||||
repo,
|
|
||||||
issue_number: pr.number,
|
|
||||||
labels: ["stale"]
|
|
||||||
});
|
|
||||||
// The pull_request_target labeled event will fire the comment automatically.
|
|
||||||
// Skip further processing for this PR in this run.
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Not stale, nothing else to do for this PR.
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------------------
|
|
||||||
// EXISTING: Manage already-stale PRs
|
|
||||||
// -------------------------------------------------------
|
|
||||||
if (!hasStale) continue; // has keep-open but not stale — skip
|
|
||||||
|
|
||||||
// Get timeline events to find when stale label was added
|
// Get timeline events to find when stale label was added
|
||||||
const { data: events } = await github.rest.issues.listEvents({
|
const { data: events } = await github.rest.issues.listEvents({
|
||||||
owner,
|
owner,
|
||||||
@@ -112,27 +57,27 @@ jobs:
|
|||||||
issue_number: pr.number,
|
issue_number: pr.number,
|
||||||
per_page: 100
|
per_page: 100
|
||||||
});
|
});
|
||||||
|
|
||||||
// Find the most recent time the stale label was added
|
// Find the most recent time the stale label was added
|
||||||
const staleLabelEvents = events
|
const staleLabelEvents = events
|
||||||
.filter(e => e.event === "labeled" && e.label?.name === "stale")
|
.filter(e => e.event === "labeled" && e.label?.name === "stale")
|
||||||
.sort((a, b) => new Date(b.created_at) - new Date(a.created_at));
|
.sort((a, b) => new Date(b.created_at) - new Date(a.created_at));
|
||||||
|
|
||||||
if (staleLabelEvents.length === 0) continue;
|
if (staleLabelEvents.length === 0) continue;
|
||||||
|
|
||||||
const staleLabelDate = new Date(staleLabelEvents[0].created_at);
|
const staleLabelDate = new Date(staleLabelEvents[0].created_at);
|
||||||
const daysSinceStale = (now - staleLabelDate) / (1000 * 60 * 60 * 24);
|
const daysSinceStale = (now - staleLabelDate) / (1000 * 60 * 60 * 24);
|
||||||
|
|
||||||
// Check for new commits since stale label was added
|
// Check for new commits since stale label was added
|
||||||
const { data: commits } = await github.rest.pulls.listCommits({
|
const { data: commits } = await github.rest.pulls.listCommits({
|
||||||
owner,
|
owner,
|
||||||
repo,
|
repo,
|
||||||
pull_number: pr.number
|
pull_number: pr.number
|
||||||
});
|
});
|
||||||
|
|
||||||
const lastCommitDate = new Date(commits[commits.length - 1].commit.author.date);
|
const lastCommitDate = new Date(commits[commits.length - 1].commit.author.date);
|
||||||
const author = pr.user.login;
|
const author = pr.user.login;
|
||||||
|
|
||||||
// If there are new commits after the stale label, remove it
|
// If there are new commits after the stale label, remove it
|
||||||
if (lastCommitDate > staleLabelDate) {
|
if (lastCommitDate > staleLabelDate) {
|
||||||
await github.rest.issues.removeLabel({
|
await github.rest.issues.removeLabel({
|
||||||
|
|||||||
41
.github/workflows/trigger_github_pages_redirect.yml
generated
vendored
41
.github/workflows/trigger_github_pages_redirect.yml
generated
vendored
@@ -1,41 +0,0 @@
|
|||||||
name: Pages Redirect
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
pages: write
|
|
||||||
id-token: write
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
deploy:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Create redirect page
|
|
||||||
run: |
|
|
||||||
mkdir site
|
|
||||||
cat <<EOF > site/index.html
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta http-equiv="refresh" content="0; url=https://community-scripts.org/">
|
|
||||||
<link rel="canonical" href="https://community-scripts.org/">
|
|
||||||
<title>Redirecting...</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
Redirecting...
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
EOF
|
|
||||||
|
|
||||||
- uses: actions/upload-pages-artifact@v3
|
|
||||||
with:
|
|
||||||
path: site
|
|
||||||
|
|
||||||
- name: Deploy
|
|
||||||
uses: actions/deploy-pages@v4
|
|
||||||
89
.github/workflows/unmet-pr-close.yml
generated
vendored
89
.github/workflows/unmet-pr-close.yml
generated
vendored
@@ -1,89 +0,0 @@
|
|||||||
name: PR Script Requirements Check
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
types: [opened, edited, synchronize]
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
pull-requests: write
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
validate-script-requirements:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Validate new script requirements
|
|
||||||
uses: actions/github-script@v7
|
|
||||||
with:
|
|
||||||
script: |
|
|
||||||
const body = context.payload.pull_request.body || "";
|
|
||||||
const lines = body.split("\n");
|
|
||||||
|
|
||||||
function checkboxChecked(line) {
|
|
||||||
return /\[\s*x\s*\]/i.test(line);
|
|
||||||
}
|
|
||||||
|
|
||||||
function findLine(text) {
|
|
||||||
return lines.find(l => l.includes(text));
|
|
||||||
}
|
|
||||||
|
|
||||||
// detect if "New script" is checked
|
|
||||||
const newScriptLine = findLine("🆕 **New script**");
|
|
||||||
if (!newScriptLine || !checkboxChecked(newScriptLine)) {
|
|
||||||
console.log("Not a new script PR — skipping requirement check.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const requirements = [
|
|
||||||
"The application is **at least 6 months old**",
|
|
||||||
"The application is **actively maintained**",
|
|
||||||
"The application has **600+ GitHub stars**",
|
|
||||||
"Official **release tarballs** are published",
|
|
||||||
"I understand that not all scripts will be accepted"
|
|
||||||
];
|
|
||||||
|
|
||||||
const missing = [];
|
|
||||||
|
|
||||||
for (const req of requirements) {
|
|
||||||
const line = findLine(req);
|
|
||||||
if (!line || !checkboxChecked(line)) {
|
|
||||||
missing.push(req);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (missing.length > 0) {
|
|
||||||
|
|
||||||
let list = "";
|
|
||||||
for (const m of missing) {
|
|
||||||
list += "- " + m + "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
const message =
|
|
||||||
"❌ **Pull Request Closed – Application Requirements Not Met**\n\n" +
|
|
||||||
"This pull request is marked as **🆕 New script**, but the required application criteria were not confirmed.\n\n" +
|
|
||||||
"The following requirement confirmations are missing:\n\n" +
|
|
||||||
list +
|
|
||||||
"\nNew application submissions must meet the project requirements before being considered.\n" +
|
|
||||||
"Please wait until the application satisfies the criteria before submitting a new PR.\n\n" +
|
|
||||||
"---\n\n" +
|
|
||||||
"⚠ **Maintainer note**\n\n" +
|
|
||||||
"The team periodically reviews closed submissions. If a project is still considered valuable to the ecosystem, maintainers may reopen the PR even if it does not fully meet the thresholds.\n\n" +
|
|
||||||
"**Please do not ping or repeatedly contact maintainers to reopen PRs.**";
|
|
||||||
|
|
||||||
await github.rest.issues.createComment({
|
|
||||||
owner: context.repo.owner,
|
|
||||||
repo: context.repo.repo,
|
|
||||||
issue_number: context.issue.number,
|
|
||||||
body: message
|
|
||||||
});
|
|
||||||
|
|
||||||
await github.rest.pulls.update({
|
|
||||||
owner: context.repo.owner,
|
|
||||||
repo: context.repo.repo,
|
|
||||||
pull_number: context.issue.number,
|
|
||||||
state: "closed"
|
|
||||||
});
|
|
||||||
|
|
||||||
core.setFailed("Application requirements checklist incomplete.");
|
|
||||||
}
|
|
||||||
218
.github/workflows/update-github-versions.yml
generated
vendored
Normal file
218
.github/workflows/update-github-versions.yml
generated
vendored
Normal file
@@ -0,0 +1,218 @@
|
|||||||
|
name: Update GitHub Versions (New)
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
schedule:
|
||||||
|
# Runs 4x daily: 00:00, 06:00, 12:00, 18:00 UTC
|
||||||
|
- cron: "0 0,6,12,18 * * *"
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
|
env:
|
||||||
|
VERSIONS_FILE: frontend/public/json/github-versions.json
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
update-github-versions:
|
||||||
|
if: github.repository == 'community-scripts/ProxmoxVED'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout Repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: main
|
||||||
|
|
||||||
|
- name: Extract GitHub versions from install scripts
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
echo "========================================="
|
||||||
|
echo " Extracting GitHub versions from scripts"
|
||||||
|
echo "========================================="
|
||||||
|
|
||||||
|
# Initialize versions array
|
||||||
|
versions_json="[]"
|
||||||
|
|
||||||
|
# Function to add a version entry
|
||||||
|
add_version() {
|
||||||
|
local slug="$1"
|
||||||
|
local repo="$2"
|
||||||
|
local version="$3"
|
||||||
|
local pinned="$4"
|
||||||
|
local date="$5"
|
||||||
|
|
||||||
|
versions_json=$(echo "$versions_json" | jq \
|
||||||
|
--arg slug "$slug" \
|
||||||
|
--arg repo "$repo" \
|
||||||
|
--arg version "$version" \
|
||||||
|
--argjson pinned "$pinned" \
|
||||||
|
--arg date "$date" \
|
||||||
|
'. += [{"slug": $slug, "repo": $repo, "version": $version, "pinned": $pinned, "date": $date}]')
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get list of slugs from JSON files
|
||||||
|
echo ""
|
||||||
|
echo "=== Scanning JSON files for slugs ==="
|
||||||
|
|
||||||
|
for json_file in frontend/public/json/*.json; do
|
||||||
|
[[ ! -f "$json_file" ]] && continue
|
||||||
|
|
||||||
|
# Skip non-app JSON files
|
||||||
|
basename_file=$(basename "$json_file")
|
||||||
|
case "$basename_file" in
|
||||||
|
metadata.json|versions.json|github-versions.json|dependency-check.json|update-apps.json)
|
||||||
|
continue
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Extract slug from JSON
|
||||||
|
slug=$(jq -r '.slug // empty' "$json_file" 2>/dev/null)
|
||||||
|
[[ -z "$slug" ]] && continue
|
||||||
|
|
||||||
|
# Find corresponding install script
|
||||||
|
install_script="install/${slug}-install.sh"
|
||||||
|
[[ ! -f "$install_script" ]] && continue
|
||||||
|
|
||||||
|
# Look for fetch_and_deploy_gh_release calls
|
||||||
|
# Pattern: fetch_and_deploy_gh_release "app" "owner/repo" ["mode"] ["version"]
|
||||||
|
while IFS= read -r line; do
|
||||||
|
# Skip commented lines
|
||||||
|
[[ "$line" =~ ^[[:space:]]*# ]] && continue
|
||||||
|
|
||||||
|
# Extract repo and version from fetch_and_deploy_gh_release
|
||||||
|
if [[ "$line" =~ fetch_and_deploy_gh_release[[:space:]]+\"[^\"]*\"[[:space:]]+\"([^\"]+)\"([[:space:]]+\"([^\"]+)\")?([[:space:]]+\"([^\"]+)\")? ]]; then
|
||||||
|
repo="${BASH_REMATCH[1]}"
|
||||||
|
mode="${BASH_REMATCH[3]:-tarball}"
|
||||||
|
pinned_version="${BASH_REMATCH[5]:-latest}"
|
||||||
|
|
||||||
|
# Check if version is pinned (not "latest" and not empty)
|
||||||
|
is_pinned=false
|
||||||
|
target_version=""
|
||||||
|
|
||||||
|
if [[ -n "$pinned_version" && "$pinned_version" != "latest" ]]; then
|
||||||
|
is_pinned=true
|
||||||
|
target_version="$pinned_version"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Fetch version from GitHub
|
||||||
|
if [[ "$is_pinned" == "true" ]]; then
|
||||||
|
# For pinned versions, verify it exists and get date
|
||||||
|
response=$(gh api "repos/${repo}/releases/tags/${target_version}" 2>/dev/null || echo '{}')
|
||||||
|
if echo "$response" | jq -e '.tag_name' > /dev/null 2>&1; then
|
||||||
|
version=$(echo "$response" | jq -r '.tag_name')
|
||||||
|
date=$(echo "$response" | jq -r '.published_at // empty')
|
||||||
|
add_version "$slug" "$repo" "$version" "true" "$date"
|
||||||
|
echo "[$slug] ✓ $version (pinned)"
|
||||||
|
else
|
||||||
|
echo "[$slug] ⚠ pinned version $target_version not found"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
# Fetch latest release
|
||||||
|
response=$(gh api "repos/${repo}/releases/latest" 2>/dev/null || echo '{}')
|
||||||
|
if echo "$response" | jq -e '.tag_name' > /dev/null 2>&1; then
|
||||||
|
version=$(echo "$response" | jq -r '.tag_name')
|
||||||
|
date=$(echo "$response" | jq -r '.published_at // empty')
|
||||||
|
add_version "$slug" "$repo" "$version" "false" "$date"
|
||||||
|
echo "[$slug] ✓ $version"
|
||||||
|
else
|
||||||
|
# Try tags as fallback
|
||||||
|
version=$(gh api "repos/${repo}/tags" --jq '.[0].name // empty' 2>/dev/null || echo "")
|
||||||
|
if [[ -n "$version" ]]; then
|
||||||
|
add_version "$slug" "$repo" "$version" "false" ""
|
||||||
|
echo "[$slug] ✓ $version (from tags)"
|
||||||
|
else
|
||||||
|
echo "[$slug] ⚠ no version found"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
break # Only first match per script
|
||||||
|
fi
|
||||||
|
done < <(grep 'fetch_and_deploy_gh_release' "$install_script" 2>/dev/null || true)
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
# Save versions file
|
||||||
|
echo "$versions_json" | jq --arg date "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
|
||||||
|
'{generated: $date, versions: (. | sort_by(.slug))}' > "$VERSIONS_FILE"
|
||||||
|
|
||||||
|
total=$(echo "$versions_json" | jq 'length')
|
||||||
|
echo ""
|
||||||
|
echo "========================================="
|
||||||
|
echo " Total versions extracted: $total"
|
||||||
|
echo "========================================="
|
||||||
|
|
||||||
|
- name: Check for changes
|
||||||
|
id: check-changes
|
||||||
|
run: |
|
||||||
|
# Check if file is new (untracked) or has changes
|
||||||
|
if [[ ! -f "$VERSIONS_FILE" ]]; then
|
||||||
|
echo "changed=false" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "Versions file was not created"
|
||||||
|
elif ! git ls-files --error-unmatch "$VERSIONS_FILE" &>/dev/null; then
|
||||||
|
# File exists but is not tracked - it's new
|
||||||
|
echo "changed=true" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "New file created: $VERSIONS_FILE"
|
||||||
|
elif git diff --quiet "$VERSIONS_FILE" 2>/dev/null; then
|
||||||
|
echo "changed=false" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "No changes detected"
|
||||||
|
else
|
||||||
|
echo "changed=true" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "Changes detected:"
|
||||||
|
git diff --stat "$VERSIONS_FILE" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Create Pull Request
|
||||||
|
if: steps.check-changes.outputs.changed == 'true'
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
run: |
|
||||||
|
BRANCH_NAME="automated/update-github-versions-$(date +%Y%m%d)"
|
||||||
|
|
||||||
|
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||||||
|
git config --global user.name "GitHub Actions[bot]"
|
||||||
|
|
||||||
|
# Check if branch exists and delete it
|
||||||
|
git push origin --delete "$BRANCH_NAME" 2>/dev/null || true
|
||||||
|
|
||||||
|
git checkout -b "$BRANCH_NAME"
|
||||||
|
git add "$VERSIONS_FILE"
|
||||||
|
git commit -m "chore: update github-versions.json
|
||||||
|
|
||||||
|
Total versions: $(jq '.versions | length' "$VERSIONS_FILE")
|
||||||
|
Pinned versions: $(jq '[.versions[] | select(.pinned == true)] | length' "$VERSIONS_FILE")
|
||||||
|
Generated: $(jq -r '.generated' "$VERSIONS_FILE")"
|
||||||
|
|
||||||
|
git push origin "$BRANCH_NAME" --force
|
||||||
|
|
||||||
|
# Check if PR already exists
|
||||||
|
existing_pr=$(gh pr list --head "$BRANCH_NAME" --state open --json number --jq '.[0].number // empty')
|
||||||
|
|
||||||
|
if [[ -n "$existing_pr" ]]; then
|
||||||
|
echo "PR #$existing_pr already exists, updating..."
|
||||||
|
else
|
||||||
|
gh pr create \
|
||||||
|
--title "[Automated] Update GitHub versions" \
|
||||||
|
--body "This PR updates version information from GitHub releases.
|
||||||
|
|
||||||
|
## How it works
|
||||||
|
1. Scans all JSON files in \`frontend/public/json/\` for slugs
|
||||||
|
2. Finds corresponding \`install/{slug}-install.sh\` scripts
|
||||||
|
3. Extracts \`fetch_and_deploy_gh_release\` calls
|
||||||
|
4. Fetches latest (or pinned) version from GitHub
|
||||||
|
|
||||||
|
## Stats
|
||||||
|
- Total versions: $(jq '.versions | length' "$VERSIONS_FILE")
|
||||||
|
- Pinned versions: $(jq '[.versions[] | select(.pinned == true)] | length' "$VERSIONS_FILE")
|
||||||
|
- Latest versions: $(jq '[.versions[] | select(.pinned == false)] | length' "$VERSIONS_FILE")
|
||||||
|
|
||||||
|
---
|
||||||
|
*Automatically generated from install scripts*" \
|
||||||
|
--base main \
|
||||||
|
--head "$BRANCH_NAME" \
|
||||||
|
--label "automated pr"
|
||||||
|
fi
|
||||||
175
.github/workflows/update-timestamp-on-db.yml
generated
vendored
175
.github/workflows/update-timestamp-on-db.yml
generated
vendored
@@ -1,175 +0,0 @@
|
|||||||
name: Update script timestamp on .sh changes
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
paths:
|
|
||||||
- "ct/**/*.sh"
|
|
||||||
- "install/**/*.sh"
|
|
||||||
- "tools/**/*.sh"
|
|
||||||
- "turnkey/**/*.sh"
|
|
||||||
- "vm/**/*.sh"
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
update-script-timestamp:
|
|
||||||
runs-on: self-hosted
|
|
||||||
steps:
|
|
||||||
- name: Checkout Repository
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Get changed .sh files and derive slugs
|
|
||||||
id: slugs
|
|
||||||
run: |
|
|
||||||
changed=$(git diff --name-only "${{ github.event.before }}" "${{ github.event.after }}" -- ct/ install/ tools/ turnkey/ vm/ | grep '\.sh$' || true)
|
|
||||||
if [[ -z "$changed" ]]; then
|
|
||||||
echo "No .sh files changed in ct/, install/, tools/, turnkey/, or vm/."
|
|
||||||
echo "count=0" >> "$GITHUB_OUTPUT"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
declare -A seen
|
|
||||||
slugs=""
|
|
||||||
for f in $changed; do
|
|
||||||
[[ -f "$f" ]] || continue
|
|
||||||
base="${f##*/}"
|
|
||||||
base="${base%.sh}"
|
|
||||||
if [[ "$f" == install/* && "$base" == *-install ]]; then
|
|
||||||
slug="${base%-install}"
|
|
||||||
else
|
|
||||||
slug="$base"
|
|
||||||
fi
|
|
||||||
if [[ -z "${seen[$slug]:-}" ]]; then
|
|
||||||
seen[$slug]=1
|
|
||||||
slugs="$slugs $slug"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
slugs=$(echo $slugs | xargs -n1 | sort -u)
|
|
||||||
if [[ -z "$slugs" ]]; then
|
|
||||||
echo "No slugs to update."
|
|
||||||
echo "count=0" >> "$GITHUB_OUTPUT"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
echo "$slugs" > changed_slugs.txt
|
|
||||||
echo "count=$(echo "$slugs" | wc -w)" >> "$GITHUB_OUTPUT"
|
|
||||||
|
|
||||||
- name: Parse PR number from merge commit
|
|
||||||
id: pr
|
|
||||||
run: |
|
|
||||||
re='#([0-9]+)'
|
|
||||||
if [[ "$COMMIT_MSG" =~ $re ]]; then
|
|
||||||
echo "number=${BASH_REMATCH[1]}" >> "$GITHUB_OUTPUT"
|
|
||||||
else
|
|
||||||
echo "number=" >> "$GITHUB_OUTPUT"
|
|
||||||
fi
|
|
||||||
env:
|
|
||||||
COMMIT_MSG: ${{ github.event.head_commit.message }}
|
|
||||||
|
|
||||||
- name: Update script timestamps in PocketBase
|
|
||||||
if: steps.slugs.outputs.count != '0'
|
|
||||||
env:
|
|
||||||
POCKETBASE_URL: ${{ secrets.POCKETBASE_URL }}
|
|
||||||
POCKETBASE_COLLECTION: ${{ secrets.POCKETBASE_COLLECTION }}
|
|
||||||
POCKETBASE_ADMIN_EMAIL: ${{ secrets.POCKETBASE_ADMIN_EMAIL }}
|
|
||||||
POCKETBASE_ADMIN_PASSWORD: ${{ secrets.POCKETBASE_ADMIN_PASSWORD }}
|
|
||||||
COMMIT_URL: ${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}
|
|
||||||
PR_URL: ${{ steps.pr.outputs.number != '' && format('{0}/{1}/pull/{2}', github.server_url, github.repository, steps.pr.outputs.number) || '' }}
|
|
||||||
run: |
|
|
||||||
node << 'ENDSCRIPT'
|
|
||||||
(async function() {
|
|
||||||
const fs = require('fs');
|
|
||||||
const https = require('https');
|
|
||||||
const http = require('http');
|
|
||||||
const url = require('url');
|
|
||||||
|
|
||||||
function request(fullUrl, opts, redirectCount) {
|
|
||||||
redirectCount = redirectCount || 0;
|
|
||||||
return new Promise(function(resolve, reject) {
|
|
||||||
const u = url.parse(fullUrl);
|
|
||||||
const isHttps = u.protocol === 'https:';
|
|
||||||
const body = opts.body;
|
|
||||||
const options = {
|
|
||||||
hostname: u.hostname,
|
|
||||||
port: u.port || (isHttps ? 443 : 80),
|
|
||||||
path: u.path,
|
|
||||||
method: opts.method || 'GET',
|
|
||||||
headers: opts.headers || {}
|
|
||||||
};
|
|
||||||
if (body) options.headers['Content-Length'] = Buffer.byteLength(body);
|
|
||||||
const lib = isHttps ? https : http;
|
|
||||||
const req = lib.request(options, function(res) {
|
|
||||||
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
|
||||||
if (redirectCount >= 5) return reject(new Error('Too many redirects from ' + fullUrl));
|
|
||||||
const redirectUrl = url.resolve(fullUrl, res.headers.location);
|
|
||||||
res.resume();
|
|
||||||
resolve(request(redirectUrl, opts, redirectCount + 1));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let data = '';
|
|
||||||
res.on('data', function(chunk) { data += chunk; });
|
|
||||||
res.on('end', function() {
|
|
||||||
resolve({ ok: res.statusCode >= 200 && res.statusCode < 300, statusCode: res.statusCode, body: data });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
req.on('error', reject);
|
|
||||||
if (body) req.write(body);
|
|
||||||
req.end();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const raw = process.env.POCKETBASE_URL.replace(/\/$/, '');
|
|
||||||
const apiBase = /\/api$/i.test(raw) ? raw : raw + '/api';
|
|
||||||
const coll = process.env.POCKETBASE_COLLECTION;
|
|
||||||
const slugsText = fs.readFileSync('changed_slugs.txt', 'utf8').trim();
|
|
||||||
const slugs = slugsText ? slugsText.split(/\s+/).filter(Boolean) : [];
|
|
||||||
if (slugs.length === 0) {
|
|
||||||
console.log('No slugs to update.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const authUrl = apiBase + '/collections/users/auth-with-password';
|
|
||||||
const authBody = JSON.stringify({
|
|
||||||
identity: process.env.POCKETBASE_ADMIN_EMAIL,
|
|
||||||
password: process.env.POCKETBASE_ADMIN_PASSWORD
|
|
||||||
});
|
|
||||||
const authRes = await request(authUrl, {
|
|
||||||
method: 'POST',
|
|
||||||
headers: { 'Content-Type': 'application/json' },
|
|
||||||
body: authBody
|
|
||||||
});
|
|
||||||
if (!authRes.ok) {
|
|
||||||
throw new Error('Auth failed: ' + authRes.body);
|
|
||||||
}
|
|
||||||
const token = JSON.parse(authRes.body).token;
|
|
||||||
const recordsUrl = apiBase + '/collections/' + encodeURIComponent(coll) + '/records';
|
|
||||||
|
|
||||||
for (const slug of slugs) {
|
|
||||||
const filter = "(slug='" + slug.replace(/'/g, "''") + "')";
|
|
||||||
const listRes = await request(recordsUrl + '?filter=' + encodeURIComponent(filter) + '&perPage=1', {
|
|
||||||
headers: { 'Authorization': token }
|
|
||||||
});
|
|
||||||
const list = JSON.parse(listRes.body);
|
|
||||||
const record = list.items && list.items[0];
|
|
||||||
if (!record) {
|
|
||||||
console.log('Slug not in DB, skipping: ' + slug);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const patchRes = await request(recordsUrl + '/' + record.id, {
|
|
||||||
method: 'PATCH',
|
|
||||||
headers: { 'Authorization': token, 'Content-Type': 'application/json' },
|
|
||||||
body: JSON.stringify({
|
|
||||||
name: record.name || record.slug,
|
|
||||||
last_update_commit: process.env.PR_URL || process.env.COMMIT_URL || ''
|
|
||||||
})
|
|
||||||
});
|
|
||||||
if (!patchRes.ok) {
|
|
||||||
console.warn('PATCH failed for slug ' + slug + ': ' + patchRes.body);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
console.log('Updated timestamp for slug: ' + slug);
|
|
||||||
}
|
|
||||||
console.log('Done.');
|
|
||||||
})().catch(e => { console.error(e); process.exit(1); });
|
|
||||||
ENDSCRIPT
|
|
||||||
shell: bash
|
|
||||||
@@ -12,12 +12,6 @@ This repository contains a collection of scripts for managing and automating Pro
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Want to help?
|
|
||||||
|
|
||||||
Follow [here](https://community-scripts.org/docs) to see our Documentations.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🚀 Development Status
|
## 🚀 Development Status
|
||||||
|
|
||||||
- **⚠️ Unstable**: Features may be incomplete or subject to change.
|
- **⚠️ Unstable**: Features may be incomplete or subject to change.
|
||||||
|
|||||||
107
ct/alpine-borgbackup-server.sh
Normal file
107
ct/alpine-borgbackup-server.sh
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
||||||
|
|
||||||
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
|
# Author: Sander Koenders (sanderkoenders)
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
||||||
|
# Source: https://www.borgbackup.org/
|
||||||
|
|
||||||
|
APP="Alpine-BorgBackup-Server"
|
||||||
|
var_tags="${var_tags:-alpine;backup}"
|
||||||
|
var_cpu="${var_cpu:-2}"
|
||||||
|
var_ram="${var_ram:-1024}"
|
||||||
|
var_disk="${var_disk:-20}"
|
||||||
|
var_os="${var_os:-alpine}"
|
||||||
|
var_version="${var_version:-3.23}"
|
||||||
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
|
|
||||||
|
header_info "$APP"
|
||||||
|
variables
|
||||||
|
color
|
||||||
|
catch_errors
|
||||||
|
|
||||||
|
function update_script() {
|
||||||
|
header_info
|
||||||
|
|
||||||
|
if [[ ! -f /usr/bin/borg ]]; then
|
||||||
|
msg_error "No ${APP} Installation Found!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
CHOICE=$(msg_menu "BorgBackup Server Update Options" \
|
||||||
|
"1" "Update BorgBackup Server" \
|
||||||
|
"2" "Reset SSH Access" \
|
||||||
|
"3" "Enable password authentication for backup user (not recommended, use SSH key instead)" \
|
||||||
|
"4" "Disable password authentication for backup user (recommended for security, use SSH key)")
|
||||||
|
|
||||||
|
case $CHOICE in
|
||||||
|
1)
|
||||||
|
msg_info "Updating $APP LXC"
|
||||||
|
$STD apk -U upgrade
|
||||||
|
msg_ok "Updated $APP LXC successfully!"
|
||||||
|
;;
|
||||||
|
2)
|
||||||
|
if [[ "${PHS_SILENT:-0}" == "1" ]]; then
|
||||||
|
msg_warn "Reset SSH Public key requires interactive mode, skipping."
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
msg_info "Setting up SSH Public Key for backup user"
|
||||||
|
|
||||||
|
msg_info "Please paste your SSH public key (e.g., ssh-rsa AAAAB3... user@host): \n"
|
||||||
|
read -p "Key: " SSH_PUBLIC_KEY
|
||||||
|
echo
|
||||||
|
|
||||||
|
if [[ -z "$SSH_PUBLIC_KEY" ]]; then
|
||||||
|
msg_error "No SSH public key provided!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! "$SSH_PUBLIC_KEY" =~ ^(ssh-rsa|ssh-dss|ssh-ed25519|ecdsa-sha2-) ]]; then
|
||||||
|
msg_error "Invalid SSH public key format!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
msg_info "Setting up SSH access"
|
||||||
|
mkdir -p /home/backup/.ssh
|
||||||
|
echo "$SSH_PUBLIC_KEY" >/home/backup/.ssh/authorized_keys
|
||||||
|
|
||||||
|
chown -R backup:backup /home/backup/.ssh
|
||||||
|
chmod 700 /home/backup/.ssh
|
||||||
|
chmod 600 /home/backup/.ssh/authorized_keys
|
||||||
|
|
||||||
|
msg_ok "SSH access configured for backup user"
|
||||||
|
;;
|
||||||
|
3)
|
||||||
|
if [[ "${PHS_SILENT:-0}" == "1" ]]; then
|
||||||
|
msg_warn "Enabling password authentication requires interactive mode, skipping."
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
msg_info "Enabling password authentication for backup user"
|
||||||
|
msg_warn "Password authentication is less secure than using SSH keys. Consider using SSH keys instead."
|
||||||
|
passwd backup
|
||||||
|
sed -i 's/^#*\s*PasswordAuthentication\s\+\(yes\|no\)/PasswordAuthentication yes/' /etc/ssh/sshd_config
|
||||||
|
rc-service sshd restart
|
||||||
|
msg_ok "Password authentication enabled for backup user"
|
||||||
|
;;
|
||||||
|
4)
|
||||||
|
msg_info "Disabling password authentication for backup user"
|
||||||
|
sed -i 's/^#*\s*PasswordAuthentication\s\+\(yes\|no\)/PasswordAuthentication no/' /etc/ssh/sshd_config
|
||||||
|
rc-service sshd restart
|
||||||
|
msg_ok "Password authentication disabled for backup user"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
start
|
||||||
|
build_container
|
||||||
|
description
|
||||||
|
|
||||||
|
msg_ok "Completed successfully!\n"
|
||||||
|
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||||
|
echo -e "${INFO}${YW}Connection information:${CL}"
|
||||||
|
echo -e "${TAB}${GATEWAY}${BGN}ssh backup@${IP}${CL}"
|
||||||
|
echo -e "${TAB}${VERIFYPW}${YW}To set SSH key, run this script with the 'update' option and select option 2${CL}"
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
|
||||||
# Author: CopilotAssistant (community-scripts)
|
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
|
||||||
# Source: https://github.com/coredns/coredns
|
|
||||||
|
|
||||||
APP="Alpine-CoreDNS"
|
|
||||||
var_tags="${var_tags:-dns;network;alpine}"
|
|
||||||
var_cpu="${var_cpu:-1}"
|
|
||||||
var_ram="${var_ram:-256}"
|
|
||||||
var_disk="${var_disk:-1}"
|
|
||||||
var_os="${var_os:-alpine}"
|
|
||||||
var_version="${var_version:-3.23}"
|
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
|
||||||
|
|
||||||
header_info "$APP"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
check_container_storage
|
|
||||||
check_container_resources
|
|
||||||
|
|
||||||
if [[ ! -f /usr/local/bin/coredns ]]; then
|
|
||||||
msg_error "No ${APP} Installation Found!"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
if check_for_gh_release "coredns" "coredns/coredns"; then
|
|
||||||
msg_info "Stopping Service"
|
|
||||||
rc-service coredns stop
|
|
||||||
msg_ok "Stopped Service"
|
|
||||||
|
|
||||||
ARCH=$(uname -m)
|
|
||||||
[[ "$ARCH" == "x86_64" ]] && ARCH="amd64"
|
|
||||||
[[ "$ARCH" == "aarch64" ]] && ARCH="arm64"
|
|
||||||
fetch_and_deploy_gh_release "coredns" "coredns/coredns" "prebuild" "latest" "/usr/local/bin" \
|
|
||||||
"coredns_.*_linux_${ARCH}\.tgz"
|
|
||||||
chmod +x /usr/local/bin/coredns
|
|
||||||
|
|
||||||
msg_info "Starting Service"
|
|
||||||
rc-service coredns start
|
|
||||||
msg_ok "Started Service"
|
|
||||||
msg_ok "Updated successfully!"
|
|
||||||
fi
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed Successfully!\n"
|
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
|
||||||
echo -e "${INFO}${YW} CoreDNS is listening on port 53 (DNS)${CL}"
|
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}dns://${IP}${CL}"
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
|
||||||
# Author: MickLesk (CanbiZ)
|
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
|
||||||
# Source: https://github.com/nearai/ironclaw
|
|
||||||
|
|
||||||
APP="Alpine-IronClaw"
|
|
||||||
var_tags="${var_tags:-ai;agent;alpine}"
|
|
||||||
var_cpu="${var_cpu:-1}"
|
|
||||||
var_ram="${var_ram:-1024}"
|
|
||||||
var_disk="${var_disk:-8}"
|
|
||||||
var_os="${var_os:-alpine}"
|
|
||||||
var_version="${var_version:-3.23}"
|
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
|
||||||
|
|
||||||
header_info "$APP"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
check_container_storage
|
|
||||||
check_container_resources
|
|
||||||
|
|
||||||
if [[ ! -f /usr/local/bin/ironclaw ]]; then
|
|
||||||
msg_error "No ${APP} Installation Found!"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
if check_for_gh_release "ironclaw-bin" "nearai/ironclaw"; then
|
|
||||||
msg_info "Stopping Service"
|
|
||||||
rc-service ironclaw stop 2>/dev/null || true
|
|
||||||
msg_ok "Stopped Service"
|
|
||||||
|
|
||||||
msg_info "Backing up Configuration"
|
|
||||||
cp /root/.ironclaw/.env /root/ironclaw.env.bak
|
|
||||||
msg_ok "Backed up Configuration"
|
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "ironclaw-bin" "nearai/ironclaw" "prebuild" "latest" "/usr/local/bin" \
|
|
||||||
"ironclaw-$(uname -m)-unknown-linux-musl.tar.gz"
|
|
||||||
chmod +x /usr/local/bin/ironclaw
|
|
||||||
|
|
||||||
msg_info "Restoring Configuration"
|
|
||||||
cp /root/ironclaw.env.bak /root/.ironclaw/.env
|
|
||||||
rm -f /root/ironclaw.env.bak
|
|
||||||
msg_ok "Restored Configuration"
|
|
||||||
|
|
||||||
msg_info "Starting Service"
|
|
||||||
rc-service ironclaw start
|
|
||||||
msg_ok "Started Service"
|
|
||||||
msg_ok "Updated successfully!"
|
|
||||||
fi
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed Successfully!\n"
|
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
|
||||||
echo -e "${INFO}${YW} Complete setup by running:${CL}"
|
|
||||||
echo -e "${TAB}${BGN}ironclaw onboard${CL}"
|
|
||||||
echo -e "${INFO}${YW} Then start the service:${CL}"
|
|
||||||
echo -e "${TAB}${BGN}rc-service ironclaw start${CL}"
|
|
||||||
echo -e "${INFO}${YW} Access the Web UI at:${CL}"
|
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}"
|
|
||||||
echo -e "${INFO}${YW} Auth token and database credentials:${CL}"
|
|
||||||
echo -e "${TAB}${BGN}cat /root/.ironclaw/.env${CL}"
|
|
||||||
@@ -2,17 +2,17 @@
|
|||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
||||||
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
# Author: community-scripts
|
# Author: cobalt (cobaltgit)
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
||||||
# Source: https://jitsi.org/
|
# Source: https://ntfy.sh/
|
||||||
|
|
||||||
APP="Jitsi-Meet"
|
APP="Alpine-ntfy"
|
||||||
var_tags="${var_tags:-video;conference;communication}"
|
var_tags="${var_tags:-notification}"
|
||||||
var_cpu="${var_cpu:-4}"
|
var_cpu="${var_cpu:-1}"
|
||||||
var_ram="${var_ram:-4096}"
|
var_ram="${var_ram:-256}"
|
||||||
var_disk="${var_disk:-12}"
|
var_disk="${var_disk:-2}"
|
||||||
var_os="${var_os:-debian}"
|
var_os="${var_os:-alpine}"
|
||||||
var_version="${var_version:-12}"
|
var_version="${var_version:-3.22}"
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
|
|
||||||
header_info "$APP"
|
header_info "$APP"
|
||||||
@@ -24,20 +24,19 @@ function update_script() {
|
|||||||
header_info
|
header_info
|
||||||
check_container_storage
|
check_container_storage
|
||||||
check_container_resources
|
check_container_resources
|
||||||
|
if [[ ! -d /etc/ntfy ]]; then
|
||||||
if [[ ! -d /etc/jitsi ]]; then
|
|
||||||
msg_error "No ${APP} Installation Found!"
|
msg_error "No ${APP} Installation Found!"
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
msg_info "Updating ntfy LXC"
|
||||||
|
$STD apk -U upgrade
|
||||||
|
setcap 'cap_net_bind_service=+ep' /usr/bin/ntfy
|
||||||
|
msg_ok "Updated ntfy LXC"
|
||||||
|
|
||||||
msg_info "Updating Jitsi Meet"
|
msg_info "Restarting ntfy"
|
||||||
$STD apt update
|
rc-service ntfy restart
|
||||||
$STD apt install -y --only-upgrade \
|
msg_ok "Restarted ntfy"
|
||||||
jitsi-meet \
|
msg_ok "Updated successfully!"
|
||||||
jicofo \
|
|
||||||
jitsi-videobridge2 \
|
|
||||||
prosody
|
|
||||||
msg_ok "Updated Jitsi Meet"
|
|
||||||
exit
|
exit
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,7 +44,7 @@ start
|
|||||||
build_container
|
build_container
|
||||||
description
|
description
|
||||||
|
|
||||||
msg_ok "Completed Successfully!\n"
|
msg_ok "Completed successfully!\n"
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}https://${IP}${CL}"
|
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"
|
||||||
67
ct/anytype-server.sh
Normal file
67
ct/anytype-server.sh
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
||||||
|
|
||||||
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
|
# Author: MickLesk (CanbiZ)
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
||||||
|
# Source: https://anytype.io
|
||||||
|
|
||||||
|
APP="Anytype-Server"
|
||||||
|
var_tags="${var_tags:-notes;productivity;sync}"
|
||||||
|
var_cpu="${var_cpu:-2}"
|
||||||
|
var_ram="${var_ram:-4096}"
|
||||||
|
var_disk="${var_disk:-16}"
|
||||||
|
var_os="${var_os:-ubuntu}"
|
||||||
|
var_version="${var_version:-24.04}"
|
||||||
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
|
|
||||||
|
header_info "$APP"
|
||||||
|
variables
|
||||||
|
color
|
||||||
|
catch_errors
|
||||||
|
|
||||||
|
function update_script() {
|
||||||
|
header_info
|
||||||
|
check_container_storage
|
||||||
|
check_container_resources
|
||||||
|
|
||||||
|
if [[ ! -f /opt/anytype/any-sync-bundle ]]; then
|
||||||
|
msg_error "No ${APP} Installation Found!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
if check_for_gh_release "anytype" "grishy/any-sync-bundle"; then
|
||||||
|
msg_info "Stopping Service"
|
||||||
|
systemctl stop anytype
|
||||||
|
msg_ok "Stopped Service"
|
||||||
|
|
||||||
|
msg_info "Backing up Data"
|
||||||
|
cp -r /opt/anytype/data /opt/anytype_data_backup
|
||||||
|
msg_ok "Backed up Data"
|
||||||
|
|
||||||
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "anytype" "grishy/any-sync-bundle" "prebuild" "latest" "/opt/anytype" "any-sync-bundle_*_linux_amd64.tar.gz"
|
||||||
|
chmod +x /opt/anytype/any-sync-bundle
|
||||||
|
|
||||||
|
msg_info "Restoring Data"
|
||||||
|
cp -r /opt/anytype_data_backup/. /opt/anytype/data
|
||||||
|
rm -rf /opt/anytype_data_backup
|
||||||
|
msg_ok "Restored Data"
|
||||||
|
|
||||||
|
msg_info "Starting Service"
|
||||||
|
systemctl start anytype
|
||||||
|
msg_ok "Started Service"
|
||||||
|
msg_ok "Updated successfully!"
|
||||||
|
fi
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
start
|
||||||
|
build_container
|
||||||
|
description
|
||||||
|
|
||||||
|
msg_ok "Completed Successfully!\n"
|
||||||
|
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||||
|
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
||||||
|
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:33010${CL}"
|
||||||
|
echo -e "${INFO}${YW} Client config file:${CL}"
|
||||||
|
echo -e "${TAB}${GATEWAY}${BGN}/opt/anytype/data/client-config.yml${CL}"
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
|
||||||
# Author: SystemIdleProcess
|
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
|
||||||
# Source: https://github.com/caronc/apprise-api
|
|
||||||
|
|
||||||
APP="Apprise-API"
|
|
||||||
var_tags="${var_tags:-notification}"
|
|
||||||
var_cpu="${var_cpu:-1}"
|
|
||||||
var_ram="${var_ram:-512}"
|
|
||||||
var_disk="${var_disk:-2}"
|
|
||||||
var_os="${var_os:-debian}"
|
|
||||||
var_version="${var_version:-13}"
|
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
|
||||||
|
|
||||||
header_info "$APP"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
check_container_storage
|
|
||||||
check_container_resources
|
|
||||||
|
|
||||||
if [[ ! -d "/opt/apprise" ]]; then
|
|
||||||
msg_error "No ${APP} Installation Found!"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
if check_for_gh_release "apprise" "caronc/apprise-api"; then
|
|
||||||
msg_info "Stopping Service"
|
|
||||||
systemctl stop apprise-api
|
|
||||||
msg_ok "Stopped Service"
|
|
||||||
|
|
||||||
PYTHON_VERSION="3.12" setup_uv
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "apprise" "caronc/apprise-api" "tarball"
|
|
||||||
|
|
||||||
msg_info "Updating Apprise-API"
|
|
||||||
cd /opt/apprise
|
|
||||||
cp ./requirements.txt /etc/requirements.txt
|
|
||||||
$STD apt install -y nginx git
|
|
||||||
$STD uv pip install -r requirements.txt gunicorn supervisor --system
|
|
||||||
cp -fr apprise_api/static /usr/share/nginx/html/s/
|
|
||||||
mv apprise_api/ webapp
|
|
||||||
touch /etc/nginx/server-override.conf
|
|
||||||
touch /etc/nginx/location-override.conf
|
|
||||||
mkdir -p /config/store /attach /plugin /tmp/apprise /opt/apprise/logs
|
|
||||||
chmod 1777 /tmp/apprise && chmod 777 /config /config/store /attach /plugin /opt/apprise/logs
|
|
||||||
sed -i \
|
|
||||||
-e '/[[]program:nginx]/,/^[[]/ s|stdout_logfile=/dev/stdout|stdout_logfile=/opt/apprise/logs/nginx.log|' \
|
|
||||||
-e '/[[]program:nginx]/,/^[[]/ s|stderr_logfile=/dev/stderr|stderr_logfile=/opt/apprise/logs/nginx_error.log|' \
|
|
||||||
-e '/[[]program:gunicorn]/,/^[[]/ s|stdout_logfile=/dev/stdout|stdout_logfile=/opt/apprise/logs/gunicorn.log|' \
|
|
||||||
-e '/[[]program:gunicorn]/,/^[[]/ s|stderr_logfile=/dev/stderr|stderr_logfile=/opt/apprise/logs/gunicorn_error.log|' \
|
|
||||||
-e '/[[]supervisord]/,/^[[]/ s|logfile=/dev/null|logfile=/opt/apprise/logs/supervisor.log|' \
|
|
||||||
-e 's|_maxbytes=0|_maxbytes=10485760|g' \
|
|
||||||
/opt/apprise/webapp/etc/supervisord.conf
|
|
||||||
msg_ok "Updated Apprise-API"
|
|
||||||
|
|
||||||
msg_info "Starting Service"
|
|
||||||
systemctl start apprise-api
|
|
||||||
msg_ok "Started Service"
|
|
||||||
msg_ok "Updated successfully!"
|
|
||||||
fi
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed successfully!\n"
|
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
|
||||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8000${CL}"
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/asylumexp/Proxmox/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2026 tteck
|
|
||||||
# Author: tteck (tteckster)
|
|
||||||
# License: MIT | https://github.com/asylumexp/Proxmox/raw/main/LICENSE
|
|
||||||
# Source: https://adguard.com/
|
|
||||||
|
|
||||||
APP="Adguard"
|
|
||||||
var_tags="${var_tags:-adblock}"
|
|
||||||
var_cpu="${var_cpu:-1}"
|
|
||||||
var_ram="${var_ram:-512}"
|
|
||||||
var_disk="${var_disk:-2}"
|
|
||||||
var_os="${var_os:-debian}"
|
|
||||||
var_version="${var_version:-13}"
|
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
|
||||||
|
|
||||||
header_info "$APP"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
check_container_storage
|
|
||||||
check_container_resources
|
|
||||||
if [[ ! -d /opt/AdGuardHome ]]; then
|
|
||||||
msg_error "No ${APP} Installation Found!"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
msg_error "Adguard Home can only be updated via the user interface."
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed successfully!\n"
|
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
|
||||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}"
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/asylumexp/Proxmox/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2026 tteck
|
|
||||||
# Author: tteck (tteckster)
|
|
||||||
# License: MIT | https://github.com/asylumexp/Proxmox/raw/main/LICENSE
|
|
||||||
# Source: https://www.bazarr.media/
|
|
||||||
|
|
||||||
APP="Bazarr"
|
|
||||||
var_tags="${var_tags:-arr}"
|
|
||||||
var_cpu="${var_cpu:-2}"
|
|
||||||
var_ram="${var_ram:-1024}"
|
|
||||||
var_disk="${var_disk:-4}"
|
|
||||||
var_os="${var_os:-debian}"
|
|
||||||
var_version="${var_version:-13}"
|
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
|
||||||
|
|
||||||
header_info "$APP"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
check_container_storage
|
|
||||||
check_container_resources
|
|
||||||
if [[ ! -d /var/lib/bazarr/ ]]; then
|
|
||||||
msg_error "No ${APP} Installation Found!"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
if check_for_gh_release "bazarr" "morpheus65535/bazarr"; then
|
|
||||||
apt-get install -y libicu76 &>/dev/null
|
|
||||||
msg_info "Stopping Service"
|
|
||||||
systemctl stop bazarr
|
|
||||||
msg_ok "Stopped Service"
|
|
||||||
|
|
||||||
PYTHON_VERSION="3.12" setup_uv
|
|
||||||
fetch_and_deploy_gh_release "bazarr" "morpheus65535/bazarr" "prebuild" "latest" "/opt/bazarr" "bazarr.zip"
|
|
||||||
|
|
||||||
msg_info "Setup Bazarr"
|
|
||||||
mkdir -p /var/lib/bazarr/
|
|
||||||
chmod 775 /opt/bazarr /var/lib/bazarr/
|
|
||||||
# Always ensure venv exists
|
|
||||||
if [[ ! -d /opt/bazarr/venv/ ]]; then
|
|
||||||
$STD uv venv --clear /opt/bazarr/venv --python 3.12
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Always check and fix service file if needed
|
|
||||||
if [[ -f /etc/systemd/system/bazarr.service ]] && grep -q "ExecStart=/usr/bin/python3" /etc/systemd/system/bazarr.service; then
|
|
||||||
sed -i "s|ExecStart=/usr/bin/python3 /opt/bazarr/bazarr.py|ExecStart=/opt/bazarr/venv/bin/python3 /opt/bazarr/bazarr.py|g" /etc/systemd/system/bazarr.service
|
|
||||||
systemctl daemon-reload
|
|
||||||
fi
|
|
||||||
sed -i.bak 's/--only-binary=Pillow//g' /opt/bazarr/requirements.txt
|
|
||||||
$STD uv pip install -r /opt/bazarr/requirements.txt --python /opt/bazarr/venv/bin/python3
|
|
||||||
msg_ok "Setup Bazarr"
|
|
||||||
|
|
||||||
msg_info "Starting Service"
|
|
||||||
systemctl start bazarr
|
|
||||||
msg_ok "Started Service"
|
|
||||||
msg_ok "Updated successfully!"
|
|
||||||
fi
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed successfully!\n"
|
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
|
||||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:6767${CL}"
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/asylumexp/Proxmox/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
|
||||||
# Author: vhsdream
|
|
||||||
# License: MIT | https://github.com/asylumexp/Proxmox/raw/main/LICENSE
|
|
||||||
# Source: https://github.com/alam00000/bentopdf
|
|
||||||
|
|
||||||
APP="BentoPDF"
|
|
||||||
var_tags="${var_tags:-pdf-editor}"
|
|
||||||
var_cpu="${var_cpu:-1}"
|
|
||||||
var_ram="${var_ram:-4096}"
|
|
||||||
var_disk="${var_disk:-4}"
|
|
||||||
var_os="${var_os:-debian}"
|
|
||||||
var_version="${var_version:-13}"
|
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
|
||||||
|
|
||||||
header_info "$APP"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
check_container_storage
|
|
||||||
check_container_resources
|
|
||||||
if [[ ! -d /opt/bentopdf ]]; then
|
|
||||||
msg_error "No ${APP} Installation Found!"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
NODE_VERSION="24" setup_nodejs
|
|
||||||
|
|
||||||
if check_for_gh_release "bentopdf" "alam00000/bentopdf"; then
|
|
||||||
msg_info "Stopping Service"
|
|
||||||
systemctl stop bentopdf
|
|
||||||
msg_ok "Stopped Service"
|
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "bentopdf" "alam00000/bentopdf" "tarball" "latest" "/opt/bentopdf"
|
|
||||||
|
|
||||||
msg_info "Updating BentoPDF"
|
|
||||||
cd /opt/bentopdf
|
|
||||||
$STD npm ci --no-audit --no-fund
|
|
||||||
export SIMPLE_MODE=true
|
|
||||||
$STD npm run build -- --mode production
|
|
||||||
msg_ok "Updated BentoPDF"
|
|
||||||
|
|
||||||
msg_info "Starting Service"
|
|
||||||
systemctl start bentopdf
|
|
||||||
msg_ok "Started Service"
|
|
||||||
msg_ok "Updated successfully!"
|
|
||||||
fi
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed successfully!\n"
|
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
|
||||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8080${CL}"
|
|
||||||
@@ -1,109 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/asylumexp/Proxmox/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2026 tteck
|
|
||||||
# Author: tteck (tteckster)
|
|
||||||
# License: MIT | https://github.com/asylumexp/Proxmox/raw/main/LICENSE
|
|
||||||
# Source: https://www.home-assistant.io/
|
|
||||||
|
|
||||||
APP="Home Assistant"
|
|
||||||
var_tags="${var_tags:-automation;smarthome}"
|
|
||||||
var_cpu="${var_cpu:-2}"
|
|
||||||
var_ram="${var_ram:-2048}"
|
|
||||||
var_disk="${var_disk:-16}"
|
|
||||||
var_os="${var_os:-debian}"
|
|
||||||
var_version="${var_version:-13}"
|
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
|
||||||
|
|
||||||
header_info "$APP"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
check_container_storage
|
|
||||||
check_container_resources
|
|
||||||
if [[ ! -d /var/lib/docker/volumes/hass_config/_data ]]; then
|
|
||||||
msg_error "No ${APP} Installation Found!"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
UPD=$(msg_menu "Home Assistant Update Options" \
|
|
||||||
"1" "Update ALL Containers" \
|
|
||||||
"2" "Remove ALL Unused Images" \
|
|
||||||
"3" "Install HACS" \
|
|
||||||
"4" "Install FileBrowser")
|
|
||||||
|
|
||||||
if [ "$UPD" == "1" ]; then
|
|
||||||
msg_info "Updating All Containers"
|
|
||||||
CONTAINER_LIST="${1:-$(docker ps -q)}"
|
|
||||||
for container in ${CONTAINER_LIST}; do
|
|
||||||
CONTAINER_IMAGE="$(docker inspect --format "{{.Config.Image}}" --type container "${container}")"
|
|
||||||
RUNNING_IMAGE="$(docker inspect --format "{{.Image}}" --type container "${container}")"
|
|
||||||
docker pull "${CONTAINER_IMAGE}"
|
|
||||||
LATEST_IMAGE="$(docker inspect --format "{{.Id}}" --type image "${CONTAINER_IMAGE}")"
|
|
||||||
if [[ "${RUNNING_IMAGE}" != "${LATEST_IMAGE}" ]]; then
|
|
||||||
pip install -U runlike
|
|
||||||
echo "Updating ${container} image ${CONTAINER_IMAGE}"
|
|
||||||
DOCKER_COMMAND="$(runlike --use-volume-id "${container}")"
|
|
||||||
docker rm --force "${container}"
|
|
||||||
eval "${DOCKER_COMMAND}"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
msg_ok "Updated All Containers"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
if [ "$UPD" == "2" ]; then
|
|
||||||
msg_info "Removing ALL Unused Images"
|
|
||||||
docker image prune -af
|
|
||||||
msg_ok "Removed ALL Unused Images"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
if [ "$UPD" == "3" ]; then
|
|
||||||
msg_info "Installing Home Assistant Community Store (HACS)"
|
|
||||||
$STD apt update
|
|
||||||
cd /var/lib/docker/volumes/hass_config/_data
|
|
||||||
$STD bash <(curl -fsSL https://get.hacs.xyz)
|
|
||||||
msg_ok "Installed Home Assistant Community Store (HACS)"
|
|
||||||
echo -e "\n Reboot Home Assistant and clear browser cache then Add HACS integration.\n"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
if [ "$UPD" == "4" ]; then
|
|
||||||
msg_info "Installing FileBrowser"
|
|
||||||
RELEASE=$(curl -fsSL https://api.github.com/repos/filebrowser/filebrowser/releases/latest | grep -o '"tag_name": ".*"' | sed 's/"//g' | sed 's/tag_name: //g')
|
|
||||||
$STD curl -fsSL https://github.com/filebrowser/filebrowser/releases/download/v2.23.0/linux-arm64-filebrowser.tar.gz | tar -xzv -C /usr/local/bin
|
|
||||||
$STD filebrowser config init -a '0.0.0.0'
|
|
||||||
$STD filebrowser config set -a '0.0.0.0'
|
|
||||||
$STD filebrowser users add admin helper-scripts.com --perm.admin
|
|
||||||
msg_ok "Installed FileBrowser"
|
|
||||||
|
|
||||||
msg_info "Creating Service"
|
|
||||||
service_path="/etc/systemd/system/filebrowser.service"
|
|
||||||
echo "[Unit]
|
|
||||||
Description=Filebrowser
|
|
||||||
After=network-online.target
|
|
||||||
[Service]
|
|
||||||
User=root
|
|
||||||
WorkingDirectory=/root/
|
|
||||||
ExecStart=/usr/local/bin/filebrowser -r /
|
|
||||||
[Install]
|
|
||||||
WantedBy=default.target" >$service_path
|
|
||||||
|
|
||||||
$STD systemctl enable --now filebrowser
|
|
||||||
msg_ok "Created Service"
|
|
||||||
|
|
||||||
msg_ok "Completed successfully!\n"
|
|
||||||
echo -e "FileBrowser should be reachable by going to the following URL.
|
|
||||||
${BL}http://$LOCAL_IP:8080${CL} admin|helper-scripts.com\n"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed successfully!\n"
|
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
|
||||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}HA: http://${IP}:8123${CL}"
|
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}Portainer: https://${IP}:9443${CL}"
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/asylumexp/Proxmox/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2026 tteck
|
|
||||||
# Author: tteck (tteckster)
|
|
||||||
# License: MIT | https://github.com/asylumexp/Proxmox/raw/main/LICENSE
|
|
||||||
# Source: https://jellyfin.org/
|
|
||||||
|
|
||||||
APP="Jellyfin"
|
|
||||||
var_tags="${var_tags:-media}"
|
|
||||||
var_cpu="${var_cpu:-2}"
|
|
||||||
var_ram="${var_ram:-2048}"
|
|
||||||
var_disk="${var_disk:-16}"
|
|
||||||
var_os="${var_os:-ubuntu}"
|
|
||||||
var_version="${var_version:-24.04}"
|
|
||||||
var_unprivileged="${var_unprivileged:-0}"
|
|
||||||
var_gpu="${var_gpu:-yes}"
|
|
||||||
|
|
||||||
header_info "$APP"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
check_container_storage
|
|
||||||
check_container_resources
|
|
||||||
if [[ ! -d /usr/lib/jellyfin ]]; then
|
|
||||||
msg_error "No ${APP} Installation Found!"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
msg_info "Updating Jellyfin"
|
|
||||||
ensure_dependencies libjemalloc2
|
|
||||||
if [[ ! -f /usr/lib/libjemalloc.so ]]; then
|
|
||||||
ln -sf /usr/lib/aarch64-linux-gnu/libjemalloc.so.2 /usr/lib/libjemalloc.so
|
|
||||||
fi
|
|
||||||
$STD apt update
|
|
||||||
$STD apt -y upgrade
|
|
||||||
$STD apt -y --with-new-pkgs upgrade jellyfin jellyfin-server
|
|
||||||
msg_ok "Updated Jellyfin"
|
|
||||||
msg_ok "Updated successfully!"
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed successfully!\n"
|
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
|
||||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8096${CL}"
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/asylumexp/Proxmox/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
|
||||||
# Author: MickLesk (CanbiZ)
|
|
||||||
# License: MIT | https://github.com/asylumexp/Proxmox/raw/main/LICENSE
|
|
||||||
# Source: https://github.com/Chevron7Locked/kima-hub
|
|
||||||
|
|
||||||
APP="Kima-Hub"
|
|
||||||
var_tags="${var_tags:-music;streaming;media}"
|
|
||||||
var_cpu="${var_cpu:-4}"
|
|
||||||
var_ram="${var_ram:-8192}"
|
|
||||||
var_disk="${var_disk:-20}"
|
|
||||||
var_os="${var_os:-debian}"
|
|
||||||
var_version="${var_version:-13}"
|
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
|
||||||
|
|
||||||
header_info "$APP"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
check_container_storage
|
|
||||||
check_container_resources
|
|
||||||
|
|
||||||
if [[ ! -d /opt/kima-hub ]]; then
|
|
||||||
msg_error "No ${APP} Installation Found!"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
if check_for_gh_release "kima-hub" "Chevron7Locked/kima-hub"; then
|
|
||||||
msg_info "Stopping Services"
|
|
||||||
systemctl stop kima-frontend kima-backend kima-analyzer kima-analyzer-clap
|
|
||||||
msg_ok "Stopped Services"
|
|
||||||
|
|
||||||
msg_info "Backing up Data"
|
|
||||||
cp /opt/kima-hub/backend/.env /opt/kima-hub-backend-env.bak
|
|
||||||
cp /opt/kima-hub/frontend/.env /opt/kima-hub-frontend-env.bak
|
|
||||||
msg_ok "Backed up Data"
|
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "kima-hub" "Chevron7Locked/kima-hub" "tarball"
|
|
||||||
|
|
||||||
msg_info "Restoring Data"
|
|
||||||
cp /opt/kima-hub-backend-env.bak /opt/kima-hub/backend/.env
|
|
||||||
cp /opt/kima-hub-frontend-env.bak /opt/kima-hub/frontend/.env
|
|
||||||
rm -f /opt/kima-hub-backend-env.bak /opt/kima-hub-frontend-env.bak
|
|
||||||
msg_ok "Restored Data"
|
|
||||||
|
|
||||||
msg_info "Rebuilding Backend"
|
|
||||||
cd /opt/kima-hub/backend
|
|
||||||
$STD npm install
|
|
||||||
$STD npm run build
|
|
||||||
$STD npx prisma generate
|
|
||||||
$STD npx prisma migrate deploy
|
|
||||||
msg_ok "Rebuilt Backend"
|
|
||||||
|
|
||||||
msg_info "Rebuilding Frontend"
|
|
||||||
cd /opt/kima-hub/frontend
|
|
||||||
$STD npm install
|
|
||||||
$STD npm run build
|
|
||||||
msg_ok "Rebuilt Frontend"
|
|
||||||
|
|
||||||
msg_info "Starting Services"
|
|
||||||
systemctl start kima-backend kima-frontend kima-analyzer kima-analyzer-clap
|
|
||||||
msg_ok "Started Services"
|
|
||||||
msg_ok "Updated successfully!"
|
|
||||||
fi
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed successfully!\n"
|
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
|
||||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3030${CL}"
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/asylumexp/Proxmox/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
|
||||||
# Author: kristocopani
|
|
||||||
# License: MIT | https://github.com/asylumexp/Proxmox/raw/main/LICENSE
|
|
||||||
# Source: https://lubelogger.com/
|
|
||||||
|
|
||||||
APP="LubeLogger"
|
|
||||||
var_tags="${var_tags:-vehicle;car}"
|
|
||||||
var_cpu="${var_cpu:-1}"
|
|
||||||
var_ram="${var_ram:-512}"
|
|
||||||
var_disk="${var_disk:-2}"
|
|
||||||
var_os="${var_os:-debian}"
|
|
||||||
var_version="${var_version:-13}"
|
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
|
||||||
|
|
||||||
header_info "$APP"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
check_container_storage
|
|
||||||
check_container_resources
|
|
||||||
if [[ ! -f /etc/systemd/system/lubelogger.service ]]; then
|
|
||||||
msg_error "No ${APP} Installation Found!"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
if check_for_gh_release "lubelogger" "hargata/lubelog"; then
|
|
||||||
msg_info "Stopping Service"
|
|
||||||
systemctl stop lubelogger
|
|
||||||
msg_ok "Stopped Service"
|
|
||||||
|
|
||||||
msg_info "Backing up data"
|
|
||||||
mkdir -p /tmp/lubeloggerData/data
|
|
||||||
cp /opt/lubelogger/appsettings.json /tmp/lubeloggerData/appsettings.json
|
|
||||||
cp -r /opt/lubelogger/data/ /tmp/lubeloggerData/
|
|
||||||
|
|
||||||
# Lubelogger has moved multiples folders to the 'data' folder, and we need to move them before the update to keep the user data
|
|
||||||
# Github Discussion: https://github.com/hargata/lubelog/discussions/787
|
|
||||||
[[ -e /opt/lubelogger/config ]] && cp -r /opt/lubelogger/config /tmp/lubeloggerData/data/
|
|
||||||
[[ -e /opt/lubelogger/wwwroot/translations ]] && cp -r /opt/lubelogger/wwwroot/translations /tmp/lubeloggerData/data/
|
|
||||||
[[ -e /opt/lubelogger/wwwroot/documents ]] && cp -r /opt/lubelogger/wwwroot/documents /tmp/lubeloggerData/data/
|
|
||||||
[[ -e /opt/lubelogger/wwwroot/images ]] && cp -r /opt/lubelogger/wwwroot/images /tmp/lubeloggerData/data/
|
|
||||||
[[ -e /opt/lubelogger/wwwroot/temp ]] && cp -r /opt/lubelogger/wwwroot/temp /tmp/lubeloggerData/data/
|
|
||||||
[[ -e /opt/lubelogger/log ]] && cp -r /opt/lubelogger/log /tmp/lubeloggerData/
|
|
||||||
rm -rf /opt/lubelogger
|
|
||||||
msg_ok "Backed up data"
|
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "lubelogger" "hargata/lubelog" "prebuild" "latest" "/opt/lubelogger" "LubeLogger*linux_x64.zip"
|
|
||||||
|
|
||||||
msg_info "Configuring LubeLogger"
|
|
||||||
chmod 700 /opt/lubelogger/CarCareTracker
|
|
||||||
cp -rf /tmp/lubeloggerData/* /opt/lubelogger/
|
|
||||||
rm -rf /tmp/lubeloggerData
|
|
||||||
msg_ok "Configured LubeLogger"
|
|
||||||
|
|
||||||
msg_info "Starting Service"
|
|
||||||
systemctl start lubelogger
|
|
||||||
msg_ok "Started Service"
|
|
||||||
msg_ok "Updated successfully!"
|
|
||||||
fi
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed successfully!\n"
|
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
|
||||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:5000${CL}"
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/asylumexp/Proxmox/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2026 tteck
|
|
||||||
# Author: tteck (tteckster)
|
|
||||||
# License: MIT | https://github.com/asylumexp/Proxmox/raw/main/LICENSE
|
|
||||||
# Source: https://pi-hole.net/
|
|
||||||
|
|
||||||
APP="Pihole"
|
|
||||||
var_tags="${var_tags:-adblock}"
|
|
||||||
var_cpu="${var_cpu:-1}"
|
|
||||||
var_ram="${var_ram:-512}"
|
|
||||||
var_disk="${var_disk:-2}"
|
|
||||||
var_os="${var_os:-debian}"
|
|
||||||
var_version="${var_version:-13}"
|
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
|
||||||
|
|
||||||
header_info "$APP"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
check_container_storage
|
|
||||||
check_container_resources
|
|
||||||
if [[ ! -d /etc/pihole ]]; then
|
|
||||||
msg_error "No ${APP} Installation Found!"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
msg_info "Updating PiHole"
|
|
||||||
set +e
|
|
||||||
$STD apt update
|
|
||||||
$STD apt upgrade -y
|
|
||||||
/usr/local/bin/pihole -up
|
|
||||||
msg_ok "Updated PiHole"
|
|
||||||
msg_ok "Updated successfully!"
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed successfully!\n"
|
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
|
||||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}/admin${CL}"
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/asylumexp/Proxmox/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2026 tteck
|
|
||||||
# Author: tteck (tteckster)
|
|
||||||
# License: MIT | https://github.com/asylumexp/Proxmox/raw/main/LICENSE
|
|
||||||
# Source: https://github.com/rogerfar/rdt-client
|
|
||||||
|
|
||||||
APP="RDTClient"
|
|
||||||
var_tags="${var_tags:-torrent}"
|
|
||||||
var_cpu="${var_cpu:-1}"
|
|
||||||
var_ram="${var_ram:-1024}"
|
|
||||||
var_disk="${var_disk:-4}"
|
|
||||||
var_os="${var_os:-debian}"
|
|
||||||
var_version="${var_version:-13}"
|
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
|
||||||
|
|
||||||
header_info "$APP"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
check_container_storage
|
|
||||||
check_container_resources
|
|
||||||
if [[ ! -d /opt/rdtc/ ]]; then
|
|
||||||
msg_error "No ${APP} Installation Found!"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
if check_for_gh_release "rdt-client" "rogerfar/rdt-client"; then
|
|
||||||
msg_info "Stopping Service"
|
|
||||||
systemctl stop rdtc
|
|
||||||
msg_ok "Stopped Service"
|
|
||||||
|
|
||||||
msg_info "Creating backup"
|
|
||||||
mkdir -p /opt/rdtc-backup
|
|
||||||
cp -R /opt/rdtc/appsettings.json /opt/rdtc-backup/
|
|
||||||
msg_ok "Backup created"
|
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "rdt-client" "rogerfar/rdt-client" "prebuild" "latest" "/opt/rdtc" "RealDebridClient.zip"
|
|
||||||
cp -R /opt/rdtc-backup/appsettings.json /opt/rdtc/
|
|
||||||
if dpkg-query -W dotnet-sdk-8.0 >/dev/null 2>&1; then
|
|
||||||
$STD apt remove --purge -y dotnet-sdk-8.0
|
|
||||||
ensure_dependencies aspnetcore-runtime-9.0
|
|
||||||
fi
|
|
||||||
rm -rf /opt/rdtc-backup
|
|
||||||
|
|
||||||
msg_info "Starting Service"
|
|
||||||
systemctl start rdtc
|
|
||||||
msg_ok "Started Service"
|
|
||||||
msg_ok "Updated successfully!"
|
|
||||||
fi
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed successfully!\n"
|
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
|
||||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:6500${CL}"
|
|
||||||
@@ -1,119 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/asylumexp/Proxmox/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2026 tteck
|
|
||||||
# Author: tteck (tteckster)
|
|
||||||
# License: MIT | https://github.com/asylumexp/Proxmox/raw/main/LICENSE
|
|
||||||
# Source: https://github.com/dani-garcia/vaultwarden
|
|
||||||
|
|
||||||
APP="Vaultwarden"
|
|
||||||
var_tags="${var_tags:-password-manager}"
|
|
||||||
var_cpu="${var_cpu:-4}"
|
|
||||||
var_ram="${var_ram:-6144}"
|
|
||||||
var_disk="${var_disk:-20}"
|
|
||||||
var_os="${var_os:-debian}"
|
|
||||||
var_version="${var_version:-13}"
|
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
|
||||||
|
|
||||||
header_info "$APP"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
check_container_storage
|
|
||||||
check_container_resources
|
|
||||||
if [[ ! -f /etc/systemd/system/vaultwarden.service ]]; then
|
|
||||||
msg_error "No ${APP} Installation Found!"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
VAULT=$(get_latest_github_release "dani-garcia/vaultwarden")
|
|
||||||
WVRELEASE=$(get_latest_github_release "dani-garcia/bw_web_builds")
|
|
||||||
|
|
||||||
UPD=$(msg_menu "Vaultwarden Update Options" \
|
|
||||||
"1" "Update VaultWarden + Web-Vault" \
|
|
||||||
"2" "Set Admin Token")
|
|
||||||
|
|
||||||
if [ "$UPD" == "1" ]; then
|
|
||||||
if check_for_gh_release "vaultwarden" "dani-garcia/vaultwarden"; then
|
|
||||||
msg_info "Stopping Service"
|
|
||||||
systemctl stop vaultwarden
|
|
||||||
msg_ok "Stopped Service"
|
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "vaultwarden" "dani-garcia/vaultwarden" "tarball" "latest" "/tmp/vaultwarden-src"
|
|
||||||
|
|
||||||
msg_info "Updating VaultWarden to $VAULT (Patience)"
|
|
||||||
cd /tmp/vaultwarden-src
|
|
||||||
VW_VERSION="$VAULT"
|
|
||||||
export VW_VERSION
|
|
||||||
$STD cargo build --features "sqlite,mysql,postgresql" --release
|
|
||||||
if [[ -f /usr/bin/vaultwarden ]]; then
|
|
||||||
cp target/release/vaultwarden /usr/bin/
|
|
||||||
else
|
|
||||||
cp target/release/vaultwarden /opt/vaultwarden/bin/
|
|
||||||
fi
|
|
||||||
cd ~ && rm -rf /tmp/vaultwarden-src
|
|
||||||
msg_ok "Updated VaultWarden to ${VAULT}"
|
|
||||||
|
|
||||||
msg_info "Starting Service"
|
|
||||||
systemctl start vaultwarden
|
|
||||||
msg_ok "Started Service"
|
|
||||||
else
|
|
||||||
msg_ok "VaultWarden is already up-to-date"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if check_for_gh_release "vaultwarden_webvault" "dani-garcia/bw_web_builds"; then
|
|
||||||
msg_info "Stopping Service"
|
|
||||||
systemctl stop vaultwarden
|
|
||||||
msg_ok "Stopped Service"
|
|
||||||
|
|
||||||
msg_info "Updating Web-Vault to $WVRELEASE"
|
|
||||||
rm -rf /opt/vaultwarden/web-vault
|
|
||||||
mkdir -p /opt/vaultwarden/web-vault
|
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "vaultwarden_webvault" "dani-garcia/bw_web_builds" "prebuild" "latest" "/opt/vaultwarden/web-vault" "bw_web_*.tar.gz"
|
|
||||||
|
|
||||||
chown -R root:root /opt/vaultwarden/web-vault/
|
|
||||||
msg_ok "Updated Web-Vault to ${WVRELEASE}"
|
|
||||||
|
|
||||||
msg_info "Starting Service"
|
|
||||||
systemctl start vaultwarden
|
|
||||||
msg_ok "Started Service"
|
|
||||||
else
|
|
||||||
msg_ok "Web-Vault is already up-to-date"
|
|
||||||
fi
|
|
||||||
|
|
||||||
msg_ok "Updated successfully!"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$UPD" == "2" ]; then
|
|
||||||
if [[ "${PHS_SILENT:-0}" == "1" ]]; then
|
|
||||||
msg_warn "Set Admin Token requires interactive mode, skipping."
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
read -r -s -p "Set the ADMIN_TOKEN: " NEWTOKEN
|
|
||||||
echo ""
|
|
||||||
if [[ -n "$NEWTOKEN" ]]; then
|
|
||||||
ensure_dependencies argon2
|
|
||||||
TOKEN=$(echo -n "${NEWTOKEN}" | argon2 "$(openssl rand -base64 32)" -t 2 -m 16 -p 4 -l 64 -e)
|
|
||||||
sed -i "s|ADMIN_TOKEN=.*|ADMIN_TOKEN='${TOKEN}'|" /opt/vaultwarden/.env
|
|
||||||
if [[ -f /opt/vaultwarden/data/config.json ]]; then
|
|
||||||
sed -i "s|\"admin_token\":.*|\"admin_token\": \"${TOKEN}\"|" /opt/vaultwarden/data/config.json
|
|
||||||
fi
|
|
||||||
systemctl restart vaultwarden
|
|
||||||
msg_ok "Admin token updated"
|
|
||||||
fi
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed successfully!\n"
|
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
|
||||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}https://${IP}:8000${CL}"
|
|
||||||
170
ct/authentik.sh
170
ct/authentik.sh
@@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
# Author: Thieneret
|
# Author: Thieneret
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
||||||
@@ -20,93 +20,93 @@ color
|
|||||||
catch_errors
|
catch_errors
|
||||||
|
|
||||||
function update_script() {
|
function update_script() {
|
||||||
header_info
|
header_info
|
||||||
check_container_storage
|
check_container_storage
|
||||||
check_container_resources
|
check_container_resources
|
||||||
|
|
||||||
AUTHENTIK_VERSION="version/2026.2.0"
|
AUTHENTIK_VERSION="version/2026.2.0"
|
||||||
NODE_VERSION="24"
|
NODE_VERSION="24"
|
||||||
|
|
||||||
if [[ ! -d /opt/authentik ]]; then
|
if [[ ! -d /opt/authentik ]]; then
|
||||||
msg_error "No authentik Installation Found!"
|
msg_error "No authentik Installation Found!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$AUTHENTIK_VERSION" == "$(cat $HOME/.authentik)" ]]; then
|
||||||
|
msg_ok "Authentik up-to-date"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
if check_for_gh_release "geoipupdate" "maxmind/geoipupdate"; then
|
||||||
|
fetch_and_deploy_gh_release "geoipupdate" "maxmind/geoipupdate" "binary"
|
||||||
|
fi
|
||||||
|
|
||||||
|
msg_info "Stopping Services"
|
||||||
|
systemctl stop authentik-server.service
|
||||||
|
systemctl stop authentik-worker.service
|
||||||
|
msg_ok "Stopped Services"
|
||||||
|
|
||||||
|
if check_for_gh_release "xmlsec" "lsh123/xmlsec"; then
|
||||||
|
|
||||||
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "xmlsec" "lsh123/xmlsec" "tarball" "latest" "/opt/xmlsec"
|
||||||
|
|
||||||
|
msg_info "Update xmlsec"
|
||||||
|
cd /opt/xmlsec
|
||||||
|
$STD ./autogen.sh
|
||||||
|
$STD make -j $(nproc)
|
||||||
|
$STD make check
|
||||||
|
$STD make install
|
||||||
|
ldconfig
|
||||||
|
msg_ok "xmlsec updated"
|
||||||
|
fi
|
||||||
|
|
||||||
|
setup_nodejs
|
||||||
|
setup_go
|
||||||
|
|
||||||
|
if check_for_gh_release "authentik" "goauthentik/authentik" "${AUTHENTIK_VERSION}"; then
|
||||||
|
|
||||||
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "authentik" "goauthentik/authentik" "tarball" "${AUTHENTIK_VERSION}" "/opt/authentik"
|
||||||
|
|
||||||
|
msg_info "Update web"
|
||||||
|
cd /opt/authentik/web
|
||||||
|
NODE_ENV="production"
|
||||||
|
$STD npm install
|
||||||
|
$STD npm run build
|
||||||
|
$STD npm run build:sfe
|
||||||
|
msg_ok "Web updated"
|
||||||
|
|
||||||
|
msg_info "Update go proxy"
|
||||||
|
cd /opt/authentik
|
||||||
|
CGO_ENABLED="1"
|
||||||
|
$STD go mod download
|
||||||
|
$STD go build -o /opt/authentik/authentik-server ./cmd/server
|
||||||
|
msg_ok "Go proxy updated"
|
||||||
|
|
||||||
|
setup_uv
|
||||||
|
|
||||||
|
setup_rust
|
||||||
|
|
||||||
|
msg_info "Update python server"
|
||||||
|
$STD uv python install 3.14.3 -i /usr/local/bin
|
||||||
|
UV_NO_BINARY_PACKAGE="cryptography lxml python-kadmin-rs xmlsec"
|
||||||
|
UV_COMPILE_BYTECODE="1"
|
||||||
|
UV_LINK_MODE="copy"
|
||||||
|
UV_NATIVE_TLS="1"
|
||||||
|
RUSTUP_PERMIT_COPY_RENAME="true"
|
||||||
|
cd /opt/authentik
|
||||||
|
export UV_PYTHON_INSTALL_DIR="/usr/local/bin"
|
||||||
|
$STD uv sync --frozen --no-install-project --no-dev
|
||||||
|
msg_ok "Python server updated"
|
||||||
|
|
||||||
|
chown -R authentik:authentik /opt/authentik
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
msg_info "Restarting services"
|
||||||
|
systemctl restart authentik-server.service authentik-worker.service
|
||||||
|
msg_ok "Started Service"
|
||||||
|
msg_ok "Updated successfully!"
|
||||||
exit
|
exit
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$AUTHENTIK_VERSION" == "$(cat $HOME/.authentik)" ]]; then
|
|
||||||
msg_ok "Authentik up-to-date"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
if check_for_gh_release "geoipupdate" "maxmind/geoipupdate"; then
|
|
||||||
fetch_and_deploy_gh_release "geoipupdate" "maxmind/geoipupdate" "binary"
|
|
||||||
fi
|
|
||||||
|
|
||||||
msg_info "Stopping Services"
|
|
||||||
systemctl stop authentik-server.service
|
|
||||||
systemctl stop authentik-worker.service
|
|
||||||
msg_ok "Stopped Services"
|
|
||||||
|
|
||||||
if check_for_gh_release "xmlsec" "lsh123/xmlsec"; then
|
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "xmlsec" "lsh123/xmlsec" "tarball" "latest" "/opt/xmlsec"
|
|
||||||
|
|
||||||
msg_info "Update xmlsec"
|
|
||||||
cd /opt/xmlsec
|
|
||||||
$STD ./autogen.sh
|
|
||||||
$STD make -j $(nproc)
|
|
||||||
$STD make check
|
|
||||||
$STD make install
|
|
||||||
ldconfig
|
|
||||||
msg_ok "xmlsec updated"
|
|
||||||
fi
|
|
||||||
|
|
||||||
setup_nodejs
|
|
||||||
setup_go
|
|
||||||
|
|
||||||
if check_for_gh_release "authentik" "goauthentik/authentik" "${AUTHENTIK_VERSION}"; then
|
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "authentik" "goauthentik/authentik" "tarball" "${AUTHENTIK_VERSION}" "/opt/authentik"
|
|
||||||
|
|
||||||
msg_info "Update web"
|
|
||||||
cd /opt/authentik/web
|
|
||||||
NODE_ENV="production"
|
|
||||||
$STD npm install
|
|
||||||
$STD npm run build
|
|
||||||
$STD npm run build:sfe
|
|
||||||
msg_ok "Web updated"
|
|
||||||
|
|
||||||
msg_info "Update go proxy"
|
|
||||||
cd /opt/authentik
|
|
||||||
CGO_ENABLED="1"
|
|
||||||
$STD go mod download
|
|
||||||
$STD go build -o /opt/authentik/authentik-server ./cmd/server
|
|
||||||
msg_ok "Go proxy updated"
|
|
||||||
|
|
||||||
setup_uv
|
|
||||||
|
|
||||||
setup_rust
|
|
||||||
|
|
||||||
msg_info "Update python server"
|
|
||||||
$STD uv python install 3.14.3 -i /usr/local/bin
|
|
||||||
UV_NO_BINARY_PACKAGE="cryptography lxml python-kadmin-rs xmlsec"
|
|
||||||
UV_COMPILE_BYTECODE="1"
|
|
||||||
UV_LINK_MODE="copy"
|
|
||||||
UV_NATIVE_TLS="1"
|
|
||||||
RUSTUP_PERMIT_COPY_RENAME="true"
|
|
||||||
cd /opt/authentik
|
|
||||||
export UV_PYTHON_INSTALL_DIR="/usr/local/bin"
|
|
||||||
$STD uv sync --frozen --no-install-project --no-dev
|
|
||||||
msg_ok "Python server updated"
|
|
||||||
|
|
||||||
chown -R authentik:authentik /opt/authentik
|
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
msg_info "Restarting services"
|
|
||||||
systemctl restart authentik-server.service authentik-worker.service
|
|
||||||
msg_ok "Started Service"
|
|
||||||
msg_ok "Updated successfully!"
|
|
||||||
exit
|
|
||||||
}
|
}
|
||||||
|
|
||||||
start
|
start
|
||||||
|
|||||||
@@ -1,78 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
|
||||||
# Author: Adrian-RDA
|
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
|
||||||
# Source: https://github.com/maziggy/bambuddy
|
|
||||||
|
|
||||||
APP="Bambuddy"
|
|
||||||
var_tags="${var_tags:-media;3d-printing}"
|
|
||||||
var_cpu="${var_cpu:-2}"
|
|
||||||
var_ram="${var_ram:-2048}"
|
|
||||||
var_disk="${var_disk:-10}"
|
|
||||||
var_os="${var_os:-debian}"
|
|
||||||
var_version="${var_version:-13}"
|
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
|
||||||
|
|
||||||
header_info "$APP"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
check_container_storage
|
|
||||||
check_container_resources
|
|
||||||
|
|
||||||
if [[ ! -d /opt/bambuddy ]]; then
|
|
||||||
msg_error "No ${APP} Installation Found!"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
if check_for_gh_release "bambuddy" "maziggy/bambuddy"; then
|
|
||||||
msg_info "Stopping Service"
|
|
||||||
systemctl stop bambuddy
|
|
||||||
msg_ok "Stopped Service"
|
|
||||||
|
|
||||||
msg_info "Backing up Configuration and Data"
|
|
||||||
cp /opt/bambuddy/.env /opt/bambuddy.env.bak
|
|
||||||
cp -r /opt/bambuddy/data /opt/bambuddy_data_bak
|
|
||||||
msg_ok "Backed up Configuration and Data"
|
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "bambuddy" "maziggy/bambuddy" "tarball" "latest" "/opt/bambuddy"
|
|
||||||
|
|
||||||
msg_info "Updating Python Dependencies"
|
|
||||||
cd /opt/bambuddy
|
|
||||||
$STD uv venv
|
|
||||||
$STD uv pip install -r requirements.txt
|
|
||||||
msg_ok "Updated Python Dependencies"
|
|
||||||
|
|
||||||
msg_info "Rebuilding Frontend"
|
|
||||||
cd /opt/bambuddy/frontend
|
|
||||||
$STD npm install
|
|
||||||
$STD npm run build
|
|
||||||
msg_ok "Rebuilt Frontend"
|
|
||||||
|
|
||||||
msg_info "Restoring Configuration and Data"
|
|
||||||
cp /opt/bambuddy.env.bak /opt/bambuddy/.env
|
|
||||||
cp -r /opt/bambuddy_data_bak/. /opt/bambuddy/data/
|
|
||||||
rm -f /opt/bambuddy.env.bak
|
|
||||||
rm -rf /opt/bambuddy_data_bak
|
|
||||||
msg_ok "Restored Configuration and Data"
|
|
||||||
|
|
||||||
msg_info "Starting Service"
|
|
||||||
systemctl start bambuddy
|
|
||||||
msg_ok "Started Service"
|
|
||||||
msg_ok "Updated successfully!"
|
|
||||||
fi
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed Successfully!\n"
|
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
|
||||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8000${CL}"
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
|
||||||
# Author: MickLesk (CanbiZ)
|
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
|
||||||
# Source: https://github.com/baserow/baserow
|
|
||||||
|
|
||||||
APP="Baserow"
|
|
||||||
var_tags="${var_tags:-database;nocode;spreadsheet}"
|
|
||||||
var_cpu="${var_cpu:-4}"
|
|
||||||
var_ram="${var_ram:-8192}"
|
|
||||||
var_disk="${var_disk:-15}"
|
|
||||||
var_os="${var_os:-debian}"
|
|
||||||
var_version="${var_version:-13}"
|
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
|
||||||
|
|
||||||
header_info "$APP"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
check_container_storage
|
|
||||||
check_container_resources
|
|
||||||
|
|
||||||
if [[ ! -d /opt/baserow ]]; then
|
|
||||||
msg_error "No ${APP} Installation Found!"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
if check_for_gh_release "baserow" "baserow/baserow"; then
|
|
||||||
msg_info "Stopping Services"
|
|
||||||
systemctl stop baserow-backend baserow-celery baserow-celery-beat baserow-celery-export baserow-frontend
|
|
||||||
msg_ok "Stopped Services"
|
|
||||||
|
|
||||||
msg_info "Backing up Data"
|
|
||||||
cp /opt/baserow/.env /opt/baserow.env.bak
|
|
||||||
msg_ok "Backed up Data"
|
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "baserow" "baserow/baserow" "tarball"
|
|
||||||
|
|
||||||
msg_info "Restoring Configuration"
|
|
||||||
cp /opt/baserow.env.bak /opt/baserow/.env
|
|
||||||
rm -f /opt/baserow.env.bak
|
|
||||||
msg_ok "Restored Configuration"
|
|
||||||
|
|
||||||
msg_info "Updating Backend Dependencies"
|
|
||||||
cd /opt/baserow/backend
|
|
||||||
$STD uv sync --frozen --no-dev
|
|
||||||
msg_ok "Updated Backend Dependencies"
|
|
||||||
|
|
||||||
msg_info "Updating Frontend"
|
|
||||||
cd /opt/baserow/web-frontend
|
|
||||||
$STD npm install
|
|
||||||
$STD npm run build
|
|
||||||
msg_ok "Updated Frontend"
|
|
||||||
|
|
||||||
msg_info "Running Migrations"
|
|
||||||
cd /opt/baserow/backend
|
|
||||||
set -a && source /opt/baserow/.env && set +a
|
|
||||||
export PYTHONPATH="/opt/baserow/backend/src:/opt/baserow/premium/backend/src:/opt/baserow/enterprise/backend/src"
|
|
||||||
$STD /opt/baserow/backend/.venv/bin/python src/baserow/manage.py migrate
|
|
||||||
msg_ok "Ran Migrations"
|
|
||||||
|
|
||||||
msg_info "Starting Services"
|
|
||||||
systemctl start baserow-backend baserow-celery baserow-celery-beat baserow-celery-export baserow-frontend
|
|
||||||
msg_ok "Started Services"
|
|
||||||
msg_ok "Updated successfully!"
|
|
||||||
fi
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed Successfully!\n"
|
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
|
||||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}"
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
|
||||||
# Author: glabutis
|
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
|
||||||
# Source: https://github.com/bitfocus/companion
|
|
||||||
|
|
||||||
APP="Bitfocus Companion"
|
|
||||||
var_tags="${var_tags:-automation;media}"
|
|
||||||
var_cpu="${var_cpu:-2}"
|
|
||||||
var_ram="${var_ram:-512}"
|
|
||||||
var_disk="${var_disk:-8}"
|
|
||||||
var_os="${var_os:-debian}"
|
|
||||||
var_version="${var_version:-12}"
|
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
|
||||||
|
|
||||||
header_info "$APP"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
check_container_storage
|
|
||||||
check_container_resources
|
|
||||||
|
|
||||||
if [[ ! -f /opt/bitfocus-companion/companion_headless.sh ]]; then
|
|
||||||
msg_error "No ${APP} Installation Found!"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
RELEASE_JSON=$(curl -fsSL "https://api.bitfocus.io/v1/product/companion/packages?limit=20")
|
|
||||||
PACKAGE_JSON=$(echo "$RELEASE_JSON" | jq -c '(if type == "array" then . else .packages end) | [.[] | select(.target=="linux-tgz" and (.uri | contains("linux-x64")))] | first')
|
|
||||||
RELEASE=$(echo "$PACKAGE_JSON" | jq -r '.version // empty')
|
|
||||||
ASSET_URL=$(echo "$PACKAGE_JSON" | jq -r '.uri // empty')
|
|
||||||
if [[ -z "$RELEASE" || -z "$ASSET_URL" ]]; then
|
|
||||||
msg_error "Could not resolve a matching Linux x64 Companion package from the Bitfocus API."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "${RELEASE}" == "$(cat ~/.bitfocus-companion 2>/dev/null)" ]]; then
|
|
||||||
msg_ok "No update required. ${APP} is already at v${RELEASE}"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
msg_info "Stopping ${APP}"
|
|
||||||
systemctl stop bitfocus-companion
|
|
||||||
msg_ok "Stopped ${APP}"
|
|
||||||
|
|
||||||
msg_info "Updating ${APP} to v${RELEASE}"
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_from_url "$ASSET_URL" "/opt/bitfocus-companion"
|
|
||||||
echo "${RELEASE}" >~/.bitfocus-companion
|
|
||||||
msg_ok "Updated ${APP} to v${RELEASE}"
|
|
||||||
|
|
||||||
msg_info "Starting ${APP}"
|
|
||||||
systemctl start bitfocus-companion
|
|
||||||
msg_ok "Started ${APP}"
|
|
||||||
|
|
||||||
msg_ok "Update Successful"
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed successfully!\n"
|
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
|
||||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8000${CL}"
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
|
||||||
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
|
||||||
# Author: mathiasnagler
|
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
|
||||||
# Source: https://github.com/router-for-me/CLIProxyAPI
|
|
||||||
|
|
||||||
APP="CLIProxyAPI"
|
|
||||||
var_tags="${var_tags:-ai;proxy}"
|
|
||||||
var_cpu="${var_cpu:-1}"
|
|
||||||
var_ram="${var_ram:-512}"
|
|
||||||
var_disk="${var_disk:-2}"
|
|
||||||
var_os="${var_os:-debian}"
|
|
||||||
var_version="${var_version:-13}"
|
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
|
||||||
|
|
||||||
header_info "$APP"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
check_container_storage
|
|
||||||
check_container_resources
|
|
||||||
|
|
||||||
if [[ ! -d /opt/cliproxyapi ]]; then
|
|
||||||
msg_error "No CLIProxyAPI Installation Found!"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
if check_for_gh_release "cliproxyapi" "router-for-me/CLIProxyAPI"; then
|
|
||||||
msg_info "Stopping CLIProxyAPI"
|
|
||||||
systemctl stop cliproxyapi
|
|
||||||
msg_ok "Stopped CLIProxyAPI"
|
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "cliproxyapi" "router-for-me/CLIProxyAPI" "prebuild" "latest" "/opt/cliproxyapi" "CLIProxyAPI_*_linux_amd64.tar.gz"
|
|
||||||
|
|
||||||
msg_info "Starting CLIProxyAPI"
|
|
||||||
systemctl start cliproxyapi
|
|
||||||
msg_ok "Started CLIProxyAPI"
|
|
||||||
|
|
||||||
msg_ok "Updated Successfully"
|
|
||||||
fi
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed successfully!\n"
|
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
|
||||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8317${CL}"
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
|
||||||
# Author: MickLesk (CanbiZ)
|
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
|
||||||
# Source: https://github.com/coredns/coredns
|
|
||||||
|
|
||||||
APP="CoreDNS"
|
|
||||||
var_tags="${var_tags:-dns;network}"
|
|
||||||
var_cpu="${var_cpu:-1}"
|
|
||||||
var_ram="${var_ram:-256}"
|
|
||||||
var_disk="${var_disk:-1}"
|
|
||||||
var_os="${var_os:-debian}"
|
|
||||||
var_version="${var_version:-13}"
|
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
|
||||||
|
|
||||||
header_info "$APP"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
check_container_storage
|
|
||||||
check_container_resources
|
|
||||||
|
|
||||||
if [[ ! -f /usr/local/bin/coredns ]]; then
|
|
||||||
msg_error "No ${APP} Installation Found!"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
if check_for_gh_release "coredns" "coredns/coredns"; then
|
|
||||||
msg_info "Stopping Service"
|
|
||||||
systemctl stop coredns
|
|
||||||
msg_ok "Stopped Service"
|
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "coredns" "coredns/coredns" "prebuild" "latest" "/usr/local/bin" \
|
|
||||||
"coredns_*_linux_$(dpkg --print-architecture).tgz"
|
|
||||||
chmod +x /usr/local/bin/coredns
|
|
||||||
|
|
||||||
msg_info "Starting Service"
|
|
||||||
systemctl start coredns
|
|
||||||
msg_ok "Started Service"
|
|
||||||
msg_ok "Updated successfully!"
|
|
||||||
fi
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed Successfully!\n"
|
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
|
||||||
echo -e "${INFO}${YW} CoreDNS is listening on port 53 (DNS)${CL}"
|
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}dns://${IP}${CL}"
|
|
||||||
115
ct/deferred/alpine-homarr.sh
Normal file
115
ct/deferred/alpine-homarr.sh
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
||||||
|
|
||||||
|
# Copyright (c) 2021-2026 tteck
|
||||||
|
# Author: tteck (tteckster) | Co-Author: MickLesk (Canbiz) | Co-Author: CrazyWolf13
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
# Source: https://homarr.dev/
|
||||||
|
|
||||||
|
APP="alpine-homarr"
|
||||||
|
var_tags="${var_tags:-arr;dashboard}"
|
||||||
|
var_cpu="${var_cpu:-2}"
|
||||||
|
var_ram="${var_ram:-4096}"
|
||||||
|
var_disk="${var_disk:-8}"
|
||||||
|
var_os="${var_os:-alpine}"
|
||||||
|
var_version="${var_version:-3.21}"
|
||||||
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
|
|
||||||
|
header_info "$APP"
|
||||||
|
|
||||||
|
variables
|
||||||
|
color
|
||||||
|
catch_errors
|
||||||
|
|
||||||
|
function update_script() {
|
||||||
|
header_info
|
||||||
|
RELEASE=$(curl -fsSL https://api.github.com/repos/homarr-labs/homarr/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
|
||||||
|
if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then
|
||||||
|
|
||||||
|
msg_info "Stopping Services (Patience)"
|
||||||
|
systemctl stop homarr
|
||||||
|
msg_ok "Services Stopped"
|
||||||
|
|
||||||
|
msg_info "Backup Data"
|
||||||
|
mkdir -p /opt/homarr-data-backup
|
||||||
|
cp /opt/homarr/.env /opt/homarr-data-backup/.env
|
||||||
|
msg_ok "Backup Data"
|
||||||
|
|
||||||
|
msg_info "Updating and rebuilding ${APP} to v${RELEASE} (Patience)"
|
||||||
|
rm /opt/run_homarr.sh
|
||||||
|
cat <<'EOF' >/opt/run_homarr.sh
|
||||||
|
#!/bin/bash
|
||||||
|
set -a
|
||||||
|
source /opt/homarr/.env
|
||||||
|
set +a
|
||||||
|
export DB_DIALECT='sqlite'
|
||||||
|
export AUTH_SECRET=$(openssl rand -base64 32)
|
||||||
|
node /opt/homarr_db/migrations/$DB_DIALECT/migrate.cjs /opt/homarr_db/migrations/$DB_DIALECT
|
||||||
|
for dir in $(find /opt/homarr_db/migrations/migrations -mindepth 1 -maxdepth 1 -type d); do
|
||||||
|
dirname=$(basename "$dir")
|
||||||
|
mkdir -p "/opt/homarr_db/migrations/$dirname"
|
||||||
|
cp -r "$dir"/* "/opt/homarr_db/migrations/$dirname/" 2>/dev/null || true
|
||||||
|
done
|
||||||
|
export HOSTNAME=$(ip route get 1.1.1.1 | grep -oP 'src \K[^ ]+')
|
||||||
|
envsubst '${HOSTNAME}' < /etc/nginx/templates/nginx.conf > /etc/nginx/nginx.conf
|
||||||
|
nginx -g 'daemon off;' &
|
||||||
|
redis-server /opt/homarr/packages/redis/redis.conf &
|
||||||
|
node apps/tasks/tasks.cjs &
|
||||||
|
node apps/websocket/wssServer.cjs &
|
||||||
|
node apps/nextjs/server.js & PID=$!
|
||||||
|
wait $PID
|
||||||
|
EOF
|
||||||
|
chmod +x /opt/run_homarr.sh
|
||||||
|
NODE_VERSION=$(curl -fsSL https://raw.githubusercontent.com/homarr-labs/homarr/dev/package.json | jq -r '.engines.node | split(">=")[1] | split(".")[0]')
|
||||||
|
NODE_MODULE="pnpm@$(curl -fsSL https://raw.githubusercontent.com/homarr-labs/homarr/dev/package.json | jq -r '.packageManager | split("@")[1]')"
|
||||||
|
install_node_and_modules
|
||||||
|
rm -rf /opt/homarr
|
||||||
|
fetch_and_deploy_gh_release "homarr-labs/homarr"
|
||||||
|
mv /opt/homarr-data-backup/.env /opt/homarr/.env
|
||||||
|
cd /opt/homarr
|
||||||
|
echo "test2"
|
||||||
|
export NODE_ENV=""
|
||||||
|
$STD pnpm install --recursive --frozen-lockfile --shamefully-hoist
|
||||||
|
$STD pnpm build
|
||||||
|
cp /opt/homarr/apps/nextjs/next.config.ts .
|
||||||
|
cp /opt/homarr/apps/nextjs/package.json .
|
||||||
|
cp -r /opt/homarr/packages/db/migrations /opt/homarr_db/migrations
|
||||||
|
cp -r /opt/homarr/apps/nextjs/.next/standalone/* /opt/homarr
|
||||||
|
mkdir -p /appdata/redis
|
||||||
|
cp /opt/homarr/packages/redis/redis.conf /opt/homarr/redis.conf
|
||||||
|
rm /etc/nginx/nginx.conf
|
||||||
|
mkdir -p /etc/nginx/templates
|
||||||
|
cp /opt/homarr/nginx.conf /etc/nginx/templates/nginx.conf
|
||||||
|
|
||||||
|
mkdir -p /opt/homarr/apps/cli
|
||||||
|
cp /opt/homarr/packages/cli/cli.cjs /opt/homarr/apps/cli/cli.cjs
|
||||||
|
echo $'#!/bin/bash\ncd /opt/homarr/apps/cli && node ./cli.cjs "$@"' >/usr/bin/homarr
|
||||||
|
chmod +x /usr/bin/homarr
|
||||||
|
|
||||||
|
mkdir /opt/homarr/build
|
||||||
|
cp ./node_modules/better-sqlite3/build/Release/better_sqlite3.node ./build/better_sqlite3.node
|
||||||
|
echo "${RELEASE}" >/opt/${APP}_version.txt
|
||||||
|
msg_ok "Updated ${APP}"
|
||||||
|
|
||||||
|
msg_info "Starting Services"
|
||||||
|
systemctl start homarr
|
||||||
|
msg_ok "Started Services"
|
||||||
|
msg_ok "Updated Successfully"
|
||||||
|
read -p "It's recommended to reboot the LXC after an update, would you like to reboot the LXC now ? (y/n): " choice
|
||||||
|
if [[ "$choice" =~ ^[Yy]$ ]]; then
|
||||||
|
reboot
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
msg_ok "No update required. ${APP} is already at v${RELEASE}"
|
||||||
|
fi
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
start
|
||||||
|
build_container
|
||||||
|
description
|
||||||
|
|
||||||
|
msg_ok "Completed successfully!\n"
|
||||||
|
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||||
|
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
||||||
|
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:7575${CL}"
|
||||||
@@ -3,7 +3,7 @@ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxV
|
|||||||
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
# Author: MickLesk (Canbiz)
|
# Author: MickLesk (Canbiz)
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
# Source: https://github.com/community-scripts/ProxmoxVE
|
# Source: https://github.com/community-scripts/ProxmoxVE
|
||||||
|
|
||||||
APP="Docspell"
|
APP="Docspell"
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxV
|
|||||||
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
# Author: Nícolas Pastorello (opastorello)
|
# Author: Nícolas Pastorello (opastorello)
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
# Source: https://github.com/jumpserver/jumpserver
|
# Source: https://github.com/jumpserver/jumpserver
|
||||||
|
|
||||||
APP="JumpServer"
|
APP="JumpServer"
|
||||||
|
|||||||
@@ -2,17 +2,17 @@
|
|||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
||||||
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
# Author: Slaviša Arežina (tremor021)
|
# Author: MickLesk (CanbiZ)
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
||||||
# Source: https://github.com/ShaneIsrael/fireshare
|
# Source: https://github.com/Kanba-co/kanba
|
||||||
|
|
||||||
APP="Fireshare"
|
APP="Kanba"
|
||||||
var_tags="${var_tags:-}"
|
var_tags="${var_tags:-kanban}"
|
||||||
var_cpu="${var_cpu:-2}"
|
var_cpu="${var_cpu:-2}"
|
||||||
var_ram="${var_ram:-2048}"
|
var_ram="${var_ram:-2048}"
|
||||||
var_disk="${var_disk:-4}"
|
var_disk="${var_disk:-5}"
|
||||||
var_os="${var_os:-debian}"
|
var_os="${var_os:-debian}"
|
||||||
var_version="${var_version:-13}"
|
var_version="${var_version:-12}"
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
|
|
||||||
header_info "$APP"
|
header_info "$APP"
|
||||||
@@ -24,11 +24,14 @@ function update_script() {
|
|||||||
header_info
|
header_info
|
||||||
check_container_storage
|
check_container_storage
|
||||||
check_container_resources
|
check_container_resources
|
||||||
if [[ ! -d /opt/fireshare ]]; then
|
if [[ ! -d /var ]]; then
|
||||||
msg_error "No ${APP} Installation Found!"
|
msg_error "No ${APP} Installation Found!"
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
cleanup_lxc
|
msg_info "Updating $APP LXC"
|
||||||
|
$STD apt-get update
|
||||||
|
$STD apt-get -y upgrade
|
||||||
|
msg_ok "Updated $APP LXC"
|
||||||
exit
|
exit
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,4 +42,4 @@ description
|
|||||||
msg_ok "Completed successfully!\n"
|
msg_ok "Completed successfully!\n"
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"
|
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}"
|
||||||
46
ct/deferred/maybe_death/petio.sh
Normal file
46
ct/deferred/maybe_death/petio.sh
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
||||||
|
# Copyright (c) 2021-2026 tteck
|
||||||
|
# Author: tteck (tteckster)
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
# Source: https://petio.tv/
|
||||||
|
|
||||||
|
APP="Petio"
|
||||||
|
var_tags="${var_tags:-media}"
|
||||||
|
var_cpu="${var_cpu:-2}"
|
||||||
|
var_ram="${var_ram:-1024}"
|
||||||
|
var_disk="${var_disk:-4}"
|
||||||
|
var_os="${var_os:-ubuntu}"
|
||||||
|
var_version="${var_version:-24.04}"
|
||||||
|
|
||||||
|
header_info "$APP"
|
||||||
|
variables
|
||||||
|
color
|
||||||
|
catch_errors
|
||||||
|
|
||||||
|
function update_script() {
|
||||||
|
header_info
|
||||||
|
check_container_storage
|
||||||
|
check_container_resources
|
||||||
|
if [[ ! -d /opt/Petio ]]; then
|
||||||
|
msg_error "No ${APP} Installation Found!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
msg_info "Updating Pepito"
|
||||||
|
systemctl stop petio
|
||||||
|
curl -fsSL https://petio.tv/releases/latest -o petio-latest.zip
|
||||||
|
$STD unzip petio-latest.zip -d /opt/Petio
|
||||||
|
systemctl start petio
|
||||||
|
msg_ok "Updated Pepito"
|
||||||
|
msg_ok "Updated successfully!"
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
start
|
||||||
|
build_container
|
||||||
|
description
|
||||||
|
|
||||||
|
msg_ok "Completed successfully!\n"
|
||||||
|
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||||
|
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
||||||
|
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:7777${CL}"
|
||||||
130
ct/deferred/netbootxyz.sh
Normal file
130
ct/deferred/netbootxyz.sh
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
||||||
|
|
||||||
|
# Copyright (c) 2021-2023 tteck
|
||||||
|
# Author: tteck (tteckster)
|
||||||
|
# License: MIT
|
||||||
|
# https://github.com/tteck/Proxmox/raw/main/LICENSE
|
||||||
|
|
||||||
|
function header_info {
|
||||||
|
clear
|
||||||
|
cat <<"EOF"
|
||||||
|
__ __ __
|
||||||
|
____ ___ / /_/ /_ ____ ____ / /_ _ ____ ______
|
||||||
|
/ __ \/ _ \/ __/ __ \/ __ \/ __ \/ __/ | |/_/ / / /_ /
|
||||||
|
/ / / / __/ /_/ /_/ / /_/ / /_/ / /__ _> </ /_/ / / /_
|
||||||
|
/_/ /_/\___/\__/_.___/\____/\____/\__(_)_/|_|\__, / /___/
|
||||||
|
/____/
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
header_info
|
||||||
|
echo -e "Loading..."
|
||||||
|
APP="netboot.xyz"
|
||||||
|
var_disk="${var_disk:-2}"
|
||||||
|
var_cpu="${var_cpu:-1}"
|
||||||
|
var_ram="${var_ram:-512}"
|
||||||
|
var_os="${var_os:-debian}"
|
||||||
|
var_version="${var_version:-12}"
|
||||||
|
variables
|
||||||
|
color
|
||||||
|
catch_errors
|
||||||
|
|
||||||
|
function default_settings() {
|
||||||
|
CT_TYPE="1"
|
||||||
|
PW=""
|
||||||
|
CT_ID=$NEXTID
|
||||||
|
HN=$NSAPP
|
||||||
|
DISK_SIZE="$var_disk"
|
||||||
|
CORE_COUNT="$var_cpu"
|
||||||
|
RAM_SIZE="$var_ram"
|
||||||
|
BRG="vmbr0"
|
||||||
|
NET="dhcp"
|
||||||
|
GATE=""
|
||||||
|
DISABLEIP6="no"
|
||||||
|
MTU=""
|
||||||
|
SD=""
|
||||||
|
NS=""
|
||||||
|
MAC=""
|
||||||
|
VLAN=""
|
||||||
|
SSH="no"
|
||||||
|
VERB="no"
|
||||||
|
echo_default
|
||||||
|
}
|
||||||
|
|
||||||
|
function update_script() {
|
||||||
|
header_info
|
||||||
|
if [[ ! -d /opt/netboot.xyz ]]; then
|
||||||
|
msg_error "No ${APP} Installation Found!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
msg_info "Stopping ${APP}"
|
||||||
|
systemctl disable netbootxyz.service &>/dev/null
|
||||||
|
systemctl stop netbootxyz
|
||||||
|
sleep 1
|
||||||
|
msg_ok "Stopped ${APP}"
|
||||||
|
|
||||||
|
msg_info "Backing up Data"
|
||||||
|
cp -R /opt/netboot.xyz/config config-backup
|
||||||
|
cp -R /opt/netboot.xyz/assets assets-backup
|
||||||
|
sleep 1
|
||||||
|
msg_ok "Backed up Data"
|
||||||
|
|
||||||
|
RELEASE=$(curl -fsSLX GET "https://api.github.com/repos/netbootxyz/netboot.xyz/releases/latest" | awk '/tag_name/{print $4;exit}' FS='[""]')
|
||||||
|
msg_info "Updating netboot.xyz to ${RELEASE}"
|
||||||
|
curl --silent -o ${RELEASE}.tar.gz -L "https://github.com/netbootxyz/netboot.xyz/archive/${RELEASE}.tar.gz" &>/dev/null
|
||||||
|
tar xvzf ${RELEASE}.tar.gz &>/dev/null
|
||||||
|
VER=$(curl -fsSL https://api.github.com/repos/netbootxyz/netboot.xyz/releases/latest |
|
||||||
|
grep "tag_name" |
|
||||||
|
awk '{print substr($2, 2, length($2)-3) }')
|
||||||
|
|
||||||
|
if [ ! -d "/opt/netboot.xyz" ]; then
|
||||||
|
mv netboot.xyz-${VER} /opt/netboot.xyz
|
||||||
|
else
|
||||||
|
cp -R netboot.xyz-${VER}/* /opt/netboot.xyz
|
||||||
|
fi
|
||||||
|
|
||||||
|
service_path="/etc/systemd/system/netbootxyz.service"
|
||||||
|
echo "[Unit]
|
||||||
|
Description=netboot.xyz
|
||||||
|
After=network.target
|
||||||
|
[Service]
|
||||||
|
Restart=always
|
||||||
|
RestartSec=5
|
||||||
|
Type=simple
|
||||||
|
User=root
|
||||||
|
WorkingDirectory=/opt/netboot.xyz
|
||||||
|
ExecStart="ansible-playbook" -i inventory site.yml
|
||||||
|
TimeoutStopSec=30
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target" >$service_path
|
||||||
|
msg_ok "Updated netboot.xyz to ${RELEASE}"
|
||||||
|
|
||||||
|
msg_info "Restoring Data"
|
||||||
|
cp -R config-backup/* /opt/netboot.xyz/config
|
||||||
|
cp -R assets-backup/* /opt/netboot.xyz/assets
|
||||||
|
sleep 1
|
||||||
|
msg_ok "Restored Data"
|
||||||
|
|
||||||
|
msg_info "Cleanup"
|
||||||
|
rm -rf ${RELEASE}.tar.gz
|
||||||
|
rm -rf netboot.xyz-${VER}
|
||||||
|
rm -rf config-backup
|
||||||
|
rm -rf assets-backup
|
||||||
|
sleep 1
|
||||||
|
msg_ok "Cleaned"
|
||||||
|
|
||||||
|
msg_info "Starting ${APP}"
|
||||||
|
systemctl enable --now netbootxyz.service &>/dev/null
|
||||||
|
sleep 2
|
||||||
|
msg_ok "Started ${APP}"
|
||||||
|
msg_ok "Updated Successfully"
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
start
|
||||||
|
build_container
|
||||||
|
description
|
||||||
|
|
||||||
|
msg_ok "Completed successfully!\n"
|
||||||
|
echo -e "${APP} should be reachable by going to the following URL.
|
||||||
|
${BL}http://${IP}:3000${CL} \n"
|
||||||
161
ct/deferred/nginxproxymanager.sh
Normal file
161
ct/deferred/nginxproxymanager.sh
Normal file
@@ -0,0 +1,161 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
||||||
|
|
||||||
|
# Copyright (c) 2021-2026 tteck
|
||||||
|
# Author: tteck (tteckster)
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
# Source: https://nginxproxymanager.com/
|
||||||
|
|
||||||
|
APP="Nginx Proxy Manager"
|
||||||
|
var_tags="${var_tags:-proxy}"
|
||||||
|
var_cpu="${var_cpu:-2}"
|
||||||
|
var_ram="${var_ram:-1024}"
|
||||||
|
var_disk="${var_disk:-4}"
|
||||||
|
var_os="${var_os:-debian}"
|
||||||
|
var_version="${var_version:-12}"
|
||||||
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
|
|
||||||
|
header_info "$APP"
|
||||||
|
variables
|
||||||
|
color
|
||||||
|
catch_errors
|
||||||
|
|
||||||
|
function update_script() {
|
||||||
|
header_info
|
||||||
|
check_container_storage
|
||||||
|
check_container_resources
|
||||||
|
if [[ ! -f /lib/systemd/system/npm.service ]]; then
|
||||||
|
msg_error "No ${APP} Installation Found!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
if ! command -v pnpm &>/dev/null; then
|
||||||
|
msg_info "Installing pnpm"
|
||||||
|
#export NODE_OPTIONS=--openssl-legacy-provider
|
||||||
|
$STD npm install -g pnpm@8.15
|
||||||
|
msg_ok "Installed pnpm"
|
||||||
|
fi
|
||||||
|
RELEASE=$(curl -fsSL https://api.github.com/repos/NginxProxyManager/nginx-proxy-manager/releases/latest |
|
||||||
|
grep "tag_name" |
|
||||||
|
awk '{print substr($2, 3, length($2)-4) }')
|
||||||
|
msg_info "Stopping Services"
|
||||||
|
systemctl stop openresty
|
||||||
|
systemctl stop npm
|
||||||
|
msg_ok "Stopped Services"
|
||||||
|
|
||||||
|
msg_info "Cleaning Old Files"
|
||||||
|
rm -rf /app \
|
||||||
|
/var/www/html \
|
||||||
|
/etc/nginx \
|
||||||
|
/var/log/nginx \
|
||||||
|
/var/lib/nginx \
|
||||||
|
$STD /var/cache/nginx
|
||||||
|
msg_ok "Cleaned Old Files"
|
||||||
|
|
||||||
|
msg_info "Downloading NPM v${RELEASE}"
|
||||||
|
curl -fsSL https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v${RELEASE} -o - | tar -xz
|
||||||
|
cd nginx-proxy-manager-${RELEASE}
|
||||||
|
msg_ok "Downloaded NPM v${RELEASE}"
|
||||||
|
|
||||||
|
msg_info "Setting up Enviroment"
|
||||||
|
ln -sf /usr/bin/python3 /usr/bin/python
|
||||||
|
ln -sf /usr/bin/certbot /opt/certbot/bin/certbot
|
||||||
|
ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx
|
||||||
|
ln -sf /usr/local/openresty/nginx/ /etc/nginx
|
||||||
|
sed -i "s|\"version\": \"0.0.0\"|\"version\": \"$RELEASE\"|" backend/package.json
|
||||||
|
sed -i "s|\"version\": \"0.0.0\"|\"version\": \"$RELEASE\"|" frontend/package.json
|
||||||
|
sed -i 's|"fork-me": ".*"|"fork-me": "Proxmox VE Helper-Scripts"|' frontend/js/i18n/messages.json
|
||||||
|
sed -i "s|https://github.com.*source=nginx-proxy-manager|https://helper-scripts.com|g" frontend/js/app/ui/footer/main.ejs
|
||||||
|
sed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf
|
||||||
|
NGINX_CONFS=$(find "$(pwd)" -type f -name "*.conf")
|
||||||
|
for NGINX_CONF in $NGINX_CONFS; do
|
||||||
|
sed -i 's+include conf.d+include /etc/nginx/conf.d+g' "$NGINX_CONF"
|
||||||
|
done
|
||||||
|
mkdir -p /var/www/html /etc/nginx/logs
|
||||||
|
cp -r docker/rootfs/var/www/html/* /var/www/html/
|
||||||
|
cp -r docker/rootfs/etc/nginx/* /etc/nginx/
|
||||||
|
cp docker/rootfs/etc/letsencrypt.ini /etc/letsencrypt.ini
|
||||||
|
cp docker/rootfs/etc/logrotate.d/nginx-proxy-manager /etc/logrotate.d/nginx-proxy-manager
|
||||||
|
ln -sf /etc/nginx/nginx.conf /etc/nginx/conf/nginx.conf
|
||||||
|
rm -f /etc/nginx/conf.d/dev.conf
|
||||||
|
mkdir -p /tmp/nginx/body \
|
||||||
|
/run/nginx \
|
||||||
|
/data/nginx \
|
||||||
|
/data/custom_ssl \
|
||||||
|
/data/logs \
|
||||||
|
/data/access \
|
||||||
|
/data/nginx/default_host \
|
||||||
|
/data/nginx/default_www \
|
||||||
|
/data/nginx/proxy_host \
|
||||||
|
/data/nginx/redirection_host \
|
||||||
|
/data/nginx/stream \
|
||||||
|
/data/nginx/dead_host \
|
||||||
|
/data/nginx/temp \
|
||||||
|
/var/lib/nginx/cache/public \
|
||||||
|
/var/lib/nginx/cache/private \
|
||||||
|
/var/cache/nginx/proxy_temp
|
||||||
|
chmod -R 777 /var/cache/nginx
|
||||||
|
chown root /tmp/nginx
|
||||||
|
echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" {print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf);" >/etc/nginx/conf.d/include/resolvers.conf
|
||||||
|
if [ ! -f /data/nginx/dummycert.pem ] || [ ! -f /data/nginx/dummykey.pem ]; then
|
||||||
|
$STD openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -subj "/O=Nginx Proxy Manager/OU=Dummy Certificate/CN=localhost" -keyout /data/nginx/dummykey.pem -out /data/nginx/dummycert.pem
|
||||||
|
fi
|
||||||
|
mkdir -p /app/global /app/frontend/images
|
||||||
|
cp -r backend/* /app
|
||||||
|
cp -r global/* /app/global
|
||||||
|
$STD python3 -m pip install --no-cache-dir certbot-dns-cloudflare
|
||||||
|
msg_ok "Setup Enviroment"
|
||||||
|
|
||||||
|
msg_info "Building Frontend"
|
||||||
|
cd ./frontend
|
||||||
|
$STD pnpm install
|
||||||
|
$STD pnpm upgrade
|
||||||
|
$STD pnpm run build
|
||||||
|
cp -r dist/* /app/frontend
|
||||||
|
cp -r app-images/* /app/frontend/images
|
||||||
|
msg_ok "Built Frontend"
|
||||||
|
|
||||||
|
msg_info "Initializing Backend"
|
||||||
|
$STD rm -rf /app/config/default.json
|
||||||
|
if [ ! -f /app/config/production.json ]; then
|
||||||
|
cat <<'EOF' >/app/config/production.json
|
||||||
|
{
|
||||||
|
"database": {
|
||||||
|
"engine": "knex-native",
|
||||||
|
"knex": {
|
||||||
|
"client": "sqlite3",
|
||||||
|
"connection": {
|
||||||
|
"filename": "/data/database.sqlite"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
cd /app
|
||||||
|
$STD pnpm install
|
||||||
|
msg_ok "Initialized Backend"
|
||||||
|
|
||||||
|
msg_info "Starting Services"
|
||||||
|
sed -i 's/user npm/user root/g; s/^pid/#pid/g' /usr/local/openresty/nginx/conf/nginx.conf
|
||||||
|
sed -i 's/su npm npm/su root root/g' /etc/logrotate.d/nginx-proxy-manager
|
||||||
|
sed -i 's/include-system-site-packages = false/include-system-site-packages = true/g' /opt/certbot/pyvenv.cfg
|
||||||
|
systemctl enable -q --now openresty
|
||||||
|
systemctl enable -q --now npm
|
||||||
|
msg_ok "Started Services"
|
||||||
|
|
||||||
|
msg_info "Cleaning up"
|
||||||
|
rm -rf ~/nginx-proxy-manager-*
|
||||||
|
msg_ok "Cleaned"
|
||||||
|
|
||||||
|
msg_ok "Updated Successfully"
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
start
|
||||||
|
build_container
|
||||||
|
description
|
||||||
|
|
||||||
|
msg_ok "Completed successfully!\n"
|
||||||
|
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||||
|
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
||||||
|
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:81${CL}"
|
||||||
64
ct/deferred/opencloud.json
generated
Normal file
64
ct/deferred/opencloud.json
generated
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
{
|
||||||
|
"name": "OpenCloud",
|
||||||
|
"slug": "opencloud",
|
||||||
|
"categories": [
|
||||||
|
2
|
||||||
|
],
|
||||||
|
"date_created": "2025-06-11",
|
||||||
|
"type": "ct",
|
||||||
|
"updateable": true,
|
||||||
|
"privileged": false,
|
||||||
|
"interface_port": 443,
|
||||||
|
"documentation": "https://docs.opencloud.eu",
|
||||||
|
"config_path": "/etc/opencloud/opencloud.env, /etc/opencloud/opencloud.yaml, /etc/opencloud/csp.yaml",
|
||||||
|
"website": "https://opencloud.eu",
|
||||||
|
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/opencloud.webp",
|
||||||
|
"description": "OpenCloud is the file sharing and collaboration solution of the Heinlein Group. Through intelligent file management and a strong open source community, files become valuable resources, effectively structured and usable in the long term. With flexible data rooms and intelligent access rights, teams can access and work together on data anytime, anywhere without barriers, but with a lot of productivity.",
|
||||||
|
"install_methods": [
|
||||||
|
{
|
||||||
|
"type": "default",
|
||||||
|
"script": "ct/opencloud.sh",
|
||||||
|
"resources": {
|
||||||
|
"cpu": 2,
|
||||||
|
"ram": 2048,
|
||||||
|
"hdd": 6,
|
||||||
|
"os": "Debian",
|
||||||
|
"version": "12"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default_credentials": {
|
||||||
|
"username": "admin",
|
||||||
|
"password": "randomly generated during installation process"
|
||||||
|
},
|
||||||
|
"notes": [
|
||||||
|
{
|
||||||
|
"text": "Valid TLS certificates and fully-qualified domain names behind a reverse proxy (Caddy) for 3 services - OpenCloud, Collabora, and WOPI are **REQUIRED**",
|
||||||
|
"type": "warning"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Forgot your admin password? Check `admin_password` in the 'idm' section in `/etc/opencloud/opencloud.yaml`",
|
||||||
|
"type": "info"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "**Optional External Apps**: extract zip archives from App Store to `/etc/opencloud/assets/apps`",
|
||||||
|
"type": "info"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "**Optional CalDAV and CardDAV**: requires separate Radicale install. Edit and rename `/opt/opencloud/proxy.yaml.bak` and change your Radicale config to use `http_x_remote_user` as the auth method",
|
||||||
|
"type": "info"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "**Optional OpenID**: Authelia and PocketID supported. Uncomment relevant lines in `/opt/opencloud/opencloud.env` and consult OpenCloud GitHub discussions for configuration tips",
|
||||||
|
"type": "info"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "**Optional Full-text Search with Apache Tika**: requires your own Tika LXC. See `https://community-scripts.github.io/ProxmoxVE/scripts?id=apache-tika`",
|
||||||
|
"type": "info"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "**Relevant services**: `opencloud.service`, `opencloud-wopi.service`, `coolwsd.service`",
|
||||||
|
"type": "info"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxV
|
|||||||
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
# Author: MickLesk (CanbiZ)
|
# Author: MickLesk (CanbiZ)
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
# Source:
|
# Source:
|
||||||
|
|
||||||
APP="Roundcubemail"
|
APP="Roundcubemail"
|
||||||
|
|||||||
58
ct/deferred/squirrelserversmanager.sh
Normal file
58
ct/deferred/squirrelserversmanager.sh
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
||||||
|
|
||||||
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
|
# Author: MickLesk (Canbiz)
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
# Source:
|
||||||
|
|
||||||
|
APP="Squirrel Servers Manager"
|
||||||
|
var_tags="${var_tags:-manager}"
|
||||||
|
var_disk="${var_disk:-10}"
|
||||||
|
var_cpu="${var_cpu:-2}"
|
||||||
|
var_ram="${var_ram:-4096}"
|
||||||
|
var_os="${var_os:-alpine}"
|
||||||
|
var_version="${var_version:-3.21}"
|
||||||
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
|
|
||||||
|
variables
|
||||||
|
color
|
||||||
|
catch_errors
|
||||||
|
|
||||||
|
function update_script() {
|
||||||
|
header_info
|
||||||
|
if [[ ! -d /opt/squirrelserversmanager ]]; then
|
||||||
|
msg_error "No ${APP} Installation Found!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
msg_info "Updating ${APP}"
|
||||||
|
pm2 stop "squirrelserversmanager-frontend"
|
||||||
|
pm2 stop "squirrelserversmanager-backend"
|
||||||
|
cd /opt/squirrelserversmanager
|
||||||
|
git pull
|
||||||
|
cd /opt/squirrelserversmanager/shared-lib
|
||||||
|
npm ci &>/dev/null
|
||||||
|
npm run build
|
||||||
|
cd /opt/squirrelserversmanager/server
|
||||||
|
npm ci &>/dev/null
|
||||||
|
npm run build
|
||||||
|
cd /opt/squirrelserversmanager/client
|
||||||
|
npm ci &>/dev/null
|
||||||
|
npm run build
|
||||||
|
pm2 flush
|
||||||
|
pm2 restart "squirrelserversmanager-frontend"
|
||||||
|
pm2 restart "squirrelserversmanager-backend"
|
||||||
|
msg_ok "Successfully Updated ${APP}"
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
start
|
||||||
|
build_container
|
||||||
|
description
|
||||||
|
msg_info "Setting Container to Normal Resources"
|
||||||
|
pct set $CTID -memory 1024
|
||||||
|
pct set $CTID -cores 1
|
||||||
|
msg_ok "Set Container to Normal Resources"
|
||||||
|
msg_ok "Completed successfully!\n"
|
||||||
|
echo -e "${APP} should be reachable by going to the following URL.
|
||||||
|
${BL}http://${IP}:80${CL} \n"
|
||||||
@@ -3,7 +3,7 @@ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxV
|
|||||||
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
# Author: SunFlowerOwl
|
# Author: SunFlowerOwl
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
# Source: https://github.com/haugene/docker-transmission-openvpn
|
# Source: https://github.com/haugene/docker-transmission-openvpn
|
||||||
|
|
||||||
APP="transmission-openvpn"
|
APP="transmission-openvpn"
|
||||||
|
|||||||
73
ct/degoog.sh
73
ct/degoog.sh
@@ -1,73 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
|
||||||
# Author: vhsdream
|
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
|
||||||
# Source: https://github.com/fccview/degoog
|
|
||||||
|
|
||||||
APP="degoog"
|
|
||||||
var_tags="${var_tags:-search;privacy;plugins}"
|
|
||||||
var_cpu="${var_cpu:-2}"
|
|
||||||
var_ram="${var_ram:-2048}"
|
|
||||||
var_disk="${var_disk:-6}"
|
|
||||||
var_os="${var_os:-debian}"
|
|
||||||
var_version="${var_version:-13}"
|
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
|
||||||
|
|
||||||
header_info "$APP"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
check_container_storage
|
|
||||||
check_container_resources
|
|
||||||
|
|
||||||
if [[ ! -d /opt/degoog ]]; then
|
|
||||||
msg_error "No ${APP} Installation Found!"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
if check_for_gh_release "degoog" "fccview/degoog"; then
|
|
||||||
msg_info "Stopping Service"
|
|
||||||
systemctl stop degoog
|
|
||||||
msg_ok "Stopped Service"
|
|
||||||
|
|
||||||
msg_info "Backing up Configuration & Data"
|
|
||||||
[[ -f /opt/degoog/.env ]] && cp /opt/degoog/.env /opt/degoog.env.bak
|
|
||||||
[[ -d /opt/degoog/data ]] && mv /opt/degoog/data /opt/degoog_data_backup
|
|
||||||
msg_ok "Backed up Configuration & Data"
|
|
||||||
|
|
||||||
if ! command -v bun >/dev/null 2>&1; then
|
|
||||||
msg_info "Installing Bun"
|
|
||||||
export BUN_INSTALL="/root/.bun"
|
|
||||||
curl -fsSL https://bun.sh/install | $STD bash
|
|
||||||
ln -sf /root/.bun/bin/bun /usr/local/bin/bun
|
|
||||||
ln -sf /root/.bun/bin/bunx /usr/local/bin/bunx
|
|
||||||
msg_ok "Installed Bun"
|
|
||||||
fi
|
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "degoog" "fccview/degoog" "prebuild" "latest" "/opt/degoog" "degoog_*_prebuild.tar.gz"
|
|
||||||
|
|
||||||
msg_info "Restoring Configuration & Data"
|
|
||||||
[[ -f /opt/degoog.env.bak ]] && mv /opt/degoog.env.bak /opt/degoog/.env
|
|
||||||
[[ -d /opt/degoog_data_backup ]] && mv /opt/degoog_data_backup /opt/degoog/data
|
|
||||||
msg_ok "Restored Configuration & Data"
|
|
||||||
|
|
||||||
msg_info "Starting Service"
|
|
||||||
systemctl start degoog
|
|
||||||
msg_ok "Started Service"
|
|
||||||
msg_ok "Updated successfully!"
|
|
||||||
fi
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed Successfully!\n"
|
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
|
||||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:4444${CL}"
|
|
||||||
@@ -29,8 +29,8 @@ function update_script() {
|
|||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
msg_info "Updating Devuan LXC"
|
msg_info "Updating Devuan LXC"
|
||||||
$STD apt update
|
$STD apt-get update
|
||||||
$STD apt -y upgrade
|
$STD apt-get -y upgrade
|
||||||
msg_ok "Updated Devuan LXC"
|
msg_ok "Updated Devuan LXC"
|
||||||
exit
|
exit
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,5 +73,5 @@ msg_ok "Completed Successfully!\n"
|
|||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"
|
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"
|
||||||
echo -e "${INFO}${YW} Credentials saved in:${CL}"
|
echo -e "${INFO}${YW} Admin Setup:${CL}"
|
||||||
echo -e "${TAB}/root/discourse.creds"
|
echo -e "${TAB}${GATEWAY}${BGN}Create the first account in the web UI (use admin@local to match developer emails)${CL}"
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxV
|
|||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
# Author: MickLesk (CanbiZ)
|
# Author: MickLesk (CanbiZ)
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
||||||
# Source: https://github.com/ente-io/ente
|
# Source: https://www.debian.org/
|
||||||
|
|
||||||
APP="Ente"
|
APP="Ente"
|
||||||
var_tags="${var_tags:-photos}"
|
var_tags="${var_tags:-photos}"
|
||||||
@@ -24,13 +24,13 @@ function update_script() {
|
|||||||
header_info
|
header_info
|
||||||
check_container_storage
|
check_container_storage
|
||||||
check_container_resources
|
check_container_resources
|
||||||
if [[ ! -d /opt/ente ]]; then
|
if [[ ! -d /var ]]; then
|
||||||
msg_error "No ${APP} Installation Found!"
|
msg_error "No ${APP} Installation Found!"
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
msg_info "Updating Ente LXC"
|
msg_info "Updating Ente LXC"
|
||||||
$STD apt update
|
$STD apt-get update
|
||||||
$STD apt -y upgrade
|
$STD apt-get -y upgrade
|
||||||
msg_ok "Updated Ente LXC"
|
msg_ok "Updated Ente LXC"
|
||||||
exit
|
exit
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,49 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
|
||||||
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
|
||||||
# Author: community-scripts
|
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
|
||||||
# Source: https://github.com/frappe/erpnext
|
|
||||||
|
|
||||||
APP="ERPNext"
|
|
||||||
var_tags="${var_tags:-erp;business;accounting}"
|
|
||||||
var_cpu="${var_cpu:-4}"
|
|
||||||
var_ram="${var_ram:-4096}"
|
|
||||||
var_disk="${var_disk:-20}"
|
|
||||||
var_os="${var_os:-debian}"
|
|
||||||
var_version="${var_version:-13}"
|
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
|
||||||
|
|
||||||
header_info "$APP"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
check_container_storage
|
|
||||||
check_container_resources
|
|
||||||
|
|
||||||
if [[ ! -d /opt/frappe-bench ]]; then
|
|
||||||
msg_error "No ${APP} Installation Found!"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
msg_info "Updating ERPNext"
|
|
||||||
$STD sudo -u frappe bash -c 'export PATH="$HOME/.local/bin:$PATH"; cd /opt/frappe-bench && bench update --reset'
|
|
||||||
msg_ok "Updated ERPNext"
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed Successfully!\n"
|
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
|
||||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"
|
|
||||||
echo -e "${INFO}${YW} Credentials:${CL}"
|
|
||||||
echo -e "${TAB}${BGN}Username: Administrator${CL}"
|
|
||||||
echo -e "${TAB}${BGN}Password: see ~/erpnext.creds${CL}"
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
|
||||||
# Author: kkroboth
|
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
|
||||||
# Source: https://fileflows.com/
|
|
||||||
|
|
||||||
APP="FileFlows"
|
|
||||||
var_tags="${var_tags:-media;automation}"
|
|
||||||
var_cpu="${var_cpu:-2}"
|
|
||||||
var_ram="${var_ram:-2048}"
|
|
||||||
var_disk="${var_disk:-8}"
|
|
||||||
var_os="${var_os:-debian}"
|
|
||||||
var_version="${var_version:-13}"
|
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
|
||||||
var_gpu="${var_gpu:-yes}"
|
|
||||||
|
|
||||||
header_info "$APP"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
check_container_storage
|
|
||||||
check_container_resources
|
|
||||||
|
|
||||||
if [[ ! -d /opt/fileflows ]]; then
|
|
||||||
msg_error "No ${APP} Installation Found!"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
update_available=$(curl -fsSL -X 'GET' "http://localhost:19200/api/status/update-available" -H 'accept: application/json' | jq .UpdateAvailable)
|
|
||||||
if [[ "${update_available}" == "true" ]]; then
|
|
||||||
msg_info "Stopping Service"
|
|
||||||
systemctl stop fileflows*
|
|
||||||
msg_info "Stopped Service"
|
|
||||||
|
|
||||||
msg_info "Creating Backup"
|
|
||||||
ls /opt/*.tar.gz &>/dev/null && rm -f /opt/*.tar.gz
|
|
||||||
backup_filename="/opt/${APP}_backup_$(date +%F).tar.gz"
|
|
||||||
tar -czf "$backup_filename" -C /opt/fileflows Data
|
|
||||||
msg_ok "Backup Created"
|
|
||||||
|
|
||||||
fetch_and_deploy_from_url "https://fileflows.com/downloads/zip" "/opt/fileflows"
|
|
||||||
|
|
||||||
msg_info "Starting Service"
|
|
||||||
systemctl start fileflows*
|
|
||||||
msg_ok "Started Service"
|
|
||||||
msg_ok "Updated successfully!"
|
|
||||||
else
|
|
||||||
msg_ok "No update required. ${APP} is already at latest version"
|
|
||||||
fi
|
|
||||||
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed successfully!\n"
|
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
|
||||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:19200${CL}"
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
|
||||||
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
|
||||||
# Author: Slaviša Arežina (tremor021)
|
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
|
||||||
# Source: https://github.com/foldergram/foldergram
|
|
||||||
|
|
||||||
APP="Foldergram"
|
|
||||||
var_tags="${var_tags:-photos}"
|
|
||||||
var_cpu="${var_cpu:-1}"
|
|
||||||
var_ram="${var_ram:-2048}"
|
|
||||||
var_disk="${var_disk:-4}"
|
|
||||||
var_os="${var_os:-debian}"
|
|
||||||
var_version="${var_version:-13}"
|
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
|
||||||
|
|
||||||
header_info "$APP"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
check_container_storage
|
|
||||||
check_container_resources
|
|
||||||
if [[ ! -d /opt/foldergram ]]; then
|
|
||||||
msg_error "No ${APP} Installation Found!"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
if check_for_gh_release "foldergram" "foldergram/foldergram"; then
|
|
||||||
msg_info "Stopping Service"
|
|
||||||
systemctl stop foldergram
|
|
||||||
msg_ok "Stopped Service"
|
|
||||||
|
|
||||||
msg_info "Backing up configuration"
|
|
||||||
cp -r /opt/foldergram/data /opt/foldergram_data
|
|
||||||
cp /opt/foldergram/foldergram.env /opt/foldergram_env
|
|
||||||
msg_ok "Backed up configuration"
|
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "foldergram" "foldergram/foldergram" "tarball"
|
|
||||||
|
|
||||||
msg_info "Installing Foldergram"
|
|
||||||
cd /opt/foldergram
|
|
||||||
$STD pnpm install --frozen-lockfile
|
|
||||||
$STD pnpm run build
|
|
||||||
msg_ok "Installed Foldergram"
|
|
||||||
|
|
||||||
msg_info "Restoring configuration"
|
|
||||||
mv /opt/foldergram_data /opt/foldergram/data
|
|
||||||
mv /opt/foldergram_env /opt/foldergram/foldergram.env
|
|
||||||
msg_ok "Restored configuration"
|
|
||||||
|
|
||||||
msg_info "Starting Service"
|
|
||||||
systemctl start foldergram
|
|
||||||
msg_ok "Started Service"
|
|
||||||
msg_ok "Updated successfully!"
|
|
||||||
fi
|
|
||||||
cleanup_lxc
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed successfully!\n"
|
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
|
||||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:4141${CL}"
|
|
||||||
@@ -3,7 +3,7 @@ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxV
|
|||||||
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
# Author: Simon Friedrich
|
# Author: Simon Friedrich
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
# Source: https://forgejo.org/
|
# Source: https://forgejo.org/
|
||||||
|
|
||||||
APP="Forgejo-Runner"
|
APP="Forgejo-Runner"
|
||||||
@@ -12,7 +12,7 @@ var_cpu="${var_cpu:-2}"
|
|||||||
var_ram="${var_ram:-2048}"
|
var_ram="${var_ram:-2048}"
|
||||||
var_disk="${var_disk:-8}"
|
var_disk="${var_disk:-8}"
|
||||||
var_os="${var_os:-debian}"
|
var_os="${var_os:-debian}"
|
||||||
var_version="${var_version:-13}"
|
var_version="${var_version:-12}"
|
||||||
|
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
var_nesting="${var_nesting:-1}"
|
var_nesting="${var_nesting:-1}"
|
||||||
@@ -33,20 +33,14 @@ function update_script() {
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
RELEASE=$(curl -fsSL https://data.forgejo.org/api/v1/repos/forgejo/runner/releases/latest | grep -oP '"tag_name":\s*"\K[^"]+' | sed 's/^v//')
|
|
||||||
if [[ "${RELEASE}" == "$(cat ~/.forgejo-runner 2>/dev/null)" ]]; then
|
|
||||||
msg_ok "No update required. ${APP} is already at v${RELEASE}"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
msg_info "Stopping Services"
|
msg_info "Stopping Services"
|
||||||
systemctl stop forgejo-runner
|
systemctl stop forgejo-runner
|
||||||
msg_ok "Stopped Services"
|
msg_ok "Stopped Services"
|
||||||
|
|
||||||
|
RELEASE=$(curl -fsSL https://data.forgejo.org/api/v1/repos/forgejo/runner/releases/latest | grep -oP '"tag_name":\s*"\K[^"]+' | sed 's/^v//')
|
||||||
msg_info "Updating Forgejo Runner to v${RELEASE}"
|
msg_info "Updating Forgejo Runner to v${RELEASE}"
|
||||||
curl -fsSL "https://code.forgejo.org/forgejo/runner/releases/download/v${RELEASE}/forgejo-runner-${RELEASE}-linux-amd64" -o /usr/local/bin/forgejo-runner
|
curl -fsSL "https://code.forgejo.org/forgejo/runner/releases/download/v${RELEASE}/forgejo-runner-linux-amd64" -o forgejo-runner
|
||||||
chmod +x /usr/local/bin/forgejo-runner
|
chmod +x /usr/local/bin/forgejo-runner
|
||||||
echo "${RELEASE}" >~/.forgejo-runner
|
|
||||||
msg_ok "Updated Forgejo Runner"
|
msg_ok "Updated Forgejo Runner"
|
||||||
|
|
||||||
msg_info "Starting Services"
|
msg_info "Starting Services"
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ function update_script() {
|
|||||||
cp -r /opt/garmin-grafana/.garminconnect /opt/garmin-grafana-tokens.bak
|
cp -r /opt/garmin-grafana/.garminconnect /opt/garmin-grafana-tokens.bak
|
||||||
msg_ok "Backed up Data"
|
msg_ok "Backed up Data"
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "garmin-grafana" "arpanghosh8453/garmin-grafana" "tarball"
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "garmin-grafana" "arpanghosh8453/garmin-grafana"
|
||||||
|
|
||||||
msg_info "Restoring Data"
|
msg_info "Restoring Data"
|
||||||
cp /opt/garmin-grafana.env.bak /opt/garmin-grafana/.env
|
cp /opt/garmin-grafana.env.bak /opt/garmin-grafana/.env
|
||||||
|
|||||||
@@ -40,17 +40,15 @@ function update_script() {
|
|||||||
msg_info "Backing up runner configuration"
|
msg_info "Backing up runner configuration"
|
||||||
BACKUP_DIR="/opt/actions-runner.backup"
|
BACKUP_DIR="/opt/actions-runner.backup"
|
||||||
mkdir -p "$BACKUP_DIR"
|
mkdir -p "$BACKUP_DIR"
|
||||||
for f in .runner .credentials .credentials_rsaparams .env .path; do
|
[[ -f /opt/actions-runner/.runner ]] && cp -a /opt/actions-runner/.runner "$BACKUP_DIR/"
|
||||||
[[ -f /opt/actions-runner/$f ]] && cp -a /opt/actions-runner/$f "$BACKUP_DIR/"
|
[[ -f /opt/actions-runner/.credentials ]] && cp -a /opt/actions-runner/.credentials "$BACKUP_DIR/"
|
||||||
done
|
|
||||||
msg_ok "Backed up configuration"
|
msg_ok "Backed up configuration"
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "actions-runner" "actions/runner" "prebuild" "latest" "/opt/actions-runner" "actions-runner-linux-x64-*.tar.gz"
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "actions-runner" "actions/runner" "prebuild" "latest" "/opt/actions-runner" "actions-runner-linux-x64-*.tar.gz"
|
||||||
|
|
||||||
msg_info "Restoring runner configuration"
|
msg_info "Restoring runner configuration"
|
||||||
for f in .runner .credentials .credentials_rsaparams .env .path; do
|
[[ -f "$BACKUP_DIR/.runner" ]] && cp -a "$BACKUP_DIR/.runner" /opt/actions-runner/
|
||||||
[[ -f "$BACKUP_DIR/$f" ]] && cp -a "$BACKUP_DIR/$f" /opt/actions-runner/
|
[[ -f "$BACKUP_DIR/.credentials" ]] && cp -a "$BACKUP_DIR/.credentials" /opt/actions-runner/
|
||||||
done
|
|
||||||
rm -rf "$BACKUP_DIR"
|
rm -rf "$BACKUP_DIR"
|
||||||
msg_ok "Restored configuration"
|
msg_ok "Restored configuration"
|
||||||
|
|
||||||
|
|||||||
54
ct/godoxy.sh
54
ct/godoxy.sh
@@ -1,54 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
|
||||||
# Author: MickLesk (CanbiZ)
|
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
|
||||||
# Source: https://github.com/yusing/godoxy
|
|
||||||
|
|
||||||
APP="GoDoxy"
|
|
||||||
var_tags="${var_tags:-reverse-proxy;agent;proxmox}"
|
|
||||||
var_cpu="${var_cpu:-1}"
|
|
||||||
var_ram="${var_ram:-512}"
|
|
||||||
var_disk="${var_disk:-2}"
|
|
||||||
var_os="${var_os:-debian}"
|
|
||||||
var_version="${var_version:-13}"
|
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
|
||||||
|
|
||||||
header_info "$APP"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
check_container_storage
|
|
||||||
check_container_resources
|
|
||||||
|
|
||||||
if [[ ! -f /usr/local/bin/godoxy ]]; then
|
|
||||||
msg_error "No ${APP} Installation Found!"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
if check_for_gh_release "godoxy" "yusing/godoxy"; then
|
|
||||||
msg_info "Stopping Service"
|
|
||||||
systemctl stop godoxy-agent
|
|
||||||
msg_ok "Stopped Service"
|
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "godoxy" "yusing/godoxy" "singlefile" "latest" "/usr/local/bin" "godoxy-agent-linux-amd64"
|
|
||||||
|
|
||||||
msg_info "Starting Service"
|
|
||||||
systemctl start godoxy-agent
|
|
||||||
msg_ok "Started Service"
|
|
||||||
msg_ok "Updated successfully!"
|
|
||||||
fi
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed Successfully!\n"
|
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
|
||||||
echo -e "${INFO}${YW} Configure certs and AGENT_PORT in:${CL}"
|
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}/etc/godoxy-agent.env${CL}"
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
___ __ _ ______ ____ _ _______
|
|
||||||
/ | / /___ (_)___ ___ / ____/___ _______ / __ \/ | / / ___/
|
|
||||||
/ /| | / / __ \/ / __ \/ _ \ / / / __ \/ ___/ _ \ / / / |/ /\__ \
|
|
||||||
/ ___ |/ / /_/ / / / / / __// /___/ /_/ / / / __/ /_/ / /| /___/ /
|
|
||||||
/_/ |_/_/ .___/_/_/ /_/\___/ \____/\____/_/ \___/____/_/ |_//____/
|
|
||||||
/_/
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
___ __ _ _____ ______
|
|
||||||
/ | / /___ (_)___ ___ / _/________ ____ ____/ ____/ ____ _ __
|
|
||||||
/ /| | / / __ \/ / __ \/ _ \ / // ___/ __ \/ __ \/ ___/ / / __ \ | /| / /
|
|
||||||
/ ___ |/ / /_/ / / / / / __/_/ // / / /_/ / / / / /__/ /___/ /_/ / |/ |/ /
|
|
||||||
/_/ |_/_/ .___/_/_/ /_/\___/___/_/ \____/_/ /_/\___/\____/\____/|__/|__/
|
|
||||||
/_/
|
|
||||||
6
ct/headers/nextexplorer
Normal file
6
ct/headers/nextexplorer
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
__ ______ __
|
||||||
|
____ ___ _ __/ /_/ ____/ ______ / /___ ________ _____
|
||||||
|
/ __ \/ _ \| |/_/ __/ __/ | |/_/ __ \/ / __ \/ ___/ _ \/ ___/
|
||||||
|
/ / / / __/> </ /_/ /____> </ /_/ / / /_/ / / / __/ /
|
||||||
|
/_/ /_/\___/_/|_|\__/_____/_/|_/ .___/_/\____/_/ \___/_/
|
||||||
|
/_/
|
||||||
@@ -36,7 +36,7 @@ function update_script() {
|
|||||||
msg_ok "Stopped Services"
|
msg_ok "Stopped Services"
|
||||||
|
|
||||||
msg_info "Backing up Configuration"
|
msg_info "Backing up Configuration"
|
||||||
cp /opt/hoodik/.env /opt/hoodik.env.bak
|
cp /opt/hoodik/.env /tmp/hoodik.env.bak
|
||||||
msg_ok "Backed up Configuration"
|
msg_ok "Backed up Configuration"
|
||||||
|
|
||||||
msg_info "Updating Hoodik (Patience - this takes 15-20 minutes)"
|
msg_info "Updating Hoodik (Patience - this takes 15-20 minutes)"
|
||||||
@@ -58,8 +58,8 @@ function update_script() {
|
|||||||
msg_ok "Updated Hoodik"
|
msg_ok "Updated Hoodik"
|
||||||
|
|
||||||
msg_info "Restoring Configuration"
|
msg_info "Restoring Configuration"
|
||||||
cp /opt/hoodik.env.bak /opt/hoodik/.env
|
cp /tmp/hoodik.env.bak /opt/hoodik/.env
|
||||||
rm -f /opt/hoodik.env.bak
|
rm -f /tmp/hoodik.env.bak
|
||||||
msg_ok "Restored Configuration"
|
msg_ok "Restored Configuration"
|
||||||
|
|
||||||
msg_info "Cleaning Up"
|
msg_info "Cleaning Up"
|
||||||
|
|||||||
75
ct/immichframe.sh
Normal file
75
ct/immichframe.sh
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
COMMUNITY_SCRIPTS_URL="${COMMUNITY_SCRIPTS_URL:-https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main}"
|
||||||
|
source <(curl -fsSL "$COMMUNITY_SCRIPTS_URL/misc/build.func")
|
||||||
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
|
# Author: Thiago Canozzo Lahr (tclahr)
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
# Source: https://github.com/immichFrame/ImmichFrame
|
||||||
|
|
||||||
|
APP="ImmichFrame"
|
||||||
|
var_tags="${var_tags:-photos;slideshow}"
|
||||||
|
var_cpu="${var_cpu:-1}"
|
||||||
|
var_ram="${var_ram:-1024}"
|
||||||
|
var_disk="${var_disk:-8}"
|
||||||
|
var_os="${var_os:-debian}"
|
||||||
|
var_version="${var_version:-13}"
|
||||||
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
|
|
||||||
|
header_info "$APP"
|
||||||
|
variables
|
||||||
|
color
|
||||||
|
catch_errors
|
||||||
|
|
||||||
|
function update_script() {
|
||||||
|
header_info
|
||||||
|
check_container_storage
|
||||||
|
check_container_resources
|
||||||
|
|
||||||
|
if [[ ! -d /opt/immichframe ]]; then
|
||||||
|
msg_error "No ${APP} Installation Found!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
if check_for_gh_release "immichframe" "immichFrame/ImmichFrame"; then
|
||||||
|
msg_info "Stopping Service"
|
||||||
|
systemctl stop immichframe
|
||||||
|
msg_ok "Stopped Service"
|
||||||
|
|
||||||
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "immichframe" "immichFrame/ImmichFrame" "tarball" "latest" "/tmp/immichframe"
|
||||||
|
|
||||||
|
msg_info "Building Application"
|
||||||
|
cd /tmp/immichframe
|
||||||
|
$STD dotnet publish ImmichFrame.WebApi/ImmichFrame.WebApi.csproj \
|
||||||
|
--configuration Release \
|
||||||
|
--runtime linux-x64 \
|
||||||
|
--self-contained false \
|
||||||
|
--output /opt/immichframe
|
||||||
|
|
||||||
|
cd /tmp/immichframe/immichFrame.Web
|
||||||
|
$STD npm ci --silent
|
||||||
|
$STD npm run build
|
||||||
|
rm -rf /opt/immichframe/wwwroot/*
|
||||||
|
cp -r build/* /opt/immichframe/wwwroot
|
||||||
|
rm -rf /tmp/immichframe
|
||||||
|
chown -R immichframe:immichframe /opt/immichframe
|
||||||
|
msg_ok "Application Built"
|
||||||
|
|
||||||
|
msg_info "Starting Service"
|
||||||
|
systemctl start immichframe
|
||||||
|
msg_ok "Started Service"
|
||||||
|
msg_ok "Updated successfully!"
|
||||||
|
fi
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
start
|
||||||
|
build_container
|
||||||
|
description
|
||||||
|
|
||||||
|
msg_ok "Completed successfully!\n"
|
||||||
|
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||||
|
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
||||||
|
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8080${CL}"
|
||||||
|
echo -e "${INFO}${YW} Configuration file location:${CL}"
|
||||||
|
echo -e "${TAB}${GATEWAY}${BGN}/opt/immichframe/Config/Settings.yml${CL}"
|
||||||
|
echo -e "${INFO}${YW} Edit the config file and set ImmichServerUrl and ApiKey before use!${CL}"
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
|
||||||
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
|
||||||
# Author: vhsdream
|
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
|
||||||
# Source: https://github.com/iv-org/invidious
|
|
||||||
|
|
||||||
APP="Invidious"
|
|
||||||
var_tags="${var_tags:-streaming}"
|
|
||||||
var_cpu="${var_cpu:-2}"
|
|
||||||
var_ram="${var_ram:-2048}"
|
|
||||||
var_disk="${var_disk:-4}"
|
|
||||||
var_os="${var_os:-debian}"
|
|
||||||
var_version="${var_version:-13}"
|
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
|
||||||
|
|
||||||
header_info "$APP"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
check_container_storage
|
|
||||||
check_container_resources
|
|
||||||
|
|
||||||
if [[ ! -d /opt/invidious ]]; then
|
|
||||||
msg_error "No ${APP} Installation Found!"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
if check_for_gh_release "Invidious" "iv-org/invidious"; then
|
|
||||||
msg_info "Stopping services"
|
|
||||||
$STD systemctl stop invidious-companion invidious
|
|
||||||
msg_ok "Stopped services"
|
|
||||||
|
|
||||||
msg_info "Backing up config"
|
|
||||||
cp /opt/invidious/config/config.yml /opt/invidious-config.yml
|
|
||||||
msg_ok "Backed up config"
|
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "Invidious" "iv-org/invidious" "tarball" "latest" "/opt/invidious"
|
|
||||||
if check_for_gh_release "Invidious-Companion" "iv-org/invidious-companion"; then
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "Invidious-Companion" "iv-org/invidious-companion" "prebuild" "latest" "/opt/invidious-companion" "invidious_companion-x86_64-unknown-linux-gnu.tar.gz"
|
|
||||||
fi
|
|
||||||
|
|
||||||
msg_info "Rebuilding Invidious"
|
|
||||||
cd /opt/invidious
|
|
||||||
$STD make
|
|
||||||
msg_ok "Rebuilt Invidious"
|
|
||||||
|
|
||||||
msg_info "Restoring config"
|
|
||||||
cp /opt/invidious-config.yml /opt/invidious/config/config.yml
|
|
||||||
rm -f /opt/invidious-config.yml
|
|
||||||
msg_ok "Restored config"
|
|
||||||
|
|
||||||
msg_info "Starting services"
|
|
||||||
$STD systemctl start invidious invidious-companion
|
|
||||||
msg_ok "Started services"
|
|
||||||
msg_ok "Updated successfully!"
|
|
||||||
fi
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed successfully!\n"
|
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
|
||||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8086${CL}"
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
|
||||||
# Author: MickLesk (CanbiZ)
|
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
|
||||||
# Source: https://github.com/nearai/ironclaw
|
|
||||||
|
|
||||||
APP="IronClaw"
|
|
||||||
var_tags="${var_tags:-ai;agent;security}"
|
|
||||||
var_cpu="${var_cpu:-2}"
|
|
||||||
var_ram="${var_ram:-2048}"
|
|
||||||
var_disk="${var_disk:-8}"
|
|
||||||
var_os="${var_os:-debian}"
|
|
||||||
var_version="${var_version:-13}"
|
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
|
||||||
|
|
||||||
header_info "$APP"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
check_container_storage
|
|
||||||
check_container_resources
|
|
||||||
|
|
||||||
if [[ ! -f /usr/local/bin/ironclaw ]]; then
|
|
||||||
msg_error "No ${APP} Installation Found!"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
if check_for_gh_release "ironclaw-bin" "nearai/ironclaw"; then
|
|
||||||
msg_info "Stopping Service"
|
|
||||||
systemctl stop ironclaw
|
|
||||||
msg_ok "Stopped Service"
|
|
||||||
|
|
||||||
msg_info "Backing up Configuration"
|
|
||||||
cp /root/.ironclaw/.env /root/ironclaw.env.bak
|
|
||||||
msg_ok "Backed up Configuration"
|
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "ironclaw-bin" "nearai/ironclaw" "prebuild" "latest" "/usr/local/bin" \
|
|
||||||
"ironclaw-$(uname -m)-unknown-linux-$([[ -f /etc/alpine-release ]] && echo "musl" || echo "gnu").tar.gz"
|
|
||||||
chmod +x /usr/local/bin/ironclaw
|
|
||||||
|
|
||||||
msg_info "Restoring Configuration"
|
|
||||||
cp /root/ironclaw.env.bak /root/.ironclaw/.env
|
|
||||||
rm -f /root/ironclaw.env.bak
|
|
||||||
msg_ok "Restored Configuration"
|
|
||||||
|
|
||||||
msg_info "Starting Service"
|
|
||||||
systemctl start ironclaw
|
|
||||||
msg_ok "Started Service"
|
|
||||||
msg_ok "Updated successfully!"
|
|
||||||
fi
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed Successfully!\n"
|
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
|
||||||
echo -e "${INFO}${YW} Complete setup by running:${CL}"
|
|
||||||
echo -e "${TAB}${BGN}ironclaw onboard${CL}"
|
|
||||||
echo -e "${INFO}${YW} Then start the service:${CL}"
|
|
||||||
echo -e "${TAB}${BGN}systemctl start ironclaw${CL}"
|
|
||||||
echo -e "${INFO}${YW} Access the Web UI at:${CL}"
|
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}"
|
|
||||||
echo -e "${INFO}${YW} Auth token and database credentials:${CL}"
|
|
||||||
echo -e "${TAB}${BGN}cat /root/.ironclaw/.env${CL}"
|
|
||||||
75
ct/isponsorblocktv.sh
Normal file
75
ct/isponsorblocktv.sh
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
||||||
|
|
||||||
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
|
# Author: Matthew Stern (sternma)
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
||||||
|
# Source: https://github.com/dmunozv04/iSponsorBlockTV
|
||||||
|
|
||||||
|
APP="iSponsorBlockTV"
|
||||||
|
var_tags="${var_tags:-media;automation}"
|
||||||
|
var_cpu="${var_cpu:-1}"
|
||||||
|
var_ram="${var_ram:-1024}"
|
||||||
|
var_disk="${var_disk:-4}"
|
||||||
|
var_os="${var_os:-debian}"
|
||||||
|
var_version="${var_version:-13}"
|
||||||
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
|
|
||||||
|
header_info "$APP"
|
||||||
|
variables
|
||||||
|
color
|
||||||
|
catch_errors
|
||||||
|
|
||||||
|
function update_script() {
|
||||||
|
header_info
|
||||||
|
check_container_storage
|
||||||
|
check_container_resources
|
||||||
|
|
||||||
|
if [[ ! -d /opt/isponsorblocktv ]]; then
|
||||||
|
msg_error "No ${APP} Installation Found!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
if check_for_gh_release "isponsorblocktv" "dmunozv04/iSponsorBlockTV"; then
|
||||||
|
msg_info "Stopping Service"
|
||||||
|
systemctl stop isponsorblocktv
|
||||||
|
msg_ok "Stopped Service"
|
||||||
|
|
||||||
|
if [[ -d /var/lib/isponsorblocktv ]]; then
|
||||||
|
msg_info "Backing up Data"
|
||||||
|
cp -r /var/lib/isponsorblocktv /var/lib/isponsorblocktv_data_backup
|
||||||
|
msg_ok "Backed up Data"
|
||||||
|
fi
|
||||||
|
|
||||||
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "isponsorblocktv" "dmunozv04/iSponsorBlockTV"
|
||||||
|
|
||||||
|
msg_info "Setting up iSponsorBlockTV"
|
||||||
|
$STD python3 -m venv /opt/isponsorblocktv/venv
|
||||||
|
$STD /opt/isponsorblocktv/venv/bin/pip install --upgrade pip
|
||||||
|
$STD /opt/isponsorblocktv/venv/bin/pip install /opt/isponsorblocktv
|
||||||
|
msg_ok "Set up iSponsorBlockTV"
|
||||||
|
|
||||||
|
if [[ -d /var/lib/isponsorblocktv_data_backup ]]; then
|
||||||
|
msg_info "Restoring Data"
|
||||||
|
rm -rf /var/lib/isponsorblocktv
|
||||||
|
cp -r /var/lib/isponsorblocktv_data_backup /var/lib/isponsorblocktv
|
||||||
|
rm -rf /var/lib/isponsorblocktv_data_backup
|
||||||
|
msg_ok "Restored Data"
|
||||||
|
fi
|
||||||
|
|
||||||
|
msg_info "Starting Service"
|
||||||
|
systemctl start isponsorblocktv
|
||||||
|
msg_ok "Started Service"
|
||||||
|
msg_ok "Updated successfully!"
|
||||||
|
fi
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
start
|
||||||
|
build_container
|
||||||
|
description
|
||||||
|
|
||||||
|
msg_ok "Completed successfully!\n"
|
||||||
|
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||||
|
echo -e "${INFO}${YW} Run the setup wizard inside the container with:${CL}"
|
||||||
|
echo -e "${TAB}${GATEWAY}${BGN}iSponsorBlockTV setup${CL}"
|
||||||
54
ct/labca.sh
54
ct/labca.sh
@@ -1,54 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
|
||||||
# Author: MickLesk (CanbiZ)
|
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
|
||||||
# Source: https://github.com/hakwerk/labca
|
|
||||||
|
|
||||||
APP="LabCA"
|
|
||||||
var_tags="${var_tags:-certificate-authority;pki;gui}"
|
|
||||||
var_cpu="${var_cpu:-1}"
|
|
||||||
var_ram="${var_ram:-512}"
|
|
||||||
var_disk="${var_disk:-2}"
|
|
||||||
var_os="${var_os:-debian}"
|
|
||||||
var_version="${var_version:-13}"
|
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
|
||||||
|
|
||||||
header_info "$APP"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
check_container_storage
|
|
||||||
check_container_resources
|
|
||||||
|
|
||||||
if [[ ! -f /usr/bin/labca-gui ]]; then
|
|
||||||
msg_error "No ${APP} Installation Found!"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
if check_for_gh_release "labca-gui" "hakwerk/labca"; then
|
|
||||||
msg_info "Stopping Service"
|
|
||||||
systemctl stop labca
|
|
||||||
msg_ok "Stopped Service"
|
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "labca-gui" "hakwerk/labca" "binary"
|
|
||||||
|
|
||||||
msg_info "Starting Service"
|
|
||||||
systemctl start labca
|
|
||||||
msg_ok "Started Service"
|
|
||||||
msg_ok "Updated successfully!"
|
|
||||||
fi
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed Successfully!\n"
|
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
|
||||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}"
|
|
||||||
101
ct/librechat.sh
101
ct/librechat.sh
@@ -1,101 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
|
||||||
# Author: MickLesk (CanbiZ)
|
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
|
||||||
# Source: https://github.com/danny-avila/LibreChat
|
|
||||||
|
|
||||||
APP="LibreChat"
|
|
||||||
var_tags="${var_tags:-ai;chat}"
|
|
||||||
var_cpu="${var_cpu:-4}"
|
|
||||||
var_ram="${var_ram:-6144}"
|
|
||||||
var_disk="${var_disk:-20}"
|
|
||||||
var_os="${var_os:-debian}"
|
|
||||||
var_version="${var_version:-13}"
|
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
|
||||||
|
|
||||||
header_info "$APP"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
check_container_storage
|
|
||||||
check_container_resources
|
|
||||||
|
|
||||||
if [[ ! -d /opt/librechat ]]; then
|
|
||||||
msg_error "No ${APP} Installation Found!"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
if check_for_gh_tag "librechat" "danny-avila/LibreChat" "v"; then
|
|
||||||
msg_info "Stopping Services"
|
|
||||||
systemctl stop librechat rag-api
|
|
||||||
msg_ok "Stopped Services"
|
|
||||||
|
|
||||||
msg_info "Backing up Configuration"
|
|
||||||
cp /opt/librechat/.env /opt/librechat.env.bak
|
|
||||||
msg_ok "Backed up Configuration"
|
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_tag "librechat" "danny-avila/LibreChat"
|
|
||||||
|
|
||||||
msg_info "Installing Dependencies"
|
|
||||||
cd /opt/librechat
|
|
||||||
$STD npm ci
|
|
||||||
msg_ok "Installed Dependencies"
|
|
||||||
|
|
||||||
msg_info "Building Frontend"
|
|
||||||
$STD npm run frontend
|
|
||||||
$STD npm prune --production
|
|
||||||
$STD npm cache clean --force
|
|
||||||
msg_ok "Built Frontend"
|
|
||||||
|
|
||||||
msg_info "Restoring Configuration"
|
|
||||||
cp /opt/librechat.env.bak /opt/librechat/.env
|
|
||||||
rm -f /opt/librechat.env.bak
|
|
||||||
msg_ok "Restored Configuration"
|
|
||||||
|
|
||||||
msg_info "Starting Services"
|
|
||||||
systemctl start rag-api librechat
|
|
||||||
msg_ok "Started Services"
|
|
||||||
msg_ok "Updated LibreChat Successfully!"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if check_for_gh_release "rag-api" "danny-avila/rag_api"; then
|
|
||||||
msg_info "Stopping RAG API"
|
|
||||||
systemctl stop rag-api
|
|
||||||
msg_ok "Stopped RAG API"
|
|
||||||
|
|
||||||
msg_info "Backing up RAG API Configuration"
|
|
||||||
cp /opt/rag-api/.env /opt/rag-api.env.bak
|
|
||||||
msg_ok "Backed up RAG API Configuration"
|
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "rag-api" "danny-avila/rag_api" "tarball"
|
|
||||||
|
|
||||||
msg_info "Updating RAG API Dependencies"
|
|
||||||
cd /opt/rag-api
|
|
||||||
$STD .venv/bin/pip install -r requirements.lite.txt
|
|
||||||
msg_ok "Updated RAG API Dependencies"
|
|
||||||
|
|
||||||
msg_info "Restoring RAG API Configuration"
|
|
||||||
cp /opt/rag-api.env.bak /opt/rag-api/.env
|
|
||||||
rm -f /opt/rag-api.env.bak
|
|
||||||
msg_ok "Restored RAG API Configuration"
|
|
||||||
|
|
||||||
msg_info "Starting RAG API"
|
|
||||||
systemctl start rag-api
|
|
||||||
msg_ok "Started RAG API"
|
|
||||||
msg_ok "Updated RAG API Successfully!"
|
|
||||||
fi
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed Successfully!\n"
|
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
|
||||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3080${CL}"
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
|
||||||
# Author: MickLesk (CanbiZ)
|
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
|
||||||
# Source: https://github.com/lobehub/lobehub
|
|
||||||
|
|
||||||
APP="LobeHub"
|
|
||||||
var_tags="${var_tags:-ai;chat}"
|
|
||||||
var_cpu="${var_cpu:-4}"
|
|
||||||
var_ram="${var_ram:-8192}"
|
|
||||||
var_disk="${var_disk:-15}"
|
|
||||||
var_os="${var_os:-debian}"
|
|
||||||
var_version="${var_version:-13}"
|
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
|
||||||
|
|
||||||
header_info "$APP"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
check_container_storage
|
|
||||||
check_container_resources
|
|
||||||
|
|
||||||
if [[ ! -d /opt/lobehub ]]; then
|
|
||||||
msg_error "No ${APP} Installation Found!"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
if check_for_gh_release "lobehub" "lobehub/lobehub"; then
|
|
||||||
msg_info "Stopping Services"
|
|
||||||
systemctl stop lobehub
|
|
||||||
msg_ok "Stopped Services"
|
|
||||||
|
|
||||||
msg_info "Backing up Data"
|
|
||||||
cp /opt/lobehub/.env /opt/lobehub.env.bak
|
|
||||||
msg_ok "Backed up Data"
|
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "lobehub" "lobehub/lobehub" "tarball"
|
|
||||||
|
|
||||||
msg_info "Restoring Configuration"
|
|
||||||
cp /opt/lobehub.env.bak /opt/lobehub/.env
|
|
||||||
rm -f /opt/lobehub.env.bak
|
|
||||||
msg_ok "Restored Configuration"
|
|
||||||
|
|
||||||
msg_info "Building Application"
|
|
||||||
cd /opt/lobehub
|
|
||||||
export NODE_OPTIONS="--max-old-space-size=4096"
|
|
||||||
$STD pnpm install
|
|
||||||
$STD pnpm run build:docker
|
|
||||||
unset NODE_OPTIONS
|
|
||||||
msg_ok "Built Application"
|
|
||||||
|
|
||||||
msg_info "Running Database Migrations"
|
|
||||||
cd /opt/lobehub
|
|
||||||
set -a && source /opt/lobehub/.env && set +a
|
|
||||||
$STD node /opt/lobehub/.next/standalone/docker.cjs
|
|
||||||
msg_ok "Ran Database Migrations"
|
|
||||||
|
|
||||||
msg_info "Starting Services"
|
|
||||||
systemctl start lobehub
|
|
||||||
msg_ok "Started Services"
|
|
||||||
msg_ok "Updated successfully!"
|
|
||||||
fi
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed Successfully!\n"
|
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
|
||||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3210${CL}"
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
source <(curl -sSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
# Author: BillyOutlast
|
# Author: BillyOutlast
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
||||||
@@ -25,11 +25,6 @@ function update_script() {
|
|||||||
check_container_storage
|
check_container_storage
|
||||||
check_container_resources
|
check_container_resources
|
||||||
|
|
||||||
if [[ ! -d /opt/localagi ]]; then
|
|
||||||
msg_error "No ${APP} Installation Found!"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
if check_for_gh_release "localagi" "mudler/LocalAGI"; then
|
if check_for_gh_release "localagi" "mudler/LocalAGI"; then
|
||||||
msg_info "Stopping Service"
|
msg_info "Stopping Service"
|
||||||
systemctl stop localagi
|
systemctl stop localagi
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxV
|
|||||||
|
|
||||||
# Copyright (c) 2021-2025 minthcm
|
# Copyright (c) 2021-2025 minthcm
|
||||||
# Author: MintHCM
|
# Author: MintHCM
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
# Source: https://github.com/minthcm/minthcm
|
# Source: https://github.com/minthcm/minthcm
|
||||||
|
|
||||||
APP="MintHCM"
|
APP="MintHCM"
|
||||||
|
|||||||
@@ -1,87 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
|
||||||
# Author: Michel Roegl-Brunner (michelroegl-brunner)
|
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
|
||||||
# Source: https://netboot.xyz
|
|
||||||
|
|
||||||
APP="netboot.xyz"
|
|
||||||
var_tags="${var_tags:-network;pxe;boot}"
|
|
||||||
var_cpu="${var_cpu:-1}"
|
|
||||||
var_ram="${var_ram:-512}"
|
|
||||||
var_disk="${var_disk:-8}"
|
|
||||||
var_os="${var_os:-debian}"
|
|
||||||
var_version="${var_version:-13}"
|
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
|
||||||
|
|
||||||
header_info "$APP"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
check_container_storage
|
|
||||||
check_container_resources
|
|
||||||
|
|
||||||
if [[ ! -f ~/.netboot-xyz ]]; then
|
|
||||||
msg_error "No ${APP} Installation Found!"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
if check_for_gh_release "netboot-xyz" "netbootxyz/netboot.xyz"; then
|
|
||||||
msg_info "Backing up Configuration"
|
|
||||||
cp /var/www/html/boot.cfg /opt/netboot-xyz-boot.cfg.bak
|
|
||||||
msg_ok "Backed up Configuration"
|
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "netboot-xyz" "netbootxyz/netboot.xyz" "prebuild" "latest" "/var/www/html" "menus.tar.gz"
|
|
||||||
|
|
||||||
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-efi" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz.efi"
|
|
||||||
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-efi-dsk" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz.efi.dsk"
|
|
||||||
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-snp" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz-snp.efi"
|
|
||||||
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-snp-dsk" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz-snp.efi.dsk"
|
|
||||||
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-snponly" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz-snponly.efi"
|
|
||||||
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-metal" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz-metal.efi"
|
|
||||||
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-metal-dsk" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz-metal.efi.dsk"
|
|
||||||
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-metal-snp" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz-metal-snp.efi"
|
|
||||||
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-metal-snp-dsk" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz-metal-snp.efi.dsk"
|
|
||||||
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-metal-snponly" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz-metal-snponly.efi"
|
|
||||||
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-kpxe" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz.kpxe"
|
|
||||||
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-undionly" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz-undionly.kpxe"
|
|
||||||
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-metal-kpxe" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz-metal.kpxe"
|
|
||||||
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-lkrn" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz.lkrn"
|
|
||||||
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-linux-bin" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz-linux.bin"
|
|
||||||
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-dsk" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz.dsk"
|
|
||||||
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-pdsk" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz.pdsk"
|
|
||||||
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-arm64" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz-arm64.efi"
|
|
||||||
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-arm64-snp" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz-arm64-snp.efi"
|
|
||||||
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-arm64-snponly" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz-arm64-snponly.efi"
|
|
||||||
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-metal-arm64" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz-metal-arm64.efi"
|
|
||||||
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-metal-arm64-snp" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz-metal-arm64-snp.efi"
|
|
||||||
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-metal-arm64-snponly" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz-metal-arm64-snponly.efi"
|
|
||||||
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-iso" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz.iso"
|
|
||||||
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-img" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz.img"
|
|
||||||
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-arm64-iso" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz-arm64.iso"
|
|
||||||
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-arm64-img" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz-arm64.img"
|
|
||||||
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-multiarch-iso" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz-multiarch.iso"
|
|
||||||
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-multiarch-img" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz-multiarch.img"
|
|
||||||
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-checksums" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz-sha256-checksums.txt"
|
|
||||||
|
|
||||||
msg_info "Restoring Configuration"
|
|
||||||
cp /opt/netboot-xyz-boot.cfg.bak /var/www/html/boot.cfg
|
|
||||||
rm -f /opt/netboot-xyz-boot.cfg.bak
|
|
||||||
msg_ok "Restored Configuration"
|
|
||||||
|
|
||||||
msg_ok "Updated successfully!"
|
|
||||||
fi
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed Successfully!\n"
|
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
|
||||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"
|
|
||||||
76
ct/nextexplorer.sh
Normal file
76
ct/nextexplorer.sh
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
||||||
|
|
||||||
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
|
# Author: vhsdream
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
||||||
|
# Source: https://github.com/nxzai/nextExplorer
|
||||||
|
|
||||||
|
APP="nextExplorer"
|
||||||
|
var_tags="${var_tags:-files;documents}"
|
||||||
|
var_cpu="${var_cpu:-2}"
|
||||||
|
var_ram="${var_ram:-3072}"
|
||||||
|
var_disk="${var_disk:-8}"
|
||||||
|
var_os="${var_os:-debian}"
|
||||||
|
var_version="${var_version:-13}"
|
||||||
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
|
|
||||||
|
header_info "$APP"
|
||||||
|
variables
|
||||||
|
color
|
||||||
|
catch_errors
|
||||||
|
|
||||||
|
function update_script() {
|
||||||
|
header_info
|
||||||
|
check_container_storage
|
||||||
|
check_container_resources
|
||||||
|
|
||||||
|
if [[ ! -d /opt/nextExplorer ]]; then
|
||||||
|
msg_error "No ${APP} Installation Found!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
NODE_VERSION="24" setup_nodejs
|
||||||
|
|
||||||
|
if check_for_gh_release "nextExplorer" "nxzai/nextExplorer"; then
|
||||||
|
msg_info "Stopping nextExplorer"
|
||||||
|
$STD systemctl stop nextexplorer
|
||||||
|
msg_ok "Stopped nextExplorer"
|
||||||
|
|
||||||
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "nextExplorer" "nxzai/nextExplorer" "tarball" "latest" "/opt/nextExplorer"
|
||||||
|
|
||||||
|
msg_info "Updating nextExplorer"
|
||||||
|
APP_DIR="/opt/nextExplorer/app"
|
||||||
|
mkdir -p "$APP_DIR"
|
||||||
|
cd /opt/nextExplorer
|
||||||
|
export NODE_ENV=production
|
||||||
|
$STD npm ci --omit=dev --workspace backend
|
||||||
|
mv node_modules "$APP_DIR"
|
||||||
|
mv backend/{src,package.json} "$APP_DIR"
|
||||||
|
unset NODE_ENV
|
||||||
|
export NODE_ENV=development
|
||||||
|
$STD npm ci --workspace frontend
|
||||||
|
$STD npm run -w frontend build -- --sourcemap false
|
||||||
|
unset NODE_ENV
|
||||||
|
mv frontend/dist/ "$APP_DIR"/src/public
|
||||||
|
chown -R explorer:explorer "$APP_DIR" /etc/nextExplorer
|
||||||
|
sed -i "\|version|s|$(jq -cr '.version' ${APP_DIR}/package.json)|$(cat ~/.nextexplorer)|" "$APP_DIR"/package.json
|
||||||
|
sed -i 's/app.js/server.js/' /etc/systemd/system/nextexplorer.service && systemctl daemon-reload
|
||||||
|
msg_ok "Updated nextExplorer"
|
||||||
|
|
||||||
|
msg_info "Starting nextExplorer"
|
||||||
|
$STD systemctl start nextexplorer
|
||||||
|
msg_ok "Started nextExplorer"
|
||||||
|
msg_ok "Updated successfully!"
|
||||||
|
fi
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
start
|
||||||
|
build_container
|
||||||
|
description
|
||||||
|
|
||||||
|
msg_ok "Completed successfully!\n"
|
||||||
|
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||||
|
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
||||||
|
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}"
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
|
||||||
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
|
||||||
# Author: vhsdream
|
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
|
||||||
# Source: https://github.com/DioCrafts/OxiCloud
|
|
||||||
|
|
||||||
APP="OxiCloud"
|
|
||||||
var_tags="${var_tags:-files;documents}"
|
|
||||||
var_cpu="${var_cpu:-2}"
|
|
||||||
var_ram="${var_ram:-3072}"
|
|
||||||
var_disk="${var_disk:-20}"
|
|
||||||
var_os="${var_os:-debian}"
|
|
||||||
var_version="${var_version:-13}"
|
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
|
||||||
|
|
||||||
header_info "$APP"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
check_container_storage
|
|
||||||
check_container_resources
|
|
||||||
|
|
||||||
if [[ ! -d /opt/oxicloud ]]; then
|
|
||||||
msg_error "No ${APP} Installation Found!"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
if check_for_gh_release "OxiCloud" "DioCrafts/OxiCloud"; then
|
|
||||||
msg_info "Stopping OxiCloud"
|
|
||||||
systemctl stop oxicloud
|
|
||||||
msg_ok "Stopped OxiCloud"
|
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "OxiCloud" "DioCrafts/OxiCloud" "tarball" "latest" "/opt/oxicloud"
|
|
||||||
TOOLCHAIN="$(sed -n '2s/[^:]*://p' /opt/oxicloud/Dockerfile | awk -F- '{print $1}')"
|
|
||||||
RUST_TOOLCHAIN=$TOOLCHAIN setup_rust
|
|
||||||
|
|
||||||
msg_info "Updating OxiCloud"
|
|
||||||
source /etc/oxicloud/.env
|
|
||||||
cd /opt/oxicloud
|
|
||||||
export DATABASE_URL
|
|
||||||
export RUSTFLAGS="-C target-cpu=native"
|
|
||||||
$STD cargo build --release
|
|
||||||
mv target/release/oxicloud /usr/bin/oxicloud && chmod +x /usr/bin/oxicloud
|
|
||||||
msg_ok "Updated OxiCloud"
|
|
||||||
|
|
||||||
msg_info "Starting OxiCloud"
|
|
||||||
$STD systemctl start oxicloud
|
|
||||||
msg_ok "Started OxiCloud"
|
|
||||||
msg_ok "Updated successfully!"
|
|
||||||
fi
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed successfully!\n"
|
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
|
||||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8086${CL}"
|
|
||||||
@@ -36,17 +36,14 @@ function update_script() {
|
|||||||
msg_ok "Services stopped"
|
msg_ok "Services stopped"
|
||||||
|
|
||||||
msg_info "Backing up Configuration"
|
msg_info "Backing up Configuration"
|
||||||
cp /opt/pixelfed/.env /opt/pixelfed.env.bak
|
cp /opt/pixelfed/.env /tmp/pixelfed.env.bak
|
||||||
cp -r /opt/pixelfed/storage /opt/pixelfed-storage.bak
|
|
||||||
msg_ok "Configuration backed up"
|
msg_ok "Configuration backed up"
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "pixelfed" "pixelfed/pixelfed" "tarball" "latest" "/opt/pixelfed"
|
fetch_and_deploy_gh_release "pixelfed" "pixelfed/pixelfed" "tarball" "latest" "/opt/pixelfed"
|
||||||
|
|
||||||
msg_info "Restoring Configuration"
|
msg_info "Restoring Configuration"
|
||||||
cp /opt/pixelfed.env.bak /opt/pixelfed/.env
|
cp /tmp/pixelfed.env.bak /opt/pixelfed/.env
|
||||||
cp -r /opt/pixelfed-storage.bak /opt/pixelfed/storage
|
rm -f /tmp/pixelfed.env.bak
|
||||||
rm -f /opt/pixelfed.env.bak
|
|
||||||
rm -rf /opt/pixelfed-storage.bak
|
|
||||||
msg_ok "Configuration restored"
|
msg_ok "Configuration restored"
|
||||||
|
|
||||||
msg_info "Updating Pixelfed"
|
msg_info "Updating Pixelfed"
|
||||||
@@ -55,7 +52,6 @@ function update_script() {
|
|||||||
chmod -R 775 /opt/pixelfed/storage /opt/pixelfed/bootstrap/cache
|
chmod -R 775 /opt/pixelfed/storage /opt/pixelfed/bootstrap/cache
|
||||||
export COMPOSER_ALLOW_SUPERUSER=1
|
export COMPOSER_ALLOW_SUPERUSER=1
|
||||||
$STD composer install --no-dev --no-ansi --no-interaction --optimize-autoloader
|
$STD composer install --no-dev --no-ansi --no-interaction --optimize-autoloader
|
||||||
$STD sudo -u pixelfed php artisan storage:link
|
|
||||||
$STD sudo -u pixelfed php artisan migrate --force
|
$STD sudo -u pixelfed php artisan migrate --force
|
||||||
$STD sudo -u pixelfed php artisan route:cache
|
$STD sudo -u pixelfed php artisan route:cache
|
||||||
$STD sudo -u pixelfed php artisan view:cache
|
$STD sudo -u pixelfed php artisan view:cache
|
||||||
@@ -81,3 +77,5 @@ echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
|||||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"
|
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"
|
||||||
echo -e "${INFO}${YW} Create an admin account with:${CL}"
|
echo -e "${INFO}${YW} Create an admin account with:${CL}"
|
||||||
echo -e "${TAB}cd /opt/pixelfed && sudo -u pixelfed php artisan user:create"
|
echo -e "${TAB}cd /opt/pixelfed && sudo -u pixelfed php artisan user:create"
|
||||||
|
echo -e "${INFO}${YW} Credentials saved in:${CL}"
|
||||||
|
echo -e "${TAB}/root/pixelfed.creds"
|
||||||
|
|||||||
96
ct/plane.sh
96
ct/plane.sh
@@ -1,96 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
|
||||||
# Author: onionrings29
|
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
|
||||||
# Source: https://plane.so | GitHub: https://github.com/makeplane/plane
|
|
||||||
|
|
||||||
APP="Plane"
|
|
||||||
var_tags="${var_tags:-project-management}"
|
|
||||||
var_cpu="${var_cpu:-4}"
|
|
||||||
var_ram="${var_ram:-6144}"
|
|
||||||
var_disk="${var_disk:-8}"
|
|
||||||
var_os="${var_os:-debian}"
|
|
||||||
var_version="${var_version:-13}"
|
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
|
||||||
|
|
||||||
header_info "$APP"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
check_container_storage
|
|
||||||
check_container_resources
|
|
||||||
|
|
||||||
if [[ ! -d /opt/plane ]]; then
|
|
||||||
msg_error "No Plane Installation Found!"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if check_for_gh_release "plane" "makeplane/plane"; then
|
|
||||||
msg_info "Stopping Services"
|
|
||||||
systemctl stop plane-api plane-worker plane-beat plane-live plane-space
|
|
||||||
msg_ok "Stopped Services"
|
|
||||||
|
|
||||||
msg_info "Backing up Data"
|
|
||||||
cp /opt/plane/apps/api/.env /opt/plane-api-env.bak
|
|
||||||
cp /opt/plane/.env /opt/plane-live-env.bak
|
|
||||||
cp /opt/plane/apps/web/.env /opt/plane-web-env.bak
|
|
||||||
cp /opt/plane/apps/admin/.env /opt/plane-admin-env.bak
|
|
||||||
cp /opt/plane/apps/space/.env /opt/plane-space-env.bak
|
|
||||||
msg_ok "Backed up Data"
|
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "plane" "makeplane/plane" "tarball"
|
|
||||||
|
|
||||||
msg_info "Restoring Config"
|
|
||||||
cp /opt/plane-api-env.bak /opt/plane/apps/api/.env
|
|
||||||
cp /opt/plane-live-env.bak /opt/plane/.env
|
|
||||||
cp /opt/plane-web-env.bak /opt/plane/apps/web/.env
|
|
||||||
cp /opt/plane-admin-env.bak /opt/plane/apps/admin/.env
|
|
||||||
cp /opt/plane-space-env.bak /opt/plane/apps/space/.env
|
|
||||||
rm -f /opt/plane-api-env.bak /opt/plane-live-env.bak /opt/plane-web-env.bak /opt/plane-admin-env.bak /opt/plane-space-env.bak
|
|
||||||
msg_ok "Restored Config"
|
|
||||||
|
|
||||||
msg_info "Rebuilding Frontend (Patience)"
|
|
||||||
cd /opt/plane
|
|
||||||
export NODE_OPTIONS="--max-old-space-size=4096"
|
|
||||||
export COREPACK_ENABLE_DOWNLOAD_PROMPT=0
|
|
||||||
$STD corepack enable pnpm
|
|
||||||
$STD pnpm install --frozen-lockfile
|
|
||||||
$STD pnpm turbo run build --filter=web --filter=admin --filter=space --filter=live
|
|
||||||
msg_ok "Rebuilt Frontend"
|
|
||||||
|
|
||||||
msg_info "Updating Python Dependencies"
|
|
||||||
cd /opt/plane/apps/api
|
|
||||||
export VIRTUAL_ENV=/opt/plane-venv
|
|
||||||
$STD uv pip install --upgrade -r requirements/production.txt
|
|
||||||
msg_ok "Updated Python Dependencies"
|
|
||||||
|
|
||||||
msg_info "Running Migrations"
|
|
||||||
cd /opt/plane/apps/api
|
|
||||||
set -a
|
|
||||||
source /opt/plane/apps/api/.env
|
|
||||||
set +a
|
|
||||||
$STD /opt/plane-venv/bin/python manage.py migrate
|
|
||||||
$STD /opt/plane-venv/bin/python manage.py collectstatic --noinput
|
|
||||||
$STD /opt/plane-venv/bin/python manage.py configure_instance
|
|
||||||
msg_ok "Ran Migrations"
|
|
||||||
|
|
||||||
msg_info "Starting Services"
|
|
||||||
systemctl start plane-api plane-worker plane-beat plane-live plane-space
|
|
||||||
msg_ok "Started Services"
|
|
||||||
msg_ok "Updated successfully!"
|
|
||||||
fi
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed successfully!\n"
|
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
|
||||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
|
||||||
# Author: Stephen Chin (steveonjava)
|
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
|
||||||
# Source: https://github.com/ProtonMail/proton-bridge
|
|
||||||
|
|
||||||
APP="ProtonMail-Bridge"
|
|
||||||
var_tags="${var_tags:-mail;proton}"
|
|
||||||
var_cpu="${var_cpu:-2}"
|
|
||||||
var_ram="${var_ram:-1024}"
|
|
||||||
var_disk="${var_disk:-8}"
|
|
||||||
var_os="${var_os:-debian}"
|
|
||||||
var_version="${var_version:-13}"
|
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
|
||||||
|
|
||||||
header_info "$APP"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
check_container_storage
|
|
||||||
check_container_resources
|
|
||||||
|
|
||||||
if [[ ! -x /usr/bin/protonmail-bridge ]]; then
|
|
||||||
msg_error "No ${APP} Installation Found!"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if check_for_gh_release "protonmail-bridge" "ProtonMail/proton-bridge"; then
|
|
||||||
local -a bridge_units=(
|
|
||||||
protonmail-bridge
|
|
||||||
protonmail-bridge-imap.socket
|
|
||||||
protonmail-bridge-smtp.socket
|
|
||||||
protonmail-bridge-imap-proxy
|
|
||||||
protonmail-bridge-smtp-proxy
|
|
||||||
)
|
|
||||||
local unit
|
|
||||||
declare -A was_active
|
|
||||||
for unit in "${bridge_units[@]}"; do
|
|
||||||
if systemctl is-active --quiet "$unit" 2>/dev/null; then
|
|
||||||
was_active["$unit"]=1
|
|
||||||
else
|
|
||||||
was_active["$unit"]=0
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
msg_info "Stopping Services"
|
|
||||||
systemctl stop protonmail-bridge-imap.socket protonmail-bridge-smtp.socket protonmail-bridge-imap-proxy protonmail-bridge-smtp-proxy protonmail-bridge
|
|
||||||
msg_ok "Stopped Services"
|
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "protonmail-bridge" "ProtonMail/proton-bridge" "binary"
|
|
||||||
|
|
||||||
if [[ -f /home/protonbridge/.protonmailbridge-initialized ]]; then
|
|
||||||
msg_info "Starting Services"
|
|
||||||
for unit in "${bridge_units[@]}"; do
|
|
||||||
if [[ "${was_active[$unit]:-0}" == "1" ]]; then
|
|
||||||
systemctl start "$unit"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
msg_ok "Started Services"
|
|
||||||
else
|
|
||||||
msg_ok "Initialization not completed. Services remain disabled."
|
|
||||||
fi
|
|
||||||
msg_ok "Updated successfully!"
|
|
||||||
fi
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed successfully!\n"
|
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
|
||||||
echo -e "${INFO}${YW}One-time configuration is required before Bridge services are enabled.${CL}"
|
|
||||||
echo -e "${INFO}${YW}Run this command in the container: protonmailbridge-configure${CL}"
|
|
||||||
@@ -53,7 +53,7 @@ function update_script() {
|
|||||||
msg_info "Running Database Migrations"
|
msg_info "Running Database Migrations"
|
||||||
cd /opt/simplelogin
|
cd /opt/simplelogin
|
||||||
cp /opt/simplelogin_env.bak /opt/simplelogin/.env
|
cp /opt/simplelogin_env.bak /opt/simplelogin/.env
|
||||||
$STD .venv/bin/alembic upgrade head
|
$STD .venv/bin/flask db upgrade
|
||||||
msg_ok "Ran Database Migrations"
|
msg_ok "Ran Database Migrations"
|
||||||
|
|
||||||
msg_info "Restoring Data"
|
msg_info "Restoring Data"
|
||||||
|
|||||||
@@ -36,14 +36,14 @@ function update_script() {
|
|||||||
msg_ok "Stopped Service"
|
msg_ok "Stopped Service"
|
||||||
|
|
||||||
msg_info "Backing up Data"
|
msg_info "Backing up Data"
|
||||||
cp /opt/skylite-ux/.env /opt/skylite-ux.env.bak
|
cp /opt/skylite-ux/.env /tmp/skylite-ux.env.backup
|
||||||
msg_ok "Backed up Data"
|
msg_ok "Backed up Data"
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "skylite-ux" "Wetzel402/Skylite-UX" "tarball"
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "skylite-ux" "Wetzel402/Skylite-UX" "tarball"
|
||||||
|
|
||||||
msg_info "Restoring Data"
|
msg_info "Restoring Data"
|
||||||
cp /opt/skylite-ux.env.bak /opt/skylite-ux/.env
|
cp /tmp/skylite-ux.env.backup /opt/skylite-ux/.env
|
||||||
rm -f /opt/skylite-ux.env.bak
|
rm -f /tmp/skylite-ux.env.backup
|
||||||
msg_ok "Restored Data"
|
msg_ok "Restored Data"
|
||||||
|
|
||||||
msg_info "Building Skylite-UX"
|
msg_info "Building Skylite-UX"
|
||||||
|
|||||||
67
ct/split-pro.sh
Normal file
67
ct/split-pro.sh
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
||||||
|
|
||||||
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
|
# Author: johanngrobe
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
# Source: https://github.com/oss-apps/split-pro
|
||||||
|
|
||||||
|
APP="Split-Pro"
|
||||||
|
var_tags="${var_tags:-finance;expense-sharing}"
|
||||||
|
var_cpu="${var_cpu:-2}"
|
||||||
|
var_ram="${var_ram:-4096}"
|
||||||
|
var_disk="${var_disk:-6}"
|
||||||
|
var_os="${var_os:-debian}"
|
||||||
|
var_version="${var_version:-13}"
|
||||||
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
|
|
||||||
|
variables
|
||||||
|
color
|
||||||
|
catch_errors
|
||||||
|
|
||||||
|
function update_script() {
|
||||||
|
header_info
|
||||||
|
check_container_storage
|
||||||
|
check_container_resources
|
||||||
|
|
||||||
|
if [[ ! -d /opt/split-pro ]]; then
|
||||||
|
msg_error "No Split Pro Installation Found!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
if check_for_gh_release "split-pro" "oss-apps/split-pro"; then
|
||||||
|
msg_info "Stopping Service"
|
||||||
|
systemctl stop split-pro
|
||||||
|
msg_ok "Stopped Service"
|
||||||
|
|
||||||
|
msg_info "Backing up Data"
|
||||||
|
cp /opt/split-pro/.env /opt/split-pro.env
|
||||||
|
msg_ok "Backed up Data"
|
||||||
|
|
||||||
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "split-pro" "oss-apps/split-pro" "tarball" "latest" "/opt/split-pro"
|
||||||
|
|
||||||
|
msg_info "Building Application"
|
||||||
|
cd /opt/split-pro
|
||||||
|
$STD pnpm install --frozen-lockfile
|
||||||
|
$STD pnpm build
|
||||||
|
cp /opt/split-pro.env /opt/split-pro/.env
|
||||||
|
rm -f /opt/split-pro.env
|
||||||
|
ln -sf /opt/split-pro_data/uploads /opt/split-pro/uploads
|
||||||
|
$STD pnpm exec prisma migrate deploy
|
||||||
|
msg_ok "Built Application"
|
||||||
|
|
||||||
|
msg_info "Starting Service"
|
||||||
|
systemctl start split-pro
|
||||||
|
msg_ok "Started Service"
|
||||||
|
msg_ok "Updated successfully!"
|
||||||
|
fi
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
start
|
||||||
|
build_container
|
||||||
|
description
|
||||||
|
msg_ok "Completed successfully!\n"
|
||||||
|
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||||
|
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
||||||
|
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}"
|
||||||
@@ -35,8 +35,9 @@ function update_script() {
|
|||||||
|
|
||||||
if check_for_gh_release "step-badger" "lukasz-lobocki/step-badger"; then
|
if check_for_gh_release "step-badger" "lukasz-lobocki/step-badger"; then
|
||||||
fetch_and_deploy_gh_release "step-badger" "lukasz-lobocki/step-badger" "prebuild" "latest" "/opt/step-badger" "step-badger_Linux_x86_64.tar.gz"
|
fetch_and_deploy_gh_release "step-badger" "lukasz-lobocki/step-badger" "prebuild" "latest" "/opt/step-badger" "step-badger_Linux_x86_64.tar.gz"
|
||||||
msg_ok "Updated step-badger"
|
msg_ok "Updated successfully!"
|
||||||
fi
|
fi
|
||||||
|
msg_ok "Updated successfully!"
|
||||||
exit
|
exit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,54 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
|
||||||
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
|
||||||
# Author: community-scripts
|
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
|
||||||
# Source: https://github.com/storybookjs/storybook
|
|
||||||
|
|
||||||
APP="Storybook"
|
|
||||||
var_tags="${var_tags:-dev-tools;frontend;ui}"
|
|
||||||
var_cpu="${var_cpu:-2}"
|
|
||||||
var_ram="${var_ram:-2048}"
|
|
||||||
var_disk="${var_disk:-8}"
|
|
||||||
var_os="${var_os:-debian}"
|
|
||||||
var_version="${var_version:-13}"
|
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
|
||||||
|
|
||||||
header_info "$APP"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
check_container_storage
|
|
||||||
check_container_resources
|
|
||||||
|
|
||||||
if [[ ! -f /opt/storybook/.projectpath ]]; then
|
|
||||||
msg_error "No ${APP} Installation Found!"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
PROJECT_PATH=$(cat /opt/storybook/.projectpath)
|
|
||||||
|
|
||||||
if [[ ! -d "$PROJECT_PATH" ]]; then
|
|
||||||
msg_error "Project directory not found: $PROJECT_PATH"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
msg_info "Updating Storybook"
|
|
||||||
cd "$PROJECT_PATH"
|
|
||||||
$STD npx storybook@latest upgrade --yes
|
|
||||||
msg_ok "Updated Storybook"
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed Successfully!\n"
|
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
|
||||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:6006${CL}"
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
|
||||||
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
|
||||||
# Author: community-scripts
|
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
|
||||||
# Source: https://gitlab.com/storyteller-platform/storyteller
|
|
||||||
|
|
||||||
APP="Storyteller"
|
|
||||||
var_tags="${var_tags:-media;ebook;audiobook}"
|
|
||||||
var_cpu="${var_cpu:-4}"
|
|
||||||
var_ram="${var_ram:-10240}"
|
|
||||||
var_disk="${var_disk:-20}"
|
|
||||||
var_os="${var_os:-debian}"
|
|
||||||
var_version="${var_version:-13}"
|
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
|
||||||
|
|
||||||
header_info "$APP"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
check_container_storage
|
|
||||||
check_container_resources
|
|
||||||
|
|
||||||
if [[ ! -d /opt/storyteller ]]; then
|
|
||||||
msg_error "No ${APP} Installation Found!"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
msg_info "Stopping Service"
|
|
||||||
systemctl stop storyteller
|
|
||||||
msg_ok "Stopped Service"
|
|
||||||
|
|
||||||
msg_info "Backing up Data"
|
|
||||||
cp /opt/storyteller/.env /opt/storyteller_env.bak
|
|
||||||
msg_ok "Backed up Data"
|
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gl_release "storyteller" "storyteller-platform/storyteller" "tarball" "latest" "/opt/storyteller"
|
|
||||||
|
|
||||||
msg_info "Restoring Configuration"
|
|
||||||
mv /opt/storyteller_env.bak /opt/storyteller/.env
|
|
||||||
msg_ok "Restored Configuration"
|
|
||||||
|
|
||||||
msg_info "Rebuilding Storyteller"
|
|
||||||
cd /opt/storyteller
|
|
||||||
export NODE_OPTIONS="--max-old-space-size=4096"
|
|
||||||
$STD yarn install --network-timeout 600000
|
|
||||||
$STD gcc -g -fPIC -rdynamic -shared web/sqlite/uuid.c -o web/sqlite/uuid.c.so
|
|
||||||
export CI=1
|
|
||||||
export NODE_ENV=production
|
|
||||||
export NEXT_TELEMETRY_DISABLED=1
|
|
||||||
export SQLITE_NATIVE_BINDING=/opt/storyteller/node_modules/better-sqlite3/build/Release/better_sqlite3.node
|
|
||||||
$STD yarn workspaces foreach -Rpt --from @storyteller-platform/web --exclude @storyteller-platform/eslint run build
|
|
||||||
mkdir -p /opt/storyteller/web/.next/standalone/web/.next/static
|
|
||||||
cp -rT /opt/storyteller/web/.next/static /opt/storyteller/web/.next/standalone/web/.next/static
|
|
||||||
if [[ -d /opt/storyteller/web/public ]]; then
|
|
||||||
mkdir -p /opt/storyteller/web/.next/standalone/web/public
|
|
||||||
cp -rT /opt/storyteller/web/public /opt/storyteller/web/.next/standalone/web/public
|
|
||||||
fi
|
|
||||||
mkdir -p /opt/storyteller/web/.next/standalone/web/migrations
|
|
||||||
cp -rT /opt/storyteller/web/migrations /opt/storyteller/web/.next/standalone/web/migrations
|
|
||||||
mkdir -p /opt/storyteller/web/.next/standalone/web/sqlite
|
|
||||||
cp -rT /opt/storyteller/web/sqlite /opt/storyteller/web/.next/standalone/web/sqlite
|
|
||||||
ln -sf /opt/storyteller/.env /opt/storyteller/web/.next/standalone/web/.env
|
|
||||||
msg_ok "Rebuilt Storyteller"
|
|
||||||
|
|
||||||
msg_info "Starting Service"
|
|
||||||
systemctl start storyteller
|
|
||||||
msg_ok "Started Service"
|
|
||||||
msg_ok "Updated successfully!"
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed Successfully!\n"
|
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
|
||||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8001${CL}"
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
|
||||||
# Author: PouletteMC
|
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
|
||||||
# Source: https://surrealdb.com
|
|
||||||
|
|
||||||
APP="SurrealDB"
|
|
||||||
var_tags="${var_tags:-database;nosql}"
|
|
||||||
var_cpu="${var_cpu:-2}"
|
|
||||||
var_ram="${var_ram:-1024}"
|
|
||||||
var_disk="${var_disk:-4}"
|
|
||||||
var_os="${var_os:-debian}"
|
|
||||||
var_version="${var_version:-13}"
|
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
|
||||||
|
|
||||||
header_info "$APP"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
check_container_storage
|
|
||||||
check_container_resources
|
|
||||||
|
|
||||||
if [[ ! -f /opt/surrealdb/surreal ]]; then
|
|
||||||
msg_error "No SurrealDB Installation Found!"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
if check_for_gh_release "surrealdb" "surrealdb/surrealdb"; then
|
|
||||||
msg_info "Stopping Service"
|
|
||||||
systemctl stop surrealdb
|
|
||||||
msg_ok "Stopped Service"
|
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "surrealdb" "surrealdb/surrealdb" "prebuild" "latest" "/opt/surrealdb" "surreal-v*.linux-amd64.tgz"
|
|
||||||
chmod +x /opt/surrealdb/surreal
|
|
||||||
|
|
||||||
msg_info "Starting Service"
|
|
||||||
systemctl start surrealdb
|
|
||||||
msg_ok "Started Service"
|
|
||||||
msg_ok "Updated successfully!"
|
|
||||||
fi
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed Successfully!\n"
|
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
|
||||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8000${CL}"
|
|
||||||
82
ct/teable.sh
82
ct/teable.sh
@@ -1,82 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
|
||||||
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
|
||||||
# Author: community-scripts
|
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
|
||||||
# Source: https://github.com/teableio/teable
|
|
||||||
|
|
||||||
APP="Teable"
|
|
||||||
var_tags="${var_tags:-database;no-code;spreadsheet}"
|
|
||||||
var_cpu="${var_cpu:-4}"
|
|
||||||
var_ram="${var_ram:-10240}"
|
|
||||||
var_disk="${var_disk:-25}"
|
|
||||||
var_os="${var_os:-debian}"
|
|
||||||
var_version="${var_version:-13}"
|
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
|
||||||
|
|
||||||
header_info "$APP"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
check_container_storage
|
|
||||||
check_container_resources
|
|
||||||
|
|
||||||
if [[ ! -d /opt/teable ]]; then
|
|
||||||
msg_error "No ${APP} Installation Found!"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
if check_for_gh_release "teable" "teableio/teable"; then
|
|
||||||
msg_info "Stopping Service"
|
|
||||||
systemctl stop teable
|
|
||||||
msg_ok "Stopped Service"
|
|
||||||
|
|
||||||
msg_info "Backing up Configuration"
|
|
||||||
cp /opt/teable/.env /opt/teable.env.bak
|
|
||||||
msg_ok "Backed up Configuration"
|
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "teable" "teableio/teable" "tarball"
|
|
||||||
|
|
||||||
msg_info "Restoring Configuration"
|
|
||||||
mv /opt/teable.env.bak /opt/teable/.env
|
|
||||||
msg_ok "Restored Configuration"
|
|
||||||
|
|
||||||
msg_info "Rebuilding Teable"
|
|
||||||
cd /opt/teable
|
|
||||||
TEABLE_VERSION=$(cat ~/.teable)
|
|
||||||
echo "NEXT_PUBLIC_BUILD_VERSION=\"${TEABLE_VERSION}\"" >>apps/nextjs-app/.env
|
|
||||||
export HUSKY=0
|
|
||||||
export NODE_OPTIONS="--max-old-space-size=8192"
|
|
||||||
$STD pnpm install --frozen-lockfile
|
|
||||||
$STD pnpm -F @teable/db-main-prisma prisma-generate --schema ./prisma/postgres/schema.prisma
|
|
||||||
NODE_ENV=production NEXT_BUILD_ENV_TYPECHECK=false \
|
|
||||||
$STD pnpm -r --filter '!playground' run build
|
|
||||||
msg_ok "Rebuilt Teable"
|
|
||||||
|
|
||||||
msg_info "Running Database Migrations"
|
|
||||||
source /opt/teable/.env
|
|
||||||
$STD pnpm -F @teable/db-main-prisma prisma-migrate deploy --schema ./prisma/postgres/schema.prisma
|
|
||||||
msg_ok "Ran Database Migrations"
|
|
||||||
|
|
||||||
msg_info "Starting Service"
|
|
||||||
systemctl start teable
|
|
||||||
msg_ok "Started Service"
|
|
||||||
msg_ok "Updated successfully!"
|
|
||||||
else
|
|
||||||
msg_ok "No update available."
|
|
||||||
fi
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed Successfully!\n"
|
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
|
||||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}"
|
|
||||||
@@ -3,7 +3,7 @@ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxV
|
|||||||
|
|
||||||
# Copyright (c) 2021-2025 community-scripts ORG
|
# Copyright (c) 2021-2025 community-scripts ORG
|
||||||
# Author: KernelSailor
|
# Author: KernelSailor
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
# Source: https://snowflake.torproject.org/
|
# Source: https://snowflake.torproject.org/
|
||||||
|
|
||||||
APP="tor-snowflake"
|
APP="tor-snowflake"
|
||||||
@@ -32,7 +32,7 @@ function update_script() {
|
|||||||
msg_ok "Updated Container OS"
|
msg_ok "Updated Container OS"
|
||||||
|
|
||||||
RELEASE=$(curl -fsSL https://gitlab.torproject.org/api/v4/projects/tpo%2Fanti-censorship%2Fpluggable-transports%2Fsnowflake/releases | jq -r '.[0].tag_name' | sed 's/^v//')
|
RELEASE=$(curl -fsSL https://gitlab.torproject.org/api/v4/projects/tpo%2Fanti-censorship%2Fpluggable-transports%2Fsnowflake/releases | jq -r '.[0].tag_name' | sed 's/^v//')
|
||||||
if [[ ! -f ~/.tor-snowflake ]] || [[ "${RELEASE}" != "$(cat ~/.tor-snowflake)" ]]; then
|
if [[ ! -f "~/.tor-snowflake" ]] || [[ "${RELEASE}" != "$(cat "~/.tor-snowflake")" ]]; then
|
||||||
msg_info "Stopping Service"
|
msg_info "Stopping Service"
|
||||||
systemctl stop snowflake-proxy
|
systemctl stop snowflake-proxy
|
||||||
msg_ok "Stopped Service"
|
msg_ok "Stopped Service"
|
||||||
@@ -41,12 +41,12 @@ function update_script() {
|
|||||||
|
|
||||||
msg_info "Updating Snowflake"
|
msg_info "Updating Snowflake"
|
||||||
$STD curl -fsSL "https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/-/archive/v${RELEASE}/snowflake-v${RELEASE}.tar.gz" -o /opt/snowflake.tar.gz
|
$STD curl -fsSL "https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/-/archive/v${RELEASE}/snowflake-v${RELEASE}.tar.gz" -o /opt/snowflake.tar.gz
|
||||||
tar -xzf /opt/snowflake.tar.gz -C /opt
|
$STD tar -xzf /opt/snowflake.tar.gz -C /opt
|
||||||
rm -rf /opt/snowflake.tar.gz
|
$STD rm -rf /opt/snowflake.tar.gz
|
||||||
rm -rf /opt/tor-snowflake
|
$STD rm -rf /opt/tor-snowflake
|
||||||
mv /opt/snowflake-v${RELEASE} /opt/tor-snowflake
|
$STD mv /opt/snowflake-v${RELEASE} /opt/tor-snowflake
|
||||||
cd /opt/tor-snowflake/proxy
|
$STD chown -R snowflake:snowflake /opt/tor-snowflake
|
||||||
$STD go build -o snowflake-proxy .
|
$STD sudo -H -u snowflake bash -c "cd /opt/tor-snowflake/proxy && go build -o snowflake-proxy ."
|
||||||
echo "${RELEASE}" >~/.tor-snowflake
|
echo "${RELEASE}" >~/.tor-snowflake
|
||||||
msg_ok "Updated Snowflake to v${RELEASE}"
|
msg_ok "Updated Snowflake to v${RELEASE}"
|
||||||
|
|
||||||
|
|||||||
@@ -1,81 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
|
||||||
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
|
||||||
# Author: community-scripts
|
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
|
||||||
# Source: https://github.com/tubearchivist/tubearchivist
|
|
||||||
|
|
||||||
APP="Tube Archivist"
|
|
||||||
var_tags="${var_tags:-media;youtube;archiving}"
|
|
||||||
var_cpu="${var_cpu:-4}"
|
|
||||||
var_ram="${var_ram:-6144}"
|
|
||||||
var_disk="${var_disk:-30}"
|
|
||||||
var_os="${var_os:-debian}"
|
|
||||||
var_version="${var_version:-13}"
|
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
|
||||||
|
|
||||||
header_info "$APP"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
check_container_storage
|
|
||||||
check_container_resources
|
|
||||||
|
|
||||||
if [[ ! -d /opt/tubearchivist ]]; then
|
|
||||||
msg_error "No ${APP} Installation Found!"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
if check_for_gh_release "tubearchivist" "tubearchivist/tubearchivist"; then
|
|
||||||
msg_info "Stopping Services"
|
|
||||||
systemctl stop tubearchivist tubearchivist-celery tubearchivist-beat
|
|
||||||
msg_ok "Stopped Services"
|
|
||||||
|
|
||||||
msg_info "Backing up Data"
|
|
||||||
cp /opt/tubearchivist/.env /opt/tubearchivist_env.bak
|
|
||||||
msg_ok "Backed up Data"
|
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "tubearchivist" "tubearchivist/tubearchivist" "tarball" "latest" "/opt/tubearchivist"
|
|
||||||
|
|
||||||
msg_info "Rebuilding Tube Archivist"
|
|
||||||
cd /opt/tubearchivist/frontend
|
|
||||||
$STD npm install
|
|
||||||
$STD npm run build:deploy
|
|
||||||
mkdir -p /opt/tubearchivist/backend/static
|
|
||||||
cp -r /opt/tubearchivist/frontend/dist/* /opt/tubearchivist/backend/static/
|
|
||||||
cp /opt/tubearchivist/docker_assets/backend_start.py /opt/tubearchivist/backend/
|
|
||||||
$STD uv pip install --python /opt/tubearchivist/.venv/bin/python -r /opt/tubearchivist/backend/requirements.txt
|
|
||||||
if [[ -f /opt/tubearchivist/backend/requirements.plugins.txt ]]; then
|
|
||||||
mkdir -p /opt/yt_plugins/bgutil
|
|
||||||
$STD uv pip install --python /opt/tubearchivist/.venv/bin/python --target /opt/yt_plugins/bgutil -r /opt/tubearchivist/backend/requirements.plugins.txt
|
|
||||||
fi
|
|
||||||
msg_ok "Rebuilt Tube Archivist"
|
|
||||||
|
|
||||||
msg_info "Restoring Configuration"
|
|
||||||
mv /opt/tubearchivist_env.bak /opt/tubearchivist/.env
|
|
||||||
msg_ok "Restored Configuration"
|
|
||||||
|
|
||||||
msg_info "Starting Services"
|
|
||||||
systemctl start tubearchivist tubearchivist-celery tubearchivist-beat
|
|
||||||
systemctl reload nginx
|
|
||||||
msg_ok "Started Services"
|
|
||||||
msg_ok "Updated successfully!"
|
|
||||||
fi
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed Successfully!\n"
|
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
|
||||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8000${CL}"
|
|
||||||
echo -e "${INFO}${YW} Credentials:${CL}"
|
|
||||||
echo -e "${TAB}${BGN}Username: admin${CL}"
|
|
||||||
echo -e "${TAB}${BGN}Password: see ~/tubearchivist.creds${CL}"
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user