diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md deleted file mode 100644 index b000bd25ee..0000000000 --- a/.github/CONTRIBUTING.md +++ /dev/null @@ -1,14 +0,0 @@ -
- - - -
-

Contributing to Proxmox VE Helper Scripts

- -Everybody is invited and welcome to contribute to Proxmox VE Helper Scripts. - -- Pull requests submitted against [**main**](https://github.com/community-scripts/ProxmoxVE/tree/main) are meticulously scrutinized, so please do not take it personally if the project maintainer rejects your request. By adhering to the established patterns and conventions throughout the codebase, you greatly increase the likelihood that your changes will get merged into [**main**](https://github.com/community-scripts/ProxmoxVE/tree/main). - -- It is important to stress that complaining about a decision after it has been made is not productive behavior for the pull request submitter. It is crucial for all contributors to respect the decision-making process and collaborate effectively towards achieving the best possible outcome for the project. - -- The repository will only accept Alpine applications that make use of the Alpine Package Keeper. diff --git a/.github/CONTRIBUTOR_GUIDE/CONTRIBUTING.md b/.github/CONTRIBUTOR_GUIDE/CONTRIBUTING.md new file mode 100644 index 0000000000..1eca1fb079 --- /dev/null +++ b/.github/CONTRIBUTOR_GUIDE/CONTRIBUTING.md @@ -0,0 +1,108 @@ + +# Community Scripts Contribution Guide + +## **Welcome to the communty-scripts Repository!** +πŸ“œ These documents outlines the essential coding standards for all our scripts and JSON files. Adhering to these standards ensures that our codebase remains consistent, readable, and maintainable. By following these guidelines, we can improve collaboration, reduce errors, and enhance the overall quality of our project. + +### Why Coding Standards Matter + +Coding standards are crucial for several reasons: + +1. **Consistency**: Consistent code is easier to read, understand, and maintain. It helps new team members quickly get up to speed and reduces the learning curve. +2. **Readability**: Clear and well-structured code is easier to debug and extend. It allows developers to quickly identify and fix issues. +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. + +### Scope of These Documents + +These documents covers the coding standards for the following types of files in our project: + +- **`APP-install.sh` Scripts**: These scripts are responsible for the installation of applications and are located in the `/install` directory. +- **`APP.sh` Scripts**: These scripts handle the creation and updating of containers and are found in the `/ct` directory. +- **JSON Files**: These files store structured data and are located in the `/json` directory. + +Each section provides detailed guidelines on various aspects of coding, including shebang usage, comments, variable naming, function naming, indentation, error handling, command substitution, quoting, script structure, and logging. Additionally, examples are provided to illustrate the application of these standards. + +By following the coding standards outlined in this document, we ensure that our scripts and JSON files are of high quality, making our project more robust and easier to manage. Please refer to this guide whenever you create or update scripts and JSON files to maintain a high standard of code quality across the project. πŸ“šπŸ” + +Let's work together to keep our codebase clean, efficient, and maintainable! πŸ’ͺπŸš€ + + +## Getting Started + +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/ProxmoxVE/blob/contributor_guide/.github/CONTRIBUTOR_GUIDE/ct/AppName.sh) and [AppName-install.sh](https://github.com/community-scripts/ProxmoxVE/blob/contributor_guide/.github/CONTRIBUTOR_GUIDE/install/AppName-install.sh) as templates when creating new scripts. +- The call to `community-scripts/ProxmoxVE` should be adjusted to reflect the correct fork URL. + +--- + +# πŸš€ The Application Script (ct/AppName.sh) + +- You can find all coding standards, as well as the structure for this files [here](https://github.com/community-scripts/ProxmoxVE/blob/contributor_guide/.github/CONTRIBUTOR_GUIDE/ct/AppName.md). +- These Scripts are responsible for container creation, setting the necessary variables and handles the update of the application. + +--- + +# πŸ›  The Installation Script (install/AppName-install.sh) + +- You can find all coding standards, as well as the structure for this files [here](https://github.com/community-scripts/ProxmoxVE/blob/contributor_guide/.github/CONTRIBUTOR_GUIDE/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/ProxmoxVE/blob/contributor_guide/.github/CONTRIBUTOR_GUIDE/install/AppName-install.sh) + +--- + +## 🀝 Contribution Process + +### 1. Fork the Repository +Fork to your GitHub account + +### 2. Clone Your Fork on your Pc +```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 +You need to switch `https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main` to `https://raw.githubusercontent.com/[USER]/[REPOSITORY]/refs/head/[BRANCH]` to test your script in your repository. Before opening a Pull Request change all this back to point to the community-scripts Repository. + +### 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 PR from your feature branch to the main repository branch. You may only include your **AppName.sh**, **AppName-install.sh** and **AppName.json** files in the pull request. + +--- + +## πŸ“š Pages + +- [Function-Overview](https://github.com/community-scripts/ProxmoxVE/wiki/Function_Overview) +- [CT Template: AppName.sh](https://github.com/community-scripts/ProxmoxVE/blob/contributor_guide/.github/CONTRIBUTOR_GUIDE/ct/AppName.sh) +- [Install Template: AppName-install.sh](https://github.com/community-scripts/ProxmoxVE/blob/contributor_guide/.github/CONTRIBUTOR_GUIDE/install/AppName-install.sh) +- [JSON Template: AppName.json](https://github.com/community-scripts/ProxmoxVE/blob/contributor_guide/.github/CONTRIBUTOR_GUIDE/json/AppName.json) + +--- + diff --git a/.github/CONTRIBUTOR_GUIDE/ct/AppName.md b/.github/CONTRIBUTOR_GUIDE/ct/AppName.md new file mode 100644 index 0000000000..be163db9c8 --- /dev/null +++ b/.github/CONTRIBUTOR_GUIDE/ct/AppName.md @@ -0,0 +1,231 @@ +# **AppName.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. + + +## 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 link to your own repository. + +> [!CAUTION] +> Before opening a Pull Request, change the link to point to the community-scripts repo. + +Example for development: +```bash +source <(curl -s https://raw.githubusercontent.com/[USER]/[REPO]/refs/heads/[BRANCH]/misc/build.func) +``` + +Example for final Script: +```bash +source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func) +``` + +### 1.3 **Metadata** +- Add clear comments for script metadata, including author, copyright, and license information. + +Example: +```bash +# Copyright (c) 2021-2024 community-scripts ORG +# Author: [YourUserName] +# License: MIT | https://github.com/community-scripts/ProxmoxVE/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 sections sets the Default Values for the Container. +- `APP` needs to be set to the Application name and must represent 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 | +>| `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 +# App Output & Base Settings +header_info "$APP" +base_settings +``` + +- `header_info`: Generates ASCII header for APP +- `base_settings`: Allows overwriting variable values + +## 2.3 **πŸ›  Core Functions** + +```bash +# Core +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 wich updates the Application and the OS in the container. +- Each update function starts with a standardised Header: +```bash +function update_script() { + header_info + check_container_storage + check_container_resources +``` + +### 3.2 **Check APP** +- Befor doing anything updatewise, 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** +- Befor updating, check if a new Version exists. +- For this we use the `${APPLICATION}_version.txt` file created in `/opt` during the install. + +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 appropiate flag (**-q** in the examples) for a command to suppres its output. +Example: +```bash +wget -q +unzip -q +``` +- If a command dose not come with such a functionality use `&>/dev/null` to suppress its output. + +Example: +```bash +php artisan migrate --force &>/dev/null +php artisan config:clear &>/dev/null +``` + +### 3.5 **Backups** +- Backup userdata if nessesary. +- Move all userdata back in the Directory when the update is finnished. +>[!NOTE] +>This is not meant to be a permantent 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 a 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 "Ther is currently no automatic update function for ${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. **Best Practices 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 an for new Version. +- [ ] Update function up temporary files. +- [ ] Script ends with a helpfull message for the User to reach the App. + diff --git a/.github/CONTRIBUTOR_GUIDE/ct/AppName.sh b/.github/CONTRIBUTOR_GUIDE/ct/AppName.sh new file mode 100644 index 0000000000..2b5d707423 --- /dev/null +++ b/.github/CONTRIBUTOR_GUIDE/ct/AppName.sh @@ -0,0 +1,93 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func) +# Copyright (c) 2021-2024 community-scripts ORG +# Author: [YourUserName] +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: [SOURCE_URL] + +# App Default Values +APP="[APP_NAME]" +# Name of the App (e.g. Google, Adventurelog, Apache-Guacamole" +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 + +# App Output & Base Settings +header_info "$APP" +base_settings + +# Core +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 + msg_info "Updating $APP" + + # 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] + sleep 2 + 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}" diff --git a/.github/CONTRIBUTOR_GUIDE/dev-scripts/README.md b/.github/CONTRIBUTOR_GUIDE/dev-scripts/README.md new file mode 100644 index 0000000000..bda6155bce --- /dev/null +++ b/.github/CONTRIBUTOR_GUIDE/dev-scripts/README.md @@ -0,0 +1,42 @@ +# Community Helper scripts for developing LXCs +## How to use + + 1. Start by forking the repository (community-scripts/ProxmoxVE) + 2. Download the three scripts provided: + - new_lxc.sh + - cleanup_lxc.sh + - change_lxc.sh + 3. Make them executable by running: +`chmod u+x ./new_lxc.sh && chmod u+x ./cleanup_lxc.sh && chmod u+x ./change_lxc.sh`. + 4. Edit all three scripts and change `quantumryuu` located in line #3 to your GitHub account name. + 5. Run `./new_lxc.sh` and provide the LXC name when asked. + 6. After pushing the last changes, make sure to run `cleanup_lxc.sh`. + 7. After running `cleanup_lxc.sh` push the changes to your LXC branch and create a PR! + +## Scripts walkthrough +### new_lxc.sh +1. Asks for LXC name. +2. Checks if repository is cloned (automatically cloned if missing). +3. Checks for a build branch (automatically created if missing). +4. Here a lot of things happen, here's a list: + - Grabs a fresh copy of **build.func** and **install.func**. + - Modifies these copies so they reflect the GitHub account and the LXC branch. This is needed since it'll fail for the sole reason of not finding the LXC files because by default as you know it looks for them under the official repo. +5. Checks for the LXC branch (automatically created if missing). +6. Grabs a copy of `evcc.sh & evcc-install.sh` as templates, renames them to the LXC name provided and changes the `source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)` to reflect to the GitHub account and LXC name like the build files above. +7. Lastly it pushes the changes and you're ready to start creating the script! + +### cleanup_lxc.sh - Should be used just before creating a PR. +1. Asks for LXC name. +2. Checks if repository is cloned (automatically cloned if missing). +3. Checks for the LXC branch (exits if not found). +4. Cleans up the following files of the LXC branch: + - LXC-install.sh - Removes empty last line. + - LXC.sh - Removes empy last line && reverts to `source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)`. + - LXC.json - Removes empty last line. + +### [WIP] change_lxc.sh - Used to change between LXC branches (modifies build.func and install.func from build branch) +1. Asks for LXC name. +2. Checks if repository is cloned (automatically cloned if missing). +3. Checks for the LXC branch (exits if not found). +4. Grabs a fresh copy of **build.func** and **install.func**. +5. Modifies said copies to point to the LXC name diff --git a/.github/CONTRIBUTOR_GUIDE/dev-scripts/change_lxc.sh b/.github/CONTRIBUTOR_GUIDE/dev-scripts/change_lxc.sh new file mode 100644 index 0000000000..e2f06c841d --- /dev/null +++ b/.github/CONTRIBUTOR_GUIDE/dev-scripts/change_lxc.sh @@ -0,0 +1,52 @@ +#!/bin/bash +# Variables - MAKE SURE TO CHANGE! +LXC_GHUSERNAME="quantumryuu" + +# Ask user for project name +read -p 'Enter project name: ' LXC_Name + +# Check if repo is cloned +echo "Checking if repo exists locally." +if [ -d ~/ProxmoxVE ]; then + echo "Repo exists locally." +else + echo "Repo does not exist. Cloning..." + cd ~ + git clone git@github.com:${LXC_GHUSERNAME}/ProxmoxVE.git --quiet +fi + +cd ~/ProxmoxVE + +check_branch=$(git ls-remote origin ${LXC_Name}) +if [[ -z ${check_branch} ]]; then + echo "Project does not exist!" + exit +else +# Change branch and refresh +echo "Changing branch to build and pulling changes." +git checkout build &>/dev/null +git pull &>/dev/null + +# Reset files +echo "Resetting build files." +curl -s "https://raw.githubusercontent.com/community-scripts/ProxmoxVE/refs/heads/main/misc/build.func" > ~/ProxmoxVE/misc/build.func +curl -s "https://raw.githubusercontent.com/community-scripts/ProxmoxVE/refs/heads/main/misc/install.func" > ~/ProxmoxVE/misc/install.func + +# Changing build files to project +echo "Changing files for build ${LXC_Name}." +#install.func file change +sed -i "s/community-scripts\/ProxmoxVE\/raw\/main/$LXC_GHUSERNAME\/ProxmoxVE\/raw\/$LXC_Name/g" ~/ProxmoxVE/misc/install.func +#build file change +#var_install replace +sed -i "s/community-scripts\/ProxmoxVE\/main\/install\//$LXC_GHUSERNAME\/ProxmoxVE\/refs\/heads\/$LXC_Name\/install\//g" ~/ProxmoxVE/misc/build.func +#install_func change +sed -i "s/community-scripts\/ProxmoxVE\/main\/misc\/install.func/$LXC_GHUSERNAME\/ProxmoxVE\/build\/misc\/install.func/g" ~/ProxmoxVE/misc/build.func + +# Commiting +echo "Pushing changes." +git add . &>/dev/null +git commit -m "${LXC_Name}" &>/dev/null +git push &>/dev/null + +echo "Done!" +fi \ No newline at end of file diff --git a/.github/CONTRIBUTOR_GUIDE/dev-scripts/cleanup_lxc.sh b/.github/CONTRIBUTOR_GUIDE/dev-scripts/cleanup_lxc.sh new file mode 100644 index 0000000000..08fb1f2099 --- /dev/null +++ b/.github/CONTRIBUTOR_GUIDE/dev-scripts/cleanup_lxc.sh @@ -0,0 +1,60 @@ +#!/bin/bash +# Variables - MAKE SURE TO CHANGE! +LXC_GHUSERNAME="quantumryuu" + +# Ask user for project name +read -p 'Enter project name: ' LXC_Name + +# Check if repo is cloned +echo "Checking if repo exists locally." +if [ -d ~/ProxmoxVE ]; then + echo "Repo exists locally." +else + echo "Repo does not exist. Cloning..." + cd ~ + git clone git@github.com:${LXC_GHUSERNAME}/ProxmoxVE.git --quiet +fi + +cd ~/ProxmoxVE + +# Check if branch exits. +check_branch=$(git ls-remote origin ${LXC_Name}) +if [[ -z ${check_branch} ]]; then + echo "${LXC_Name} does not exist. Exiting..." + exit +else + + # Change branch and refresh + echo "Changing branch to ${LXC_Name} and pulling changes." + git checkout ${LXC_Name} -q + git pull -q +fi + +echo "Cleaning up files." +if [ -f ~/ProxmoxVE/install/${LXC_Name}-install.sh ]; then + echo "Cleaning ${LXC_Name}-install.sh" + sed -i '$ {/^$/d;}' ~/ProxmoxVE/install/${LXC_Name}-install.sh +else + echo "${LXC_Name}-install.sh not found. Exiting..." + exit +fi + +if [ -f ~/ProxmoxVE/ct/${LXC_Name}.sh ]; then + echo "Cleaning ct.sh" + sed -i "s/$LXC_GHUSERNAME\/ProxmoxVE\/refs\/heads\/build\/misc\//community-scripts\/ProxmoxVE\/main\/misc\//g" ~/ProxmoxVE/ct/${LXC_Name}.sh + sed -i '${/^$/d}' ~/ProxmoxVE/ct/${LXC_Name}.sh + +else + echo "${LXC_Name}.sh not found. Exiting..." + exit +fi + +if [ -f ~/ProxmoxVE/install/${LXC_Name}-install.sh ]; then + echo "Cleaning ${LXC_Name}.json" + sed -i '${/^$/d}' ~/ProxmoxVE/json/${LXC_Name}.json +else + echo "${LXC_Name}.json not found. Exiting..." + exit +fi + +echo "Ready to push changes!" \ No newline at end of file diff --git a/.github/CONTRIBUTOR_GUIDE/dev-scripts/new_lxc.sh b/.github/CONTRIBUTOR_GUIDE/dev-scripts/new_lxc.sh new file mode 100644 index 0000000000..e8a0e4fe81 --- /dev/null +++ b/.github/CONTRIBUTOR_GUIDE/dev-scripts/new_lxc.sh @@ -0,0 +1,84 @@ +#!/bin/bash +# Variables - MAKE SURE TO CHANGE! +LXC_GHUSERNAME="quantumryuu" + +# Ask user for project name +read -p 'Enter project name: ' LXC_Name + +# Check if repo is cloned +echo "Checking if repo exists locally." +if [ -d ~/ProxmoxVE ]; then + echo "Repo exists locally." +else + echo "Repo does not exist. Cloning..." + cd ~ + git clone git@github.com:${LXC_GHUSERNAME}/ProxmoxVE.git --quiet +fi + +cd ~/ProxmoxVE + +# Check if build branch exists. +build_branch=$(git ls-remote origin build) +if [[ ! -z ${build_branch} ]]; then + echo "Build branch exists!" +else +echo "Creating build branch" +git checkout -b build main -q +git add . &>/dev/null +git commit -am "build branch creation" &>/dev/null +git push --quiet -u --no-progress origin build +fi + +# Check if branch exists. +check_branch=$(git ls-remote origin ${LXC_Name}) +if [[ ! -z ${check_branch} ]]; then + echo "${LXC_Name} exists. Exiting..." + exit +else + +# Change branch and refresh +echo "Changing branch to build and pulling changes." +git checkout build -q +git pull -q + +# Reset files +echo "Resetting build files." +curl -s "https://raw.githubusercontent.com/community-scripts/ProxmoxVE/refs/heads/main/misc/build.func" > ~/ProxmoxVE/misc/build.func +curl -s "https://raw.githubusercontent.com/community-scripts/ProxmoxVE/refs/heads/main/misc/install.func" > ~/ProxmoxVE/misc/install.func + +# Changing build files to project +echo "Changing build files for ${LXC_Name}." + +#install.func file change +sed -i "s/community-scripts\/ProxmoxVE\/raw\/main/$LXC_GHUSERNAME\/ProxmoxVE\/raw\/$LXC_Name/g" ~/ProxmoxVE/misc/install.func + +#build file change +#var_install replace +sed -i "s/community-scripts\/ProxmoxVE\/main\/install\//$LXC_GHUSERNAME\/ProxmoxVE\/refs\/heads\/$LXC_Name\/install\//g" ~/ProxmoxVE/misc/build.func +#install_func change +sed -i "s/community-scripts\/ProxmoxVE\/main\/misc\/install.func/$LXC_GHUSERNAME\/ProxmoxVE\/build\/misc\/install.func/g" ~/ProxmoxVE/misc/build.func + +# Commiting +echo "Pushing changes." +git add . &>/dev/null +git commit -m "${LXC_Name}" &>/dev/null +git push -q + +# Create new branch +echo "Creating new branch for ${LXC_Name}." +git checkout -b ${LXC_Name} main -q + +# Create required files +echo "Creating ct and install files." +curl -s "https://raw.githubusercontent.com/community-scripts/ProxmoxVE/refs/heads/main/ct/evcc.sh" > ~/ProxmoxVE/ct/${LXC_Name}.sh +sed -i "s/community-scripts\/ProxmoxVE\/main\/misc\//$LXC_GHUSERNAME\/ProxmoxVE\/refs\/heads\/build\/misc\//g" ~/ProxmoxVE/ct/${LXC_Name}.sh +curl -s "https://raw.githubusercontent.com/community-scripts/ProxmoxVE/refs/heads/main/install/evcc-install.sh" > ~/ProxmoxVE/install/${LXC_Name}-install.sh + +# Push new files +echo "Pushing created files." +git add . &>/dev/null +git commit -am "${LXC_Name}" &>/dev/null +git push --quiet -u --no-progress origin "${LXC_Name}" + +echo "Done!" +fi \ No newline at end of file diff --git a/.github/CONTRIBUTOR_GUIDE/install/AppName-install.md b/.github/CONTRIBUTOR_GUIDE/install/AppName-install.md new file mode 100644 index 0000000000..cd660411b4 --- /dev/null +++ b/.github/CONTRIBUTOR_GUIDE/install/AppName-install.md @@ -0,0 +1,262 @@ + +# **AppName-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. + +## 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-2024 community-scripts ORG +# Author: [YourUserName] +# License: MIT +# 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 **Collaps Dependencies** +- Collaps 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 applications** +- If possible install the App and all nessesery files in `/opt/` + +--- + +## 5. **Version Management** + +### 5.1 **Install the latest Release** +- Always try and install the latest Release if possibly +- Do not hardcode any version if not absolutly nessesery + +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) }') +wget -q "https://github.com/snipe/snipe-it/archive/refs/tags/v${RELEASE}.zip" +``` + +### 5.2 **Store the Version in a File for later Updates** +- Write the installed Version into a file. +- This is used for the Update function in app.sh to check if we need to update or not + +Example: +```bash +echo "${RELEASE}" >"/opt/AppName_version.txt" +``` +--- + +## 6. **Input and Output Management** + +### 6.1 **User Feedback** +- Use standard functions like `msg_info` and `msg_ok` to print status messages. +- Display meaningful progress messages at key stages. + +Example: +```bash +msg_info "Installing Dependencies" +$STD apt-get install ... +msg_ok "Installed Dependencies" +``` +### 6.2 **Verbosity** +- Use the appropiate flag (**-q** in the examples) for a command to suppres its output +Example: +```bash +wget -q +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 secure tools (e.g., `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 </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 **Enviromental Files** +- Use `cat </path/to/.env +VARIABLE="value" +PORT=3000 +DB_NAME="${DB_NAME}" +EOF +``` + +### 9.4 **Services** +- Enable affected services after configuration changes and start it right away. + +Example: +```bash +systemctl enable -q --now nginx +``` + +--- + +## 10. **Cleanup** + +### 10.1 **Remove Temporary Files** +- Remove temporary files or unnecessary downloads after use. + +Example: +```bash +rm -rf /opt/v${RELEASE}.zip +``` + +### 10.2 **Autoremove and Autoclean** +- Clean up 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** diff --git a/.github/CONTRIBUTOR_GUIDE/install/AppName-install.sh b/.github/CONTRIBUTOR_GUIDE/install/AppName-install.sh new file mode 100644 index 0000000000..a1d0f8a2db --- /dev/null +++ b/.github/CONTRIBUTOR_GUIDE/install/AppName-install.sh @@ -0,0 +1,86 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2024 community-scripts ORG +# Author: [YourUserName] +# License: MIT +# 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) }') +wget -q "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 </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" + +motd_ssh +customize diff --git a/.github/CONTRIBUTOR_GUIDE/json/AppName.json b/.github/CONTRIBUTOR_GUIDE/json/AppName.json new file mode 100644 index 0000000000..622f370a4b --- /dev/null +++ b/.github/CONTRIBUTOR_GUIDE/json/AppName.json @@ -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": "Deescription 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": [] +} \ No newline at end of file diff --git a/.github/CONTRIBUTOR_GUIDE/json/AppName.md b/.github/CONTRIBUTOR_GUIDE/json/AppName.md new file mode 100644 index 0000000000..59d38aa345 --- /dev/null +++ b/.github/CONTRIBUTOR_GUIDE/json/AppName.md @@ -0,0 +1,5 @@ +# **AppName.json Files** + `AppName.json` files found in the `/json` directory. These files are used to provide informations for the frontend. For this guide we take `/json/snipeit.json` as example. + + ## 1 **Json Generator** + - To spare you some headache creating the json file, use the [Json-Editor](https://community-scripts.github.io/ProxmoxVE/json-editor) \ No newline at end of file