[
  {
    "path": ".github/CODE_OF_CONDUCT.md",
    "content": "\n# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nWe as members, contributors, and leaders pledge to make participation in our\ncommunity a harassment-free experience for everyone, regardless of age, body\nsize, visible or invisible disability, ethnicity, sex characteristics, gender\nidentity and expression, level of experience, education, socio-economic status,\nnationality, personal appearance, race, religion, or sexual identity\nand orientation.\n\nWe pledge to act and interact in ways that contribute to an open, welcoming,\ndiverse, inclusive, and healthy community.\n\n## Our Standards\n\nExamples of behavior that contributes to a positive environment for our\ncommunity include:\n\n* Demonstrating empathy and kindness toward other people\n* Being respectful of differing opinions, viewpoints, and experiences\n* Giving and gracefully accepting constructive feedback\n* Accepting responsibility and apologizing to those affected by our mistakes,\n  and learning from the experience\n* Focusing on what is best not just for us as individuals, but for the\n  overall community\n\nExamples of unacceptable behavior include:\n\n* The use of sexualized language or imagery, and sexual attention or\n  advances of any kind\n* Trolling, insulting or derogatory comments, and personal or political attacks\n* Public or private harassment\n* Publishing others' private information, such as a physical or email\n  address, without their explicit permission\n* Other conduct which could reasonably be considered inappropriate in a\n  professional setting\n\n## Enforcement Responsibilities\n\nCommunity leaders are responsible for clarifying and enforcing our standards of\nacceptable behavior and will take appropriate and fair corrective action in\nresponse to any behavior that they deem inappropriate, threatening, offensive,\nor harmful.\n\nCommunity leaders have the right and responsibility to remove, edit, or reject\ncomments, commits, code, wiki edits, issues, and other contributions that are\nnot aligned to this Code of Conduct, and will communicate reasons for moderation\ndecisions when appropriate.\n\n## Scope\n\nThis Code of Conduct applies within all community spaces, and also applies when\nan individual is officially representing the community in public spaces.\nExamples of representing our community include using an official e-mail address,\nposting via an official social media account, or acting as an appointed\nrepresentative at an online or offline event.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be\nreported to the community leaders responsible for enforcement.\nAll complaints will be reviewed and investigated promptly and fairly.\n\nAll community leaders are obligated to respect the privacy and security of the\nreporter of any incident.\n\n## Enforcement Guidelines\n\nCommunity leaders will follow these Community Impact Guidelines in determining\nthe consequences for any action they deem in violation of this Code of Conduct:\n\n### 1. Correction\n\n**Community Impact**: Use of inappropriate language or other behavior deemed\nunprofessional or unwelcome in the community.\n\n**Consequence**: A private, written warning from community leaders, providing\nclarity around the nature of the violation and an explanation of why the\nbehavior was inappropriate. A public apology may be requested.\n\n### 2. Warning\n\n**Community Impact**: A violation through a single incident or series\nof actions.\n\n**Consequence**: A warning with consequences for continued behavior. No\ninteraction with the people involved, including unsolicited interaction with\nthose enforcing the Code of Conduct, for a specified period of time. This\nincludes avoiding interactions in community spaces as well as external channels\nlike social media. Violating these terms may lead to a temporary or\npermanent ban.\n\n### 3. Temporary Ban\n\n**Community Impact**: A serious violation of community standards, including\nsustained inappropriate behavior.\n\n**Consequence**: A temporary ban from any sort of interaction or public\ncommunication with the community for a specified period of time. No public or\nprivate interaction with the people involved, including unsolicited interaction\nwith those enforcing the Code of Conduct, is allowed during this period.\nViolating these terms may lead to a permanent ban.\n\n### 4. Permanent Ban\n\n**Community Impact**: Demonstrating a pattern of violation of community\nstandards, including sustained inappropriate behavior,  harassment of an\nindividual, or aggression toward or disparagement of classes of individuals.\n\n**Consequence**: A permanent ban from any sort of public interaction within\nthe community.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage],\nversion 2.0, available at\n[https://www.contributor-covenant.org/version/2/0/code_of_conduct.html][v2.0].\n\nCommunity Impact Guidelines were inspired by\n[Mozilla's code of conduct enforcement ladder][Mozilla CoC].\n\nFor answers to common questions about this code of conduct, see the FAQ at\n[https://www.contributor-covenant.org/faq][FAQ]. Translations are available\nat [https://www.contributor-covenant.org/translations][translations].\n\n[homepage]: https://www.contributor-covenant.org\n[v2.0]: https://www.contributor-covenant.org/version/2/0/code_of_conduct.html\n[Mozilla CoC]: https://github.com/mozilla/diversity\n[FAQ]: https://www.contributor-covenant.org/faq\n[translations]: https://www.contributor-covenant.org/translations\n"
  },
  {
    "path": ".github/CONTRIBUTING.md",
    "content": "<div align=\"center\">\n  <a href=\"#\">\n    <img src=\"https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/logo.png\" height=\"100px\" />\n </a>\n</div>\n<h2 align=\"center\">Contributing to Proxmox VE Helper Scripts</h2>\n\nEverybody is invited and welcome to contribute to Proxmox VE Helper Scripts. \n\n- Pull requests submitted against [**main**](https://github.com/tteck/Proxmox/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/tteck/Proxmox/tree/main).\n\n- 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.\n\n- The repository will only accept Alpine applications that make use of the Alpine Package Keeper.\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "ko_fi: proxmoxhelperscripts\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.yaml",
    "content": "name: Problems with a script.\ndescription: Generate a report on an issue pertaining specifically to a script. For other inquires please share them in the Discussions section.\nbody:\n  - type: markdown\n    attributes:\n      value: |\n        **IMPORTANT:** Failure to comply with the following guidelines may result in immediate closure.\n        - Prior to submitting, kindly search the closed issues to check if the problem you are reporting has already been addressed and resolved. If you come across a closed issue that pertains to your problem, please leave a comment on that issue instead of creating a new one.\n        - If the default Linux distribution is not adhered to, script support will be discontinued.\n        - When encountering the error message `[ERROR] in line 23: exit code *: while executing command \"$@\" > /dev/null 2>&1`, make sure to run the script in verbose mode to accurately determine the underlying issue.\n        - For suggestions, questions or feature/script requests, please share them in the [Discussions section.](https://github.com/tteck/Proxmox/discussions)\n  - type: input\n    id: guidelines\n    attributes:\n      label: Please verify that you have read and understood the guidelines.\n      placeholder: 'yes'\n    validations:\n      required: true\n  - type: textarea\n    id: bug\n    attributes:\n      label: A clear and concise description of the issue.\n    validations:\n      required: true\n  - type: dropdown\n    id: settings\n    validations:\n      required: true\n    attributes:\n      label: What settings are you currently utilizing?\n      options:\n        - \n        - Default Settings\n        - Advanced Settings\n  - type: markdown\n    attributes:\n      value: (if Advanced Settings, please try Default Settings before creating an issue)\n  - type: dropdown\n    id: distribution\n    validations:\n      required: true\n    attributes:\n      label: Which Linux distribution are you employing?\n      options:\n        - \n        - Alpine\n        - Debian 11\n        - Debian 12\n        - Ubuntu 20.04\n        - Ubuntu 22.04\n        - Ubuntu 24.04\n  - type: textarea\n    id: screenshot\n    attributes:\n      label: If relevant, including screenshots or a code block can be helpful in clarifying the issue.\n      placeholder: Code blocks begin and conclude by enclosing the code with three backticks (```) above and below it.\n    validations:\n      required: false\n  - type: textarea\n    id: reproduce\n    attributes:\n      label: Please provide detailed steps to reproduce the issue.\n      placeholder: First do this, then this ...\n    validations:\n      required: false\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "content": "blank_issues_enabled: false\ncontact_links:\n  - name: Helper-Scripts Community Support\n    url: https://github.com/tteck/Proxmox/discussions\n    about: Please ask and answer questions here.\n"
  },
  {
    "path": ".github/pull_request_template.md",
    "content": "> [!NOTE]\nI am meticulous when it comes to merging code into the main branch, so please understand that I may reject pull requests that do not meet the project's standards. It's never personal. Also, game-related scripts have a lower chance of being merged.\n\n## Description\n\nProvide a summary of the changes made and/or reference the issue being addressed.\n\nFixes # (issue)\n\n## Type of change\n\nPlease check the relevant option(s):\n\n- [ ] Bug fix (non-breaking change that resolves an issue)\n- [ ] New feature (non-breaking change that adds functionality)\n- [ ] Breaking change (a fix or feature that would cause existing functionality to change unexpectedly)\n- [ ] New script (a fully functional and thoroughly tested script or set of scripts.)\n- [ ] Self-review performed (I have reviewed my code, ensuring it follows established patterns and conventions)\n- [ ] Documentation update required (this change requires an update to the documentation)\n\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "<div align=\"center\">\n  <a href=\"#\">\n    <img src=\"https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/logo.png\" height=\"100px\" />\n </a>\n</div>\n<h1 align=\"center\">Changelog</h1>\n\n<h3 align=\"center\">All notable changes to this project will be documented in this file.</h3>\n\n> [!CAUTION]\nExercise vigilance regarding copycat or coat-tailing sites that seek to exploit the project's popularity for potentially malicious purposes.\n\n> [!NOTE]\nAll LXC instances created using this repository come pre-installed with Midnight Commander, which is a command-line tool (`mc`) that offers a user-friendly file and directory management interface for the terminal environment.\n\n## 2024-10-27\n\n### Changed\n\n- **Open WebUI LXC** [(Commit)](https://github.com/tteck/Proxmox/commit/8a21f6e7f025a911865395d4c0fa9a001bd0d512)\n  - Refactor Script to add an option to install Ollama.\n\n## 2024-10-26\n\n### Changed\n\n- **AdventureLog LXC** [(View Source)](https://github.com/tteck/Proxmox/blob/main/install/adventurelog-install.sh)\n  - NEW Script\n\n## 2024-10-25\n\n### Changed\n\n- **Zoraxy LXC** [(Commit)](https://github.com/tteck/Proxmox/commit/468a5d367ded4cf453a1507452e112ac3e234e2a)\n  - Switch built from source to a pre-compiled binary version.\n  - Breaking Change\n\n## 2024-10-23\n\n### Changed\n\n- **Wallos LXC** [(View Source)](https://github.com/tteck/Proxmox/blob/main/install/wallos-install.sh)\n  - NEW Script\n- **Open WebUI LXC** [(View Source)](https://github.com/tteck/Proxmox/blob/main/install/openwebui-install.sh)\n  - NEW Script\n\n## 2024-10-19\n\n### Changed\n\n- **Cockpit LXC** [(View Source)](https://github.com/tteck/Proxmox/blob/main/install/cockpit-install.sh)\n  - NEW Script\n- **Neo4j LXC** [(View Source)](https://github.com/tteck/Proxmox/blob/main/install/neo4j-install.sh)\n  - NEW Script\n\n## 2024-10-18\n\n### Changed\n\n- **ArchiveBox LXC** [(View Source)](https://github.com/tteck/Proxmox/blob/main/install/archivebox-install.sh)\n  - NEW Script\n\n## 2024-10-15\n\n### Changed\n\n- **evcc LXC** [(View Source)](https://github.com/tteck/Proxmox/blob/main/install/evcc-install.sh)\n  - NEW Script\n\n## 2024-10-10\n\n### Changed\n\n- **MySQL LXC** [(View Source)](https://github.com/tteck/Proxmox/blob/main/install/mysql-install.sh)\n  - NEW Script\n- **Tianji LXC** [(Commit)](https://github.com/tteck/Proxmox/commit/4c83a790ac9b040da1f11ad2cbe13d3fc5f480e9)\n  - Breaking Change\n  - Switch from `pm2` process management to `systemd`\n\n## 2024-10-03\n\n### Changed\n\n- **Home Assistant Core LXC** [(Commit)](https://github.com/tteck/Proxmox/commit/f2937febe69b2bad8b3a14eb84aa562a8f14cc6a) [(Commit)](https://github.com/tteck/Proxmox/commit/f2966ced7f457fd506f865f7f5b70ea12c4b0049)\n  - Refactor Code\n  - Breaking Change\n  - Home Assistant has transitioned to using `uv` for managing the virtual environment and installing additional modules.\n\n## 2024-09-16\n\n### Changed\n\n- **HomeBox LXC** [(View Source)](https://github.com/tteck/Proxmox/blob/main/install/homebox-install.sh)\n  - NEW Script\n- **Zipline LXC** [(View Source)](https://github.com/tteck/Proxmox/blob/main/install/zipline-install.sh)\n  - NEW Script\n\n## 2024-09-13\n\n### Changed\n\n- **Tianji LXC** [(View Source)](https://github.com/tteck/Proxmox/blob/main/install/tianji-install.sh)\n  - NEW Script\n\n## 2024-08-21\n\n### Changed\n\n- **WireGuard LXC** [(Commit)](https://github.com/tteck/Proxmox/commit/723365a79df7cc0fd29b1af8f7ef200a7e0921b1)\n  - Refactor Code\n  - Breaking Change\n\n## 2024-08-19\n\n### Changed\n\n- **CommaFeed LXC** [(Commit)](https://github.com/tteck/Proxmox/commit/0a33d1739ec3a49011411929bd46a260e92e99f9)\n  - Refactor Code\n  - Breaking Change\n\n## 2024-08-06\n\n### Changed\n\n- **lldap LXC** [(View Source)](https://github.com/tteck/Proxmox/blob/main/install/lldap-install.sh)\n  - NEW Script\n\n## 2024-07-26\n\n### Changed\n\n- **Gitea LXC** [(View Source)](https://github.com/tteck/Proxmox/blob/main/install/gitea-install.sh)\n  - NEW Script\n\n## 2024-06-30\n\n### Changed\n\n- **All Scripts** [(Commit)](https://github.com/tteck/Proxmox/commit/39ea1d4a20b83c07d084ebafdc811eec3548f289)\n  - Requires Proxmox Virtual Environment version 8.1 or later.\n\n## 2024-06-27\n\n### Changed\n\n- **Kubo LXC** [(View Source)](https://github.com/tteck/Proxmox/blob/main/install/kubo-install.sh)\n  - NEW Script\n- **RabbitMQ LXC** [(View Source)](https://github.com/tteck/Proxmox/blob/main/install/rabbitmq-install.sh)\n  - NEW Script\n- **Scrutiny LXC**\n  - Removed from website, broken.\n\n## 2024-06-26\n\n### Changed\n\n- **Scrutiny LXC**\n  - NEW Script\n\n## 2024-06-14\n\n### Changed\n\n- **MySpeed LXC** [(View Source)](https://github.com/tteck/Proxmox/blob/main/install/myspeed-install.sh)\n  - NEW Script\n\n## 2024-06-13\n\n### Changed\n\n- **PeaNUT LXC** [(View Source)](https://github.com/tteck/Proxmox/blob/main/install/peanut-install.sh)\n  - NEW Script\n- **Website**\n  - If the Changelog has changed recently, the link on the website will pulse.\n- **Spoolman LXC** [(View Source)](https://github.com/tteck/Proxmox/blob/main/install/spoolman-install.sh)\n  - NEW Script\n\n## 2024-06-12\n\n### Changed\n\n- **MeTube LXC** [(View Source)](https://github.com/tteck/Proxmox/blob/main/install/metube-install.sh)\n  - NEW Script\n- **Matterbridge LXC** [(View Source)](https://github.com/tteck/Proxmox/blob/main/install/matterbridge-install.sh)\n  - NEW Script\n- **Website**\n  - Reopen the gh-pages site (https://tteck.github.io/Proxmox/) \n\n## 2024-06-11\n\n### Changed\n\n- **Zabbix LXC** [(View Source)](https://github.com/tteck/Proxmox/blob/main/install/zabbix-install.sh)\n  - NEW Script\n\n## 2024-06-06\n\n### Changed\n\n- **Petio LXC** [(View Source)](https://github.com/tteck/Proxmox/blob/main/install/petio-install.sh)\n  - NEW Script\n- **Website**\n  - Important notices will now be displayed on the landing page.\n\n## 2024-06-04\n\n### Changed\n\n- **FlareSolverr LXC** [(View Source)](https://github.com/tteck/Proxmox/blob/main/install/flaresolverr-install.sh)\n  - NEW Script\n\n## 2024-05-31\n\n### Changed\n\n- **Advanced Settings** [(Commit)](https://github.com/tteck/Proxmox/commit/fc9dff220b4ea426d3a75178ad8accacae4683ca)\n  - Passwords are now masked\n\n## 2024-05-30\n\n### Changed\n\n- **Forgejo LXC**\n  - NEW Script\n\n## 2024-05-28\n\n### Changed\n\n- **Notifiarr LXC**\n  - NEW Script\n\n## 2024-05-25\n\n### Changed\n\n- **Threadfin LXC**\n  - NEW Script\n\n## 2024-05-23\n\n### Changed\n\n- **BunkerWeb LXC**\n  - NEW Script\n\n## 2024-05-20\n\n### Changed\n\n- **Traefik LXC**\n  - NEW Script\n\n## 2024-05-19\n\n### Changed\n\n- **NetBird**\n  - NEW Script\n- **Tailscale**\n  - Refactor Code\n\n## 2024-05-18\n\n### Changed\n\n- **MongoDB LXC**\n  - NEW Script\n\n## 2024-05-17\n\n### Changed\n\n- **New Website**\n  - We have officially moved to [Helper-Scripts.com](https://helper-scripts.com)\n\n## 2024-05-16\n\n### Changed\n\n- **iVentoy LXC**\n  - NEW Script\n\n## 2024-05-13\n\n### Changed\n\n- **Headscale LXC**\n  - NEW Script\n\n## 2024-05-11\n\n### Changed\n\n- **Caddy LXC**\n  - NEW Script\n\n## 2024-05-09\n\n### Changed\n\n- **Umami LXC**\n  - NEW Script\n\n## 2024-05-08\n\n### Changed\n\n- **Kernel Pin**\n  - NEW Script\n- **Home Assistant Core LXC**\n  - Ubuntu 24.04 ONLY\n\n## 2024-05-07\n\n### Changed\n\n- **Pocketbase LXC**\n  - NEW Script\n\n## 2024-05-05\n\n### Changed\n\n- **Fenrus LXC**\n  - NEW Script\n\n## 2024-05-02\n\n### Changed\n\n- **OpenMediaVault LXC**\n  - Set Debian 12 as default\n  - OpenMediaVault 7 (sandworm)\n\n## 2024-04-30\n\n### Changed\n\n- **Tdarr LXC**\n  - Default settings are now **Unprivileged**\n  - Unprivileged Hardware Acceleration\n\n## 2024-04-29\n\n### Changed\n\n- **ErsatzTV LXC**\n  - NEW Script\n\n## 2024-04-28\n\n### Changed\n\n- **Scrypted LXC**\n  - Unprivileged Hardware Acceleration\n- **Emby LXC**\n  - Unprivileged Hardware Acceleration\n\n## 2024-04-27\n\n### Changed\n\n- **Frigate LXC**\n  - Unprivileged Hardware Acceleration https://github.com/tteck/Proxmox/discussions/2711#discussioncomment-9244629\n- **Ubuntu 24.04 VM**\n  - NEW Script\n\n## 2024-04-26\n\n### Changed\n\n- **Glances**\n  - NEW Script\n\n## 2024-04-25\n\n### Changed\n\n- **Jellyfin LXC**\n  - Default settings are now **Unprivileged**\n  - Unprivileged Hardware Acceleration\n  - Groups are set automatically\n  - Checks for the existence of `/dev/dri/card0` if not found, use `/dev/dri/card1`. Set the GID to `44`\n  - Set the GID for `/dev/dri/renderD128` to `104`\n  - Not tested <8.1.11\n- **Plex LXC**\n  - Default settings are now **Unprivileged**\n  - Unprivileged Hardware Acceleration\n  - Groups are set automatically\n  - Checks for the existence of `/dev/dri/card0` if not found, use `/dev/dri/card1`. Set the GID to `44`\n  - Set the GID for `/dev/dri/renderD128` to `104`\n  - Not tested <8.1.11\n\n## 2024-04-24\n\n### Changed\n\n- **Traccar LXC**\n  - NEW Script\n- **Calibre-Web LXC**\n  - NEW Script\n\n## 2024-04-21\n\n### Changed\n\n- **Aria2 LXC**\n  - NEW Script\n\n## 2024-04-15\n\n### Changed\n\n- **Homarr LXC**\n  - Add back to website\n- **Umbrel LXC**\n  - Add back to website\n- **OpenMediaVault LXC**\n  - Add back to website\n\n## 2024-04-12\n\n### Changed\n\n- **OpenMediaVault LXC**\n  - Removed from website\n\n## 2024-04-09\n\n### Changed\n\n- **PairDrop LXC**\n  - Add back to website\n\n## 2024-04-05\n\n### Changed\n\n- **Medusa LXC**\n  - NEW Script\n- **WatchYourLAN LXC**\n  - NEW Script\n\n## 2024-04-04\n\n### Changed\n\n- **Actual Budget LXC**\n  - NEW Script\n\n## 2024-04-03\n\n### Changed\n\n- **LazyLibrarian LXC**\n  - NEW Script\n\n## 2024-04-01\n\n### Changed\n\n- **Frigate LXC**\n  - NEW Script\n\n## 2024-03-26\n\n### Changed\n\n- **MediaMTX LXC**\n  - NEW Script\n\n## 2024-03-25\n\n### Changed\n\n- **Proxmox VE Post Install**\n  - ~Requires Proxmox Virtual Environment Version 8.1.1 or later.~\n  - Requires Proxmox Virtual Environment Version 8.0 or later.\n- **Proxmox Backup Server LXC**\n  - NEW Script\n\n## 2024-03-24\n\n### Changed\n\n- **SmokePing LXC**\n  - NEW Script\n\n## 2024-03-13\n\n### Changed\n\n- **FlowiseAI LXC**\n  - NEW Script\n\n## 2024-03-11\n\n### Changed\n\n- **Wastebin LXC**\n  - NEW Script\n\n## 2024-03-08\n\n### Changed\n\n- **Proxmox VE Post Install**\n  - Requires Proxmox Virtual Environment Version 8.1.1 or later.\n\n## 2024-02-26\n\n### Changed\n\n- **Mafl LXC**\n  - NEW Script\n\n## 2024-02-23\n\n### Changed\n\n- **Tandoor Recipes LXC**\n  - NEW Script (Thanks @MickLesk)\n\n## 2024-02-21\n\n### Changed\n\n- **All scripts**\n  - As of today, the scripts require the Bash shell specifically. ([more info](https://github.com/tteck/Proxmox/discussions/2536))\n\n## 2024-02-19\n\n### Changed\n\n- **PairDrop LXC**\n  - Removed from the website ([more info](https://github.com/tteck/Proxmox/discussions/2516))\n\n## 2024-02-16\n\n### Changed\n\n- **Proxmox VE LXC Filesystem Trim**\n  - NEW Script ([more info](https://github.com/tteck/Proxmox/discussions/2505#discussion-6226037))\n\n## 2024-02-11\n\n### Changed\n\n- **HiveMQ CE LXC**\n  - NEW Script\n- **Apache-CouchDB LXC**\n  - NEW Script\n\n## 2024-02-06\n\n### Changed\n\n- **All Scripts**\n  - The scripts will only work with PVE7 Version 7.4-13 or later, or PVE8 Version 8.1.1 or later.\n\n## 2024-02-05\n\n### Changed\n\n- **Gokapi LXC**\n  - NEW Script\n- **Nginx Proxy Manager LXC**\n  - Option to install v2.10.4\n\n## 2024-02-04\n\n### Changed\n\n- **Pi-hole LXC**\n  - Option to add Unbound\n\n## 2024-02-02\n\n### Changed\n\n- **Readeck LXC**\n  - NEW Script\n\n## 2024-01-25\n\n### Changed\n\n- **PairDrop LXC**\n  - NEW Script\n\n## 2024-01-20\n\n### Changed\n\n- **Apache-Cassandra LXC**\n  - NEW Script\n- **Redis LXC**\n  - NEW Script\n\n## 2024-01-17\n\n### Changed\n\n- **ntfy LXC**\n  - NEW Script\n- **HyperHDR LXC**\n  - NEW Script\n\n## 2024-01-16\n\n### Changed\n\n- **Website Improvements**\n  - Refine and correct pointers.\n  - Change hover colors to intuitively indicate categories/items.\n  - Implement opening links in new tabs for better navigation.\n  - Enhance the Copy button to better indicate that the command has been successfully copied.\n  - Introduce a Clear Search button.\n  - While not directly related to the website, it's worth mentioning that the logo in newly created LXC notes now serves as a link to the website, conveniently opening in a new tab.\n\n## 2024-01-12\n\n### Changed\n\n- **Apt-Cacher-NG LXC**\n  - NEW Script\n- **New Feature**\n  - The option to utilize Apt-Cacher-NG (Advanced settings) when creating LXCs. The added functionality is expected to decrease bandwidth usage and expedite package installation and updates. https://github.com/tteck/Proxmox/discussions/2332\n\n## 2024-01-09\n\n### Changed\n\n- **Verbose mode**\n  - Only entries with `$STD` will be shown\n\n## 2024-01-07\n\n### Changed\n\n- **Stirling-PDF LXC**\n  - NEW Script\n- **SFTPGo LXC**\n  - NEW Script\n\n## 2024-01-04\n\n### Changed\n\n- **CommaFeed LXC**\n  - NEW Script\n\n## 2024-01-03\n\n### Changed\n\n- **Sonarr LXC**\n  - Breaking Change\n  - Complete recode\n  - https://github.com/tteck/Proxmox/discussions/1738#discussioncomment-8005107\n\n## 2024-01-01\n\n### Changed\n\n- **Gotify LXC**\n  - NEW Script\n\n## 2023-12-19\n\n### Changed\n\n- **Proxmox VE Netdata**\n  - NEW Script\n\n## 2023-12-10\n\n### Changed\n\n- **Homarr LXC**\n  - Removed, again.\n\n## 2023-12-02\n\n### Changed\n\n- **Runtipi LXC**\n  - NEW Script\n\n## 2023-12-01\n\n### Changed\n\n- **Mikrotik RouterOS VM**\n  - Now Mikrotik RouterOS CHR VM\n  - code refactoring\n  - update to CHR\n  - thanks to @NiccyB\n- **Channels DVR Server LXC**\n  - NEW Script\n\n## 2023-11-19\n\n### Changed\n\n- **Dockge LXC**\n  - NEW Script\n\n## 2023-11-18\n\n### Changed\n\n- **Ubuntu 22.04 VM**\n  - NEW Script\n\n## 2023-11-14\n\n### Changed\n\n- **TurnKey Nextcloud VM**\n  - NEW Script\n- **TurnKey ownCloud VM**\n  - NEW Script\n\n## 2023-11-11\n\n### Changed\n\n- **Homarr LXC**\n  - Returns with v0.14.0 (The authentication update).\n\n## 2023-11-9\n\n### Changed\n\n- **AgentDVR LXC**\n  - NEW Script\n\n## 2023-11-8\n\n### Changed\n\n- **Linkwarden LXC**\n  - NEW Script\n\n## 2023-11-2\n\n### Changed\n\n- **PhotoPrism LXC**\n  - Transitioned to PhotoPrism's latest installation package, featuring Linux binaries.\n\n## 2023-11-1\n\n### Changed\n\n- **Owncast LXC**\n  - NEW Script\n\n## 2023-10-31\n\n### Changed\n\n- **Debian 12 VM**\n  - NEW Script\n\n## 2023-10-29\n\n### Changed\n\n- **Unmanic LXC**\n  - NEW Script\n\n## 2023-10-27\n\n### Changed\n\n- **Webmin**\n  - A full code overhaul.\n\n## 2023-10-15\n\n### Changed\n\n- **TasmoAdmin LXC**\n  - NEW Script\n\n## 2023-10-14\n\n### Changed\n\n- **Sonarr LXC**\n  - Include an option to install v4 (experimental)\n\n## 2023-10-11\n\n### Changed\n\n- **Proxmox VE CPU Scaling Governor**\n  - A full code overhaul.\n  - Include an option to configure a crontab for ensuring that the CPU Scaling Governor configuration persists across reboots.\n\n## 2023-10-08\n\n### Changed\n\n- **Proxmox VE LXC Updater**\n  - Now displays which containers require a reboot.\n- **File Browser**\n  - Uninstall by re-executing the script\n  - Option to use No Authentication\n\n## 2023-10-05\n\n### Changed\n\n- **Pingvin Share LXC**\n  - NEW Script\n\n## 2023-09-30\n\n### Changed\n\n- **All Templates**\n  - NEW Script\n\n## 2023-09-28\n\n### Changed\n\n- **Alpine Nextcloud Hub LXC**\n  - NEW Script (Thanks to @nicedevil007)\n\n## 2023-09-14\n\n### Changed\n\n- **Proxmox VE Processor Microcode**\n  - Allow users to select available microcode packages.\n\n## 2023-09-13\n\n### Changed\n\n- **Pi.Alert LXC**\n  - NEW Script\n- **Proxmox VE Kernel Clean**\n  - Code overhaul with a fresh start. This script offers the flexibility to select specific kernels for removal, unlike the previous version, which was an all-or-nothing approach.\n\n## 2023-09-11\n\n### Changed\n\n- **Paperless-ngx LXC**\n  - Modify the script to incorporate Redis and PostgreSQL, while also introducing an option to include Adminer during installation.\n\n## 2023-09-10\n\n### Changed\n\n- **TurnKey Game Server LXC**\n  - NEW Script\n\n## 2023-09-09\n\n### Changed\n\n- **Proxmox VE Host Backup**\n  - Users are now able to specify both the backup path and the directory in which they wish to work.\n\n## 2023-09-07\n\n### Changed\n\n- **Proxmox VE Host Backup**\n  - NEW Script\n\n## 2023-09-06\n\n### Changed\n\n- **Proxmox VE LXC Cleaner**\n  - Added a new menu that allows you to choose which containers you want to exclude from the clean process.\n- **Tailscale**\n  - Added a menu that enables you to choose the specific container where you want to install Tailscale.\n\n## 2023-09-05\n\n### Changed\n\n- **Proxmox VE LXC Updater**\n  - Added a new menu that allows you to choose which containers you want to exclude from the update process.\n\n## 2023-09-01\n\n### Changed\n\n- **TurnKey Media Server LXC**\n  - NEW Script\n\n## 2023-08-31\n\n### Changed\n\n- **TurnKey ZoneMinder LXC**\n  - NEW Script\n- **TurnKey OpenVPN LXC**\n  - NEW Script\n\n## 2023-08-30\n\n### Changed\n\n- **TurnKey**\n  - Introducing a **NEW** Category on the Site.\n  - My intention is to maintain the TurnKey scripts in their simplest form, contained within a single file, and with minimal options, if any.\n- **TurnKey Core LXC**\n  - NEW Script\n- **TurnKey File Server LXC**\n  - NEW Script\n- **TurnKey Gitea LXC**\n  - NEW Script\n- **TurnKey GitLab LXC**\n  - NEW Script\n- **TurnKey Nextcloud LXC**\n  - NEW Script\n- **TurnKey Observium LXC**\n  - NEW Script\n- **TurnKey ownCloud LXC**\n  - NEW Script\n- **TurnKey Torrent Server LXC**\n  - NEW Script\n- **TurnKey Wordpress LXC**\n  - NEW Script\n\n## 2023-08-24\n\n### Changed\n\n- **qBittorrent LXC**\n  - Added back to repository with UPnP disabled and password changed.\n\n## 2023-08-24\n\n### Changed\n\n- **qBittorrent LXC**\n  - Removed from this repository for potential malicious hidden code https://github.com/tteck/Proxmox/discussions/1725\n\n## 2023-08-16\n\n### Changed\n\n- **Homarr LXC**\n  - NEW Script\n\n## 2023-08-10\n\n### Changed\n\n- **Proxmox VE Processor Microcode**\n  - AMD microcode-20230808 Release\n\n## 2023-08-09\n\n### Changed\n\n- **Omada Controller LXC**\n  - Update via script\n- **Proxmox VE Processor Microcode**\n  - [Intel microcode-20230808 Release](https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/releases/tag/microcode-20230808)\n\n## 2023-08-01\n\n### Changed\n\n- **Overseerr LXC**\n  - NEW Script\n- **Jellyseerr LXC**\n  - NEW Script\n\n## 2023-07-24\n\n### Changed\n\n- **Ombi LXC**\n  - NEW Script\n\n## 2023-07-23\n\n### Changed\n\n- **Zoraxy LXC**\n  - NEW Script\n\n## 2023-07-18\n\n### Changed\n\n- **Proxmox VE Cron LXC Updater**\n  - NEW Script\n\n## 2023-07-11\n\n### Changed\n\n- **Scrypted LXC**\n  - Add VAAPI hardware transcoding\n\n## 2023-07-07\n\n### Changed\n\n- **Real-Debrid Torrent Client LXC**\n  - NEW Script\n\n## 2023-07-05\n\n### Changed\n\n- There have been more than 110 commits since June 18th, although not all of them are significant, with a majority focused on ensuring compatibility with Proxmox VE 8 and Debian 12.\n\n## 2023-06-18\n\n### Changed\n\n- **OpenObserve LXC**\n  - NEW Script\n\n## 2023-06-17\n\n### Changed\n\n- **UniFi Network Application LXC**\n  - Now distribution agnostic.\n- **Omada Controller LXC**\n  - Now distribution agnostic.\n## 2023-06-16\n\n### Changed\n\n- **Proxmox VE Monitor-All**\n  - Skip instances based on onboot and templates. [8c2a3cc](https://github.com/tteck/Proxmox/commit/8c2a3cc4d774fa13d17f695d6bdf9a4deedb1372). \n\n## 2023-06-12\n\n### Changed\n\n- **Proxmox VE Edge Kernel**\n  - Removed, with the Proxmox opt-in kernels and the upcoming Proxmox Virtual Environment 8, edge kernels are no longer needed.\n- **Proxmox VE Kernel Clean**\n  - Now compatible with PVE8.\n\n## 2023-06-11\n\n### Changed\n\n- **Proxmox VE Post Install**\n  - Now compatible with both Proxmox Virtual Environment 7 (PVE7) and Proxmox Virtual Environment 8 (PVE8). \n\n## 2023-06-02\n\n### Changed\n\n- **Proxmox VE 7 Post Install**\n  - In a non-clustered environment, you can choose to disable high availability, which helps save system resources.\n\n## 2023-05-27\n\n### Changed\n\n- **Proxmox VE 7 Post Install**\n  - If an Intel N-series processor is detected, ~the script provides options to install both the Proxmox 6.2 kernel and the Intel microcode.~ and using PVE7, recommend using PVE8\n\n## 2023-05-23\n\n### Changed\n\n- **OpenWrt VM**\n  - NEW Script\n\n## 2023-05-17\n\n### Changed\n\n- **Alpine-AdGuard Home LXC**\n  - Removed, it wasn't installed through the Alpine package manager.\n- **Alpine-Whoogle LXC**\n  - Removed, it wasn't installed through the Alpine package manager.\n\n## 2023-05-16\n\n### Changed\n\n- **Proxmox VE LXC Updater**\n  - Add information about the boot disk, which provides an easy way to determine if you need to expand the disk.\n- **Proxmox VE Processor Microcode**\n  - [Intel microcode-20230512 Release](https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/releases/tag/microcode-20230512)\n\n## 2023-05-13\n\n### Changed\n\n- **Tautulli LXC**\n  - NEW Script\n\n## 2023-05-12\n\n### Changed\n\n- **Bazarr LXC**\n  - NEW Script\n\n## 2023-05-08\n\n### Changed\n\n- **Proxmox VE Intel Processor Microcode**\n  - Renamed to **Proxmox VE Processor Microcode**\n  - Automatically identifies the processor vendor (Intel/AMD) and installs the appropriate microcode.\n\n## 2023-05-07\n\n### Changed\n\n- **FHEM LXC**\n  - NEW Script\n\n## 2023-05-01\n\n### Changed\n\n- **OctoPrint LXC**\n  - NEW Script\n- **Proxmox VE Intel Processor Microcode**\n  - NEW Script\n\n## 2023-04-30\n\n### Changed\n\n- **Proxmox VE Monitor-All**\n  - NEW Script\n  - Replaces Proxmox VE LXC Monitor\n\n## 2023-04-28\n\n### Changed\n\n- **Proxmox VE LXC Monitor**\n  - NEW Script\n\n## 2023-04-26\n\n### Changed\n\n- **The site can now be accessed through a more memorable URL, which is [helper-scripts.com](http://helper-scripts.com).**\n\n## 2023-04-23\n\n### Changed\n\n- **Non-Alpine LXC's**\n  - Advanced settings provide the option for users to switch between Debian and Ubuntu distributions. However, some applications or services, such as Deconz, grocy or Omada, may not be compatible with the selected distribution due to dependencies.\n\n## 2023-04-16\n\n### Changed\n\n- **Home Assistant Core LXC**\n  - Python 3.11.2\n\n## 2023-04-15\n\n### Changed\n\n- **InfluxDB LXC**\n  - Choosing InfluxDB v1 will result in Chronograf being installed automatically.\n- **[User Submitted Guides](https://github.com/tteck/Proxmox/blob/main/USER_SUBMITTED_GUIDES.md)**\n  -  Informative guides that demonstrate how to install various software packages using Proxmox VE Helper Scripts.\n\n## 2023-04-14\n\n### Changed\n\n- **Cloudflared LXC**\n  - NEW Script\n\n## 2023-04-05\n\n### Changed\n\n- **Jellyfin LXC**\n  - Set Ubuntu 22.04 as default\n  - Use the Deb822 format jellyfin.sources configuration (jellyfin.list configuration has been obsoleted)\n\n## 2023-04-02\n\n### Changed\n\n- **Home Assistant OS VM**\n  - Include a choice within the \"Advanced\" settings to configure the CPU model between kvm64 (default) or host.\n\n## 2023-03-31\n\n### Changed\n\n- **Home Assistant OS VM**\n  - Include a choice within the \"Advanced\" settings to configure the disk cache between none (default) or Write Through.\n\n## 2023-03-27\n\n### Changed\n\n- **Removed Alpine-ESPHome LXC**\n  - Nonoperational\n- **All Scripts**\n  - Incorporate code that examines whether SSH is being used and, if yes, offers a suggestion against it without restricting or blocking its usage.\n\n## 2023-03-25\n\n### Changed\n\n- **Alpine-ESPHome LXC**\n  - NEW Script\n- **Alpine-Whoogle LXC**\n  - NEW Script\n\n## 2023-03-22\n\n### Changed\n\n- **The latest iteration of the scripts**\n  - Going forward, versioning will no longer be utilized in order to avoid breaking web-links in blogs and YouTube videos.\n  - The scripts have been made more legible as the repetitive code has been moved to function files, making it simpler to share among the scripts and hopefully easier to maintain. This also makes it simpler to contribute to the project.\n  - When a container is created with privileged mode enabled, the USB passthrough feature is automatically activated.\n\n## 2023-03-18\n\n### Changed\n\n- **Alpine-AdGuard Home LXC** (Thanks @nicedevil007)\n  - NEW Script\n- **Alpine-Docker LXC**\n  - NEW Script\n- **Alpine-Zigbee2MQTT LXC**\n  - NEW Script\n\n## 2023-03-15\n\n### Changed\n\n- **Alpine-Grafana LXC** (Thanks @nicedevil007)\n  - NEW Script\n\n## 2023-03-10\n\n### Changed\n\n- **Proxmox LXC Updater** \n  - You can use the command line to exclude multiple containers simultaneously.\n\n## 2023-03-08\n\n### Changed\n\n- **Proxmox CPU Scaling Governor**\n  - Menu options dynamically based on the available scaling governors.\n\n## 2023-03-07\n\n### Changed\n\n- **Alpine-Vaultwarden LXC**\n  - NEW Script\n- **All LXC Scripts**\n  - Retrieve the time zone from Proxmox and configure the container to use the same time zone\n\n## 2023-02-24\n\n### Changed\n\n- **qBittorrent LXC** (Thanks @romka777)\n  - NEW Script\n- **Jackett LXC** (Thanks @romka777)\n  - NEW Script\n\n## 2023-02-23\n\n### Changed\n\n- **Proxmox LXC Updater** \n  - Skip all templates, allowing for the starting, updating, and shutting down of containers to be resumed automatically.\n  - Exclude an additional container by adding the CTID at the end of the shell command ( -s 103).\n\n## 2023-02-16\n\n### Changed\n\n- **RSTPtoWEB LXC** \n  - NEW Script\n- **go2rtc LXC** \n  - NEW Script\n\n## 2023-02-12\n\n### Changed\n\n- **OliveTin** \n  - NEW Script\n\n## 2023-02-10\n\n### Changed\n\n- **Home Assistant OS VM** \n  - Code Refactoring\n\n## 2023-02-05\n\n### Changed\n\n- **Devuan LXC** \n  - NEW Script\n\n## 2023-02-02\n\n### Changed\n\n- **Audiobookshelf LXC** \n  - NEW Script\n- **Rocky Linux LXC** \n  - NEW Script\n\n## 2023-01-28\n\n### Changed\n\n- **LXC Cleaner** \n  - Code refactoring to give the user the option to choose whether cache or logs will be deleted for each app/service.\n  - Leaves directory structure intact\n\n## 2023-01-27\n\n### Changed\n\n- **LXC Cleaner** \n  - NEW Script\n\n## 2023-01-26\n\n### Changed\n\n- **ALL LXC's** \n  - Add an option to disable IPv6 (Advanced)\n\n## 2023-01-25\n\n### Changed\n\n- **Home Assistant OS VM** \n  - switch to v5\n  - add an option to set MTU size (Advanced)\n  - add arch check (no ARM64) (issue from community.home-assistant.io)\n  - add check to insure VMID isn't already used before VM creation (Advanced) (issue from forum.proxmox.com)\n  - code refactoring\n- **PiMox Home Assistant OS VM** \n  - switch to v5\n  - add an option to set MTU size (Advanced)\n  - add arch check (no AMD64)\n  - add pve check (=>7.2)\n  - add check to insure VMID isn't already used before VM creation (Advanced)\n  - code refactoring\n- **All LXC's** \n  - add arch check (no ARM64) (issue from forum.proxmox.com)\n\n## 2023-01-24\n\n### Changed\n\n- **Transmission LXC** \n  - NEW Script\n\n## 2023-01-23\n\n### Changed\n\n- **ALL LXC's** \n  - Add [Midnight Commander (mc)](https://www.linuxcommand.org/lc3_adv_mc.php)\n\n## 2023-01-22\n\n### Changed\n\n- **Autobrr LXC** \n  - NEW Script\n\n## 2023-01-21\n\n### Changed\n\n- **Kavita LXC** \n  - NEW Script\n\n## 2023-01-19\n\n### Changed\n\n- **SABnzbd LXC** \n  - NEW Script\n\n## 2023-01-17\n\n### Changed\n\n- **Homer LXC** \n  - NEW Script\n\n## 2023-01-14\n\n### Changed\n\n- **Tdarr LXC** \n  - NEW Script\n- **Deluge LXC** \n  - NEW Script\n\n## 2023-01-13\n\n### Changed\n\n- **Lidarr LXC** \n  - NEW Script\n- **Prowlarr LXC** \n  - NEW Script\n- **Radarr LXC** \n  - NEW Script\n- **Readarr LXC** \n  - NEW Script\n- **Sonarr LXC** \n  - NEW Script\n- **Whisparr LXC** \n  - NEW Script\n\n## 2023-01-12\n\n### Changed\n\n- **ALL LXC's** \n  - Add an option to set MTU size (Advanced)\n\n## 2023-01-11\n\n### Changed\n\n- **Home Assistant Core LXC** \n  - Auto Initialize\n- **Cronicle Primary/Worker LXC** \n  - NEW Script\n\n## 2023-01-09\n\n### Changed\n\n- **ALL LXC's** \n  - v5\n- **k0s Kubernetes LXC** \n  - NEW Script\n- **Podman LXC** \n  - NEW Script\n\n## 2023-01-04\n\n### Changed\n\n- **YunoHost LXC** \n  - NEW Script\n\n## 2022-12-31\n\n### Changed\n\n- **v5 Scripts** (Testing before moving forward https://github.com/tteck/Proxmox/discussions/881)\n  - Adguard Home LXC\n  - Docker LXC\n  - Home Assistant Core LXC\n  - PhotoPrism LXC\n  - Shinobi NVR LXC\n  - Vaultwarden LXC\n\n## 2022-12-27\n\n### Changed\n\n- **Home Assistant Container LXC** \n  - Add an option to use Fuse Overlayfs (ZFS) (Advanced)\n\n- **Docker LXC** \n  - Add an option to use Fuse Overlayfs (ZFS) (Advanced)\n  - If the LXC is created Privileged, the script will automatically set up USB passthrough.\n\n## 2022-12-22\n\n### Changed\n\n- **All LXC's** \n  - Add an option to run the script in Verbose Mode (Advanced)\n\n## 2022-12-20\n\n### Changed\n\n- **Hyperion LXC** \n  - NEW Script\n\n## 2022-12-17\n\n### Changed\n\n- **Home Assistant Core LXC** \n  - Linux D-Bus Message Broker\n  - Mariadb & PostgreSQL Ready\n  - Bluetooth Ready\n  - Fix for Inconsistent Dependency Versions (dbus-fast & bleak)\n\n## 2022-12-16\n\n### Changed\n\n- **Home Assistant Core LXC** \n  - Python 3.10.8\n\n## 2022-12-09\n\n### Changed\n\n- **Change Detection LXC** \n  - NEW Script\n\n## 2022-12-03\n\n### Changed\n\n- **All LXC's** \n  - Add options to set DNS Server IP Address and DNS Search Domain (Advanced)\n\n## 2022-11-27\n\n### Changed\n\n- **Shinobi LXC** \n  - NEW Script\n\n## 2022-11-24\n\n### Changed\n\n- **Home Assistant OS VM** \n  - Add option to set machine type during VM creation (Advanced)\n\n## 2022-11-23\n\n### Changed\n\n- **All LXC's** \n  - Add option to enable root ssh access during LXC creation (Advanced)\n\n## 2022-11-21\n\n### Changed\n\n- **Proxmox LXC Updater** \n  - Now updates Ubuntu, Debian, Devuan, Alpine Linux, CentOS-Rocky-Alma, Fedora, ArchLinux [(@Uruknara)](https://github.com/tteck/Proxmox/commits?author=Uruknara)\n\n## 2022-11-13\n\n### Changed\n\n- **All LXC's** \n  - Add option to continue upon Internet NOT Connected\n\n## 2022-11-11\n\n### Changed\n\n- **HA Bluetooth Integration Preparation** \n  - [NEW Script](https://github.com/tteck/Proxmox/discussions/719)\n\n## 2022-11-04\n\n### Changed\n\n- **Scrypted LXC** \n  - NEW Script\n\n## 2022-11-01\n\n### Changed\n\n- **Alpine LXC** \n  - NEW Script\n- **Arch LXC** \n  - NEW Script\n\n## 2022-10-27\n\n### Changed\n\n- **Container & Core Restore from Backup** \n  - [NEW Scripts](https://github.com/tteck/Proxmox/discussions/674)\n\n## 2022-10-07\n\n### Changed\n\n- **Home Assistant OS VM** \n  - Add \"Latest\" Image\n\n## 2022-10-05\n\n### Changed\n\n- **Umbrel LXC** \n  - NEW Script (Docker)\n- **Blocky LXC** \n  - NEW Script (Adblocker - DNS)\n\n## 2022-09-29\n\n### Changed\n\n- **Home Assistant Container LXC** \n  - If the LXC is created Privileged, the script will automatically set up USB passthrough.\n- **Home Assistant Core LXC** \n  - NEW Script\n- **PiMox HAOS VM** \n  - NEW Script\n\n## 2022-09-23\n\n### Changed\n\n- **EMQX LXC** \n  - NEW Script\n\n## 2022-09-22\n\n### Changed\n\n- **NextCloudPi LXC** \n  - NEW Script\n\n## 2022-09-21\n\n### Changed\n\n- **Proxmox Backup Server Post Install** \n  - NEW Script\n- **Z-wave JS UI LXC** \n  - NEW Script (and all sub scripts 🤞)\n- **Zwave2MQTT LXC** \n  - Bye Bye Script\n\n## 2022-09-20\n\n### Changed\n\n- **OpenMediaVault LXC** \n  - NEW Script\n\n## 2022-09-16\n\n### Changed\n\n- **Paperless-ngx LXC** \n  - NEW Script (Thanks @Donkeykong307)\n\n## 2022-09-11\n\n### Changed\n\n- **Trilium LXC** \n  - NEW Script\n\n## 2022-09-10\n\n### Changed\n\n- **Syncthing LXC** \n  - NEW Script\n\n## 2022-09-09\n\n### Changed\n\n- **CasaOS LXC** \n  - NEW Script\n- **Proxmox Kernel Clean** \n  - Now works with Proxmox Backup Server\n\n## 2022-09-08\n\n### Changed\n\n- **Navidrome LXC** \n  - NEW Script\n- **Homepage LXC** \n  - NEW Script\n\n## 2022-08-31\n\n### Changed\n\n- **All LXC's** \n  - Add Internet & DNS Check\n\n## 2022-08-22\n\n### Changed\n\n- **Wiki.js LXC** \n  - NEW Script\n- **Emby Media Server LXC**\n  - NEW Script\n\n## 2022-08-20\n\n### Changed\n\n- **Mikrotik RouterOS VM** \n  - NEW Script\n\n## 2022-08-19\n\n### Changed\n\n- **PhotoPrism LXC** \n  - Fixed .env bug (Thanks @cklam2)\n\n## 2022-08-13\n\n### Changed\n\n- **Home Assistant OS VM** \n  - Option to create VM using Stable, Beta or Dev Image\n\n## 2022-08-11\n\n### Changed\n\n- **Home Assistant OS VM** \n  - Validate Storage\n\n## 2022-08-04\n\n### Changed\n\n- **VS Code Server** \n  - NEW Script\n\n## 2022-08-02\n\n### Changed\n\n- **All LXC/VM** \n  - v4 Script - Whiptail menu's\n\n## 2022-07-26\n\n### Changed\n\n- **Home Assistant OS VM** \n  - Set the real time clock (RTC) to local time.\n  - Disable the USB tablet device (save resources / not needed).\n\n## 2022-07-24\n\n### Changed\n\n- **Home Assistant OS VM** \n  - Present the drive to the guest as a solid-state drive rather than a rotational hard disk. There is no requirement that the underlying storage actually be backed by SSD's. \n  - When the VM’s filesystem marks blocks as unused after deleting files, the SCSI controller will relay this information to the storage, which will then shrink the disk image accordingly.\n  - 👉 [more info](https://github.com/tteck/Proxmox/discussions/378)\n\n## 2022-07-22\n\n### Changed\n\n- **n8n LXC** (thanks to @cyakimov)\n  - NEW Script\n\n## 2022-07-21\n\n### Changed\n\n- **grocy LXC**\n  - NEW Script\n\n## 2022-07-17\n\n### Changed\n\n- **Vaultwarden LXC**\n  - NEW Vaultwarden Update (post 2022-05-29 installs only) Script\n  - NEW Web-vault Update (any) Script\n\n## 2022-07-14\n\n### Changed\n\n- **MagicMirror Server LXC**\n  - NEW Script\n\n## 2022-07-13\n\n### Changed\n\n- **Proxmox Edge Kernel Tool**\n  - NEW Script\n\n## 2022-07-11\n\n### Changed\n\n- **Home Assistant OS VM**\n  - Supports lvmthin, zfspool, nfs, dir and btrfs storage types.\n\n## 2022-07-08\n\n### Changed\n\n- **openHAB LXC**\n  - NEW Script\n\n## 2022-07-03\n\n### Changed\n\n- **Tailscale**\n  - NEW Script\n\n## 2022-07-01\n\n### Changed\n\n- **Home Assistant OS VM**\n  - Allow different storage types (lvmthin, nfs, dir).\n\n## 2022-06-30\n\n### Changed\n\n- **Prometheus LXC**\n  - NEW Script\n\n## 2022-06-06\n\n### Changed\n\n- **Whoogle LXC**\n  - NEW Script\n\n## 2022-05-29\n\n### Changed\n\n- **Vaultwarden LXC**\n  - Code refactoring\n- **CrowdSec**\n  - NEW Script\n\n## 2022-05-21\n\n### Changed\n\n- **Home Assistant OS VM**\n  - Code refactoring\n\n## 2022-05-19\n\n### Changed\n\n- **Keycloak LXC**\n  - NEW Script\n\n## 2022-05-18\n\n### Changed\n\n- **File Browser**\n  - NEW Script\n\n## 2022-05-13\n\n### Changed\n\n- **PostgreSQL LXC**\n  - NEW Script\n\n## 2022-05-10\n\n### Changed\n\n- **deCONZ LXC**\n  - NEW Script\n\n## 2022-05-07\n\n### Changed\n\n- **NocoDB LXC**\n  - ADD update script\n\n## 2022-05-06\n\n### Changed\n\n- **PhotoPrism LXC**\n  - ADD GO Dependencies for full functionality\n\n## 2022-05-05\n\n### Changed\n\n- **Ubuntu LXC**\n  - ADD option to define version (18.04 20.04 21.10 22.04)\n\n## 2022-04-28\n\n### Changed\n\n- **v3 Script**\n  - Remove Internet Check\n\n## 2022-04-27\n\n### Changed\n\n- **Home Assistant OS VM**\n  - ADD Option to set Bridge, VLAN and MAC Address\n- **v3 Script**\n  - Improve Internet Check (prevent ‼ ERROR 4@57)\n\n## 2022-04-26\n\n### Changed\n\n- **Home Assistant OS VM**\n  - Fixed bad path\n  - ADD Option to create VM using Latest or Stable image\n- **UniFi Network Application LXC**\n  - ADD Local Controller Option\n\n## 2022-04-25\n\n### Changed\n\n- **v3 Script**\n  - Improve Error Handling\n\n## 2022-04-23\n\n### Changed\n\n- **v3 Script**\n  - ADD Internet Connection Check\n- **Proxmox VE 7 Post Install**\n  - NEW v3 Script\n- **Proxmox Kernel Clean**\n  - NEW v3 Script\n\n## 2022-04-22\n\n### Changed\n\n- **Omada Controller LXC**\n  - Update script to install version 5.1.7\n- **Uptime Kuma LXC**\n  - ADD Update script\n\n## 2022-04-20\n\n### Changed\n\n- **Ubuntu LXC**\n  - ADD option to install version 20.04 or 21.10\n- **v3 Script**\n  - ADD option to set Bridge\n\n## 2022-04-19\n\n### Changed\n\n- **ALL LXC's**\n  - New [V3 Install Script](https://github.com/tteck/Proxmox/issues/162) \n- **ioBroker LXC**\n  - New Script V3\n\n## 2022-04-13\n\n### Changed\n\n- **Uptime Kuma LXC**\n  - New Script V2\n\n## 2022-04-11\n\n### Changed\n\n- **Proxmox LXC Updater**\n  - ADD option to skip stopped containers\n- **Proxmox VE 7 Post Install**\n  - ADD PVE 7 check\n\n## 2022-04-10\n\n### Changed\n\n- **Debian 11 LXC**\n  - ADD An early look at the v3 install script\n\n## 2022-04-09\n\n### Changed\n\n- **NocoDB LXC**\n  - New Script V2\n\n## 2022-04-05\n\n### Changed\n\n- **MeshCentral LXC**\n  - New Script V2\n\n## 2022-04-01\n\n### Changed\n\n- **Scripts** (V2)\n  - FIX Pressing enter without making a selection first would cause an Error \n\n## 2022-03-28\n\n### Changed\n\n- **Docker LXC**\n  - Add Docker Compose Option (@wovalle)\n\n## 2022-03-27\n\n### Changed\n\n- **Heimdall Dashboard LXC**\n  - New Update Script\n\n## 2022-03-26\n\n### Changed\n\n- **UniFi Network Application LXC**\n  - New Script V2\n- **Omada Controller LXC**\n  - New Script V2\n\n## 2022-03-25\n\n### Changed\n\n- **Proxmox CPU Scaling Governor**\n  - New Script\n\n\n## 2022-03-24\n\n### Changed\n\n- **Plex Media Server LXC**\n  - Switch to Ubuntu 20.04 to support HDR tone mapping\n- **Docker LXC**\n  - Add Portainer Option\n\n## 2022-03-23\n\n### Changed\n\n- **Heimdall Dashboard LXC**\n  - New Script V2\n\n## 2022-03-20\n\n### Changed\n\n- **Scripts** (V2)\n  - ADD choose between Automatic or Manual DHCP  \n\n## 2022-03-18\n\n### Changed\n\n- **Technitium DNS LXC**\n  - New Script V2\n- **WireGuard LXC**\n  - Add WGDashboard\n\n## 2022-03-17\n\n### Changed\n\n- **Docker LXC**\n  - New Script V2\n\n## 2022-03-16\n\n### Changed\n\n- **PhotoPrism LXC**\n  - New Update/Branch Script\n\n## 2022-03-15\n\n### Changed\n\n- **Dashy LXC**\n  - New Update Script\n\n## 2022-03-14\n\n### Changed\n\n- **Zwavejs2MQTT LXC**\n  - New Update Script\n\n## 2022-03-12\n\n### Changed\n\n- **PhotoPrism LXC**\n  - New Script V2\n\n## 2022-03-11\n\n### Changed\n\n- **Vaultwarden LXC**\n  - New V2 Install Script\n\n## 2022-03-08\n\n### Changed\n\n- **Scripts** (V2)\n  - Choose between Privileged or Unprivileged CT and Automatic or Password Login \n- **ESPHome LXC**\n  - New V2 Install Script\n- **Zwavejs2MQTT LXC**\n  - New V2 Install Script\n- **Motioneye LXC**\n  - New V2 Install Script\n- **Pihole LXC**\n  - New V2 Install Script\n- **GamUntu LXC**\n  - New V2 Install Script\n\n## 2022-03-06\n\n### Changed\n\n- **Zwavejs2MQTT LXC**\n  - New GUI script to copy data from one Zwavejs2MQTT LXC to another Zwavejs2MQTT LXC\n\n## 2022-03-05\n\n### Changed\n\n- **Homebridge LXC**\n  - New Script V2\n\n## 2022-03-04\n\n### Changed\n\n- **Proxmox Kernel Clean**\n  - New Script\n\n## 2022-03-03\n\n### Changed\n\n- **WireGuard LXC**\n  - New Script V2\n\n## 2022-03-02\n\n### Changed\n\n- **Proxmox LXC Updater**\n  - New Script\n- **Dashy LXC**\n  - New Script V2\n- **Grafana LXC**\n  - New Script V2\n- **InfluxDB/Telegraf LXC**\n  - New Script V2\n\n## 2022-03-01\n\n### Changed\n\n- **Daemon Sync Server LXC**\n  - New Script V2\n\n## 2022-02-28\n\n### Changed\n\n- **Vaultwarden LXC**\n  - Add Update Script\n\n## 2022-02-24\n\n### Changed\n\n- **Nginx Proxy Manager LXC**\n  - New V2 Install Script\n\n## 2022-02-23\n\n### Changed\n\n- **Adguard Home LXC**\n  - New V2 Install Script\n- **Zigbee2MQTT LXC**\n  - New V2 Install Script\n- **Home Assistant Container LXC**\n  - Update Menu usability improvements\n\n## 2022-02-22\n\n### Changed\n\n- **Home Assistant Container LXC**\n  - New V2 Install Script\n- **Node-Red LXC**\n  - New V2 Install Script\n- **Mariadb LXC**\n  - New V2 Install Script\n- **MQTT LXC**\n  - New V2 Install Script\n- **Debian 11 LXC**\n  - New V2 Install Script\n- **Ubuntu 21.10 LXC**\n  - New V2 Install Script\n\n## 2022-02-20\n\n### Changed\n\n- **Home Assistant Container LXC**\n  - New Script to migrate to the latest Update Menu\n\n## 2022-02-19\n\n### Changed\n\n- **Nginx Proxy Manager LXC**\n  - Add Update Script\n- **Vaultwarden LXC**\n  - Make unattended install & Cleanup Script\n\n## 2022-02-18\n\n### Changed\n\n- **Node-Red LXC**\n  - Add Install [Themes Script](https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/node-red-themes.png)\n\n## 2022-02-16\n\n### Changed\n\n- **Home Assistant Container LXC**\n  - Add Options to [Update Menu](https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/update-menu.png)\n\n## 2022-02-14\n\n### Changed\n\n- **Home Assistant Container LXC**\n  - Add [Update Menu](https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/update-menu.png)\n\n## 2022-02-13\n\n### Changed\n\n- **Mariadb LXC**\n  - Add [Adminer](https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/adminer.png) (formerly phpMinAdmin), a full-featured database management tool\n\n## 2022-02-12\n\n### Changed\n\n- **Home Assistant Container LXC (Podman)**\n  - Add Yacht web interface for managing Podman containers\n  - new GUI script to copy data from a **Home Assistant LXC** to a **Podman Home Assistant LXC**\n  - Improve documentation for several LXC's\n\n## 2022-02-10\n\n### Changed\n\n- **GamUntu LXC**\n  - New Script\n- **Jellyfin Media Server LXC**\n  - new script to fix [start issue](https://github.com/tteck/Proxmox/issues/29#issue-1127457380)\n- **MotionEye NVR LXC**\n  - New script\n\n## 2022-02-09\n\n### Changed\n\n- **Zigbee2MQTT LXC**\n  - added USB passthrough during installation (no extra script)\n  - Improve documentation\n- **Zwavejs2MQTT LXC**\n  - added USB passthrough during installation (no extra script)\n- **Jellyfin Media Server LXC**\n  - Moved to testing due to issues. \n  - Changed install method.\n- **Home Assistant Container LXC (Podman)** \n  - add script for easy Home Assistant update\n\n## 2022-02-06\n\n### Changed\n\n- **Debian 11 LXC**\n  - Add Docker Support\n- **Ubuntu 21.10 LXC**\n  - Add Docker Support\n\n## 2022-02-05\n\n### Changed\n\n- **Vaultwarden LXC**\n  - New script\n\n## 2022-02-01\n\n### Changed\n\n- **All Scripts**\n  - Fix issue where some networks were slow to assign a IP address to the container causing scripts to fail.\n\n## 2022-01-30\n\n### Changed\n\n- **Zigbee2MQTT LXC**\n  - Clean up / Improve script\n  - Improve documentation\n\n## 2022-01-29\n\n### Changed\n\n- **Node-Red LXC**\n  - Clean up / Improve script\n  - Improve documentation\n\n## 2022-01-25\n\n### Changed\n\n- **Jellyfin Media Server LXC**\n  - new script\n\n## 2022-01-24\n\n### Changed\n\n- **Plex Media Server LXC**\n  - better Hardware Acceleration Support\n  - `va-driver-all` is preinstalled\n  - now using Ubuntu 21.10\n- **misc**\n  - new GUI script [(Screenshot)](https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/pms-copy-data.png) to copy data from one Plex Media Server LXC to another Plex Media Server LXC \n\n\n## Initial Catch up - 2022-01-23\n \n### Changed\n\n- **Plex Media Server LXC**\n  - add Hardware Acceleration Support\n  - add script to install Intel Drivers\n- **Zwavejs2MQTT LXC**\n  - new script to solve no auto start at boot\n- **Nginx Proxy Manager LXC** \n  - new script to use Debian 11\n- **Ubuntu 21.10 LXC** \n  - new script\n- **Mariadb LXC** \n  - add MariaDB Package Repository\n- **MQTT LXC** \n  - add Eclipse Mosquitto Package Repository\n- **Home Assistant Container LXC** \n  - change if ZFS filesystem is detected, execute automatic installation of static fuse-overlayfs\n  - add script for easy Home Assistant update\n- **Home Assistant Container LXC (Podman)** \n  - change if ZFS filesystem is detected, execute automatic installation of static fuse-overlayfs\n- **Home Assistant OS VM** \n  - change disk type from SATA to SCSI to follow Proxmox official recommendations of choosing VirtIO-SCSI with SCSI disk\n  - clean up\n- **Proxmox VE 7 Post Install** \n  - new *No-Nag* method\n- **misc**\n  - new GUI script to copy data from one Home Assistant LXC to another Home Assistant LXC\n  - new GUI script to copy data from one Zigbee2MQTT LXC to another Zigbee2MQTT LXC\n"
  },
  {
    "path": "CODE-AUDIT.md",
    "content": "<div align=\"center\">\n<img src=\"https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/logo.png\" height=\"100px\" />\n</div>\n<h2><div align=\"center\">Exploring the Scripts and Steps Involved in an Application LXC Installation</div></h2>\n\n1) [adguard.sh](https://github.com/tteck/Proxmox/blob/main/ct/adguard.sh): This script collects system parameters. (Also holds the function to update the application.)\n2) [build.func](https://github.com/tteck/Proxmox/blob/main/misc/build.func): Adds user settings and integrates collected information.\n3) [create_lxc.sh](https://github.com/tteck/Proxmox/blob/main/ct/create_lxc.sh): Constructs the LXC container.\n4) [adguard-install.sh](https://github.com/tteck/Proxmox/blob/main/install/adguard-install.sh): Executes functions from [install.func](https://github.com/tteck/Proxmox/blob/main/misc/install.func), and installs the application.\n5) [adguard.sh](https://github.com/tteck/Proxmox/blob/main/ct/adguard.sh) (again): To display the completion message.\n\nThe installation process uses reusable scripts: [build.func](https://github.com/tteck/Proxmox/blob/main/misc/build.func), [create_lxc.sh](https://github.com/tteck/Proxmox/blob/main/ct/create_lxc.sh), and [install.func](https://github.com/tteck/Proxmox/blob/main/misc/install.func), which are not specific to any particular application.\n\nTo gain a better understanding, focus on reviewing [adguard-install.sh](https://github.com/tteck/Proxmox/blob/main/install/adguard-install.sh). This script contains the commands and configurations for installing and configuring AdGuard Home within the LXC container.\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2021-2024 tteck\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "<div style=\"border: 2px solid #d1d5db; padding: 20px; border-radius: 8px; background-color: #f9fafb;\"> <h2 align=\"center\">Proxmox VE Helper-Scripts: A Community Legacy</h2> <p>Dear Community,</p> <p>As we prepare to archive this repository, we’re excited to announce a new home for the project: <a href=\"https://github.com/community-scripts/ProxmoxVE\">https://github.com/community-scripts/ProxmoxVE</a>. While we’re still settling in, this will soon become the go-to place for the latest Proxmox VE scripts.</p> <p>Thank you for your continued support.</p> <br>The Community </div>\n<div align=\"center\">\n  <a href=\"#\">\n    <img src=\"https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/logo.png\" height=\"100px\" />\n </a>\n</div>\n<h1 align=\"center\">Proxmox VE Helper-Scripts</h1>\n\n<p align=\"center\">\n  <a href=\"https://helper-scripts.com\">Website</a> | \n  <a href=\"https://github.com/tteck/Proxmox/blob/main/.github/CONTRIBUTING.md\">Contribute</a> |\n  <a href=\"https://github.com/tteck/Proxmox/blob/main/USER_SUBMITTED_GUIDES.md\">Guides</a> |\n  <a href=\"https://github.com/tteck/Proxmox/blob/main/CHANGELOG.md\">Changelog</a> |\n  <a href=\"https://ko-fi.com/D1D7EP4GF\">Support</a>\n</p>\n\n---\n\nThese scripts empower users to create a Linux container or virtual machine interactively, providing choices for both simple and advanced configurations. The basic setup adheres to default settings, while the advanced setup gives users the ability to customize these defaults. \n\nOptions are displayed to users in a dialog box format. Once the user makes their selections, the script collects and validates their input to generate the final configuration for the container or virtual machine.\n<p align=\"center\">\nBe cautious and thoroughly evaluate scripts and automation tasks obtained from external sources. <a href=\"https://github.com/tteck/Proxmox/blob/main/CODE-AUDIT.md\">Read more</a>\n</p>\n<sub><div align=\"center\"> Proxmox® is a registered trademark of Proxmox Server Solutions GmbH. </div></sub>\n"
  },
  {
    "path": "USER_SUBMITTED_GUIDES.md",
    "content": "<div align=\"center\">\n  <a href=\"#\">\n    <img src=\"https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/logo.png\" height=\"100px\" />\n </a>\n</div>\n<h2 align=\"center\">User Submitted Guides </h2>\n\n<sub> In order to contribute a guide on installing with Proxmox VE Helper Scripts, you should open a pull request that adds the guide to the `USER_SUBMITTED_GUIDES.md` file. </sub>\n\n[Proxmox Automation with Proxmox Helper Scripts!](https://www.youtube.com/watch?v=kcpu4z5eSEU)\n\n[Installing Home Assistant OS using Proxmox 8](https://community.home-assistant.io/t/installing-home-assistant-os-using-proxmox-8/201835)\n\n[How To Separate Zigbee2MQTT From Home Assistant In Proxmox](https://smarthomescene.com/guides/how-to-separate-zigbee2mqtt-from-home-assistant-in-proxmox/)\n\n[How To Install Home Assistant On Proxmox: The Easy Way](https://smarthomescene.com/guides/how-to-install-home-assistant-on-proxmox-the-easy-way/)\n\n[Home Assistant: Installing InfluxDB (LXC)](https://www.derekseaman.com/2023/04/home-assistant-installing-influxdb-lxc.html)\n\n[Home Assistant: Proxmox Quick Start Guide](https://www.derekseaman.com/2023/10/home-assistant-proxmox-ve-8-0-quick-start-guide-2.html)\n\n[Home Assistant: Installing Grafana (LXC) with Let’s Encrypt SSL](https://www.derekseaman.com/2023/04/home-assistant-installing-grafana-lxc.html)\n\n[Proxmox: Plex LXC with Alder Lake Transcoding](https://www.derekseaman.com/2023/04/proxmox-plex-lxc-with-alder-lake-transcoding.html)\n\n[How To Backup Home Assistant In Proxmox](https://smarthomescene.com/guides/how-to-backup-home-assistant-in-proxmox/)\n\n[Running Frigate on Proxmox](https://www.homeautomationguy.io/blog/running-frigate-on-proxmox)\n\n[Frigate VM on Proxmox with PCIe Coral TPU](https://www.derekseaman.com/2023/06/home-assistant-frigate-vm-on-proxmox-with-pcie-coral-tpu.html)\n\n[Moving Home Assistant’s Database To MariaDB On Proxmox](https://smarthomescene.com/guides/moving-home-assistants-database-to-mariadb-on-proxmox/)\n\n[How-to: Proxmox VE 7.4 to 8.0 Upgrade](https://www.derekseaman.com/2023/06/how-to-proxmox-7-4-to-8-0-upgrade.html)\n\n[iGPU Transcoding In Proxmox with Jellyfin](https://www.youtube.com/watch?v=XAa_qpNmzZs)\n\n[Proxmox + NetData](<https://dbt3ch.com/books/proxmox-netdata-for-better-insights-and-notifications/page/proxmox-netdata-for-better-insights-and-notifications>)\n\n[Proxmox Homelab Series](<https://blog.kye.dev/proxmox-series>)\n\n[The fastest installation of Docker and Portainer on Proxmox VE](https://lavr.site/en-fastest-install-docker-portainer-proxmox/)\n\n[How To Setup Proxmox Backuper Server Using Helper Scripts](<https://youtu.be/6C2JOsrZZZw?si=kkrrcL_nLCDBJkOB>)\n"
  },
  {
    "path": "ct/actualbudget.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ___        __              __   ____            __           __\n   /   | _____/ /___  ______ _/ /  / __ )__  ______/ /___ ____  / /_\n  / /| |/ ___/ __/ / / / __ `/ /  / __  / / / / __  / __ `/ _ \\/ __/\n / ___ / /__/ /_/ /_/ / /_/ / /  / /_/ / /_/ / /_/ / /_/ /  __/ /_\n/_/  |_\\___/\\__/\\__,_/\\__,_/_/  /_____/\\__,_/\\__,_/\\__, /\\___/\\__/\n                                                  /____/\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Actual Budget\"\nvar_disk=\"4\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/actualbudget ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating ${APP}\"\nsystemctl stop actualbudget.service\ncd /opt/actualbudget\ngit pull &>/dev/null\nyarn install &>/dev/null\nsystemctl start actualbudget.service\nmsg_ok \"Successfully Updated ${APP}\"\nexit\n}\n\nstart\nbuild_container\ndescription\nmsg_info \"Setting Container to Normal Resources\"\npct set $CTID -memory 1024\npct set $CTID -cores 1\nmsg_ok \"Set Container to Normal Resources\"\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:5006${CL} \\n\"\n"
  },
  {
    "path": "ct/adguard.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ___       __                           __\n   /   | ____/ /___ ___  ______ __________/ /\n  / /| |/ __  / __  / / / / __  / ___/ __  / \n / ___ / /_/ / /_/ / /_/ / /_/ / /  / /_/ /  \n/_/  |_\\__,_/\\__, /\\__,_/\\__,_/_/   \\__,_/   \n            /____/                           \n \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Adguard\"\nvar_disk=\"2\"\nvar_cpu=\"1\"\nvar_ram=\"512\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/AdGuardHome ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nif (( $(df /boot | awk 'NR==2{gsub(\"%\",\"\",$5); print $5}') > 80 )); then\n  read -r -p \"Warning: Storage is dangerously low, continue anyway? <y/N> \" prompt\n  [[ ${prompt,,} =~ ^(y|yes)$ ]] || exit\nfi\nwget -qL https://static.adguard.com/adguardhome/release/AdGuardHome_linux_amd64.tar.gz\nmsg_info \"Stopping AdguardHome\"\nsystemctl stop AdGuardHome\nmsg_ok \"Stopped AdguardHome\"\n\nmsg_info \"Updating AdguardHome\"\ntar -xvf AdGuardHome_linux_amd64.tar.gz &>/dev/null\nmkdir -p adguard-backup\ncp -r /opt/AdGuardHome/AdGuardHome.yaml /opt/AdGuardHome/data adguard-backup/\ncp AdGuardHome/AdGuardHome /opt/AdGuardHome/AdGuardHome\ncp -r adguard-backup/* /opt/AdGuardHome/\nmsg_ok \"Updated AdguardHome\"\n\nmsg_info \"Starting AdguardHome\"\nsystemctl start AdGuardHome\nmsg_ok \"Started AdguardHome\"\n\nmsg_info \"Cleaning Up\"\nrm -rf AdGuardHome_linux_amd64.tar.gz AdGuardHome adguard-backup\nmsg_ok \"Cleaned\"\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} Setup should be reachable by going to the following URL.\n         ${BL}http://${IP}:3000${CL} \\n\"\n"
  },
  {
    "path": "ct/adventurelog.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck\n# Co-Author: MickLesk (Canbiz)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ___       __                 __                  __               \n   /   | ____/ /   _____  ____  / /___  __________  / /   ____  ____ _\n  / /| |/ __  / | / / _ \\/ __ \\/ __/ / / / ___/ _ \\/ /   / __ \\/ __ `/\n / ___ / /_/ /| |/ /  __/ / / / /_/ /_/ / /  /  __/ /___/ /_/ / /_/ / \n/_/  |_\\__,_/ |___/\\___/_/ /_/\\__/\\__,_/_/   \\___/_____/\\____/\\__, /  \n                                                             /____/   \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"AdventureLog\"\nvar_disk=\"7\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/adventurelog ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nif (( $(df /boot | awk 'NR==2{gsub(\"%\",\"\",$5); print $5}') > 80 )); then\n  read -r -p \"Warning: Storage is dangerously low, continue anyway? <y/N> \" prompt\n  [[ ${prompt,,} =~ ^(y|yes)$ ]] || exit\nfi\nRELEASE=$(curl -s https://api.github.com/repos/seanmorley15/AdventureLog/releases/latest | grep \"tag_name\" | awk '{print substr($2, 3, length($2)-4) }')\nif [[ ! -f /opt/${APP}_version.txt ]] || [[ \"${RELEASE}\" != \"$(cat /opt/${APP}_version.txt)\" ]]; then\n  msg_info \"Stopping Services\"\n  systemctl stop adventurelog-backend\n  systemctl stop adventurelog-frontend\n  msg_ok \"Services Stopped\"\n\n  msg_info \"Updating ${APP} to ${RELEASE}\"\n  cp /opt/adventurelog/backend/server/.env /opt/server.env\n  cp /opt/adventurelog/frontend/env /opt/frontend.env\n  wget -q \"https://github.com/seanmorley15/AdventureLog/archive/refs/tags/v${RELEASE}.zip\"\n  unzip -q v${RELEASE}.zip\n  mv AdventureLog-${RELEASE} /opt/adventurelog\n  mv /opt/server.env /opt/adventurelog/backend/server/.env\n  cd /opt/adventurelog/backend/server\n  pip install --upgrade pip &>/dev/null\n  pip install -r requirements.txt &>/dev/null\n  python3 manage.py collectstatic --noinput &>/dev/null\n  python3 manage.py migrate &>/dev/null\n  \n  mv /opt/frontend.env /opt/adventurelog/frontend/.env\n  cd /opt/adventurelog/frontend\n  pnpm install &>/dev/null\n  pnpm run build &>/dev/null\n  echo \"${RELEASE}\" >/opt/${APP}_version.txt\n  msg_ok \"Updated ${APP}\"\n\n  msg_info \"Starting Services\"\n  systemctl start adventurelog-backend\n  systemctl start adventurelog-frontend\n  msg_ok \"Started Services\"\n\n  msg_info \"Cleaning Up\"\n  rm -rf v${RELEASE}.zip\n  msg_ok \"Cleaned\"\n  msg_ok \"Updated Successfully\"\nelse\n  msg_ok \"No update required. ${APP} is already at ${RELEASE}\"\nfi\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} Setup should be reachable by going to the following URL.\n         ${BL}http://${IP}:3000${CL} \\n\""
  },
  {
    "path": "ct/agentdvr.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ___                    __  ____ _    ______\n   /   | ____ ____  ____  / /_/ __ \\ |  / / __ \\\n  / /| |/ __ `/ _ \\/ __ \\/ __/ / / / | / / /_/ /\n / ___ / /_/ /  __/ / / / /_/ /_/ /| |/ / _, _/\n/_/  |_\\__, /\\___/_/ /_/\\__/_____/ |___/_/ |_|\n      /____/\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"AgentDVR\"\nvar_disk=\"8\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"ubuntu\"\nvar_version=\"22.04\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"0\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/agentdvr ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_error \"There is currently no update path available.\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP}${CL} should be reachable by going to the following URL.\n         ${BL}http://${IP}:8090${CL} \\n\"\n"
  },
  {
    "path": "ct/alpine-docker.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\n  clear\n  cat <<\"EOF\"\n    ____             __            \n   / __ \\____  _____/ /_  __  _____\n  / / / / __ \\/ ___/ //_/ _ \\/ ___/\n / /_/ / /_/ / /__/ ,< /  __/ /    \n/_____/\\____/\\___/_/|_|\\___/_/     \n Alpine\n \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Alpine-Docker\"\nvar_disk=\"2\"\nvar_cpu=\"1\"\nvar_ram=\"1024\"\nvar_os=\"alpine\"\nvar_version=\"3.19\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\n  if ! apk -e info newt >/dev/null 2>&1; then\n    apk add -q newt\n  fi\n  while true; do\n    CHOICE=$(\n      whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"SUPPORT\" --menu \"Select option\" 11 58 1 \\\n        \"1\" \"Check for Docker Updates\" 3>&2 2>&1 1>&3\n    )\n    exit_status=$?\n    if [ $exit_status == 1 ]; then\n      clear\n      exit-script\n    fi\n    header_info\n    case $CHOICE in\n    1)\n      apk update && apk upgrade\n      exit\n      ;;\n    esac\n  done\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\n"
  },
  {
    "path": "ct/alpine-grafana.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\n  clear\n  cat <<\"EOF\"\n   ______           ____                 \n  / ____/________ _/ __/___ _____  ____ _\n / / __/ ___/ __  / /_/ __  / __ \\/ __  /\n/ /_/ / /  / /_/ / __/ /_/ / / / / /_/ / \n\\____/_/   \\__,_/_/  \\__,_/_/ /_/\\__,_/  \n Alpine\n \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Alpine-Grafana\"\nvar_disk=\"1\"\nvar_cpu=\"1\"\nvar_ram=\"256\"\nvar_os=\"alpine\"\nvar_version=\"3.19\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\n  if ! apk -e info newt >/dev/null 2>&1; then\n    apk add -q newt\n  fi\n  LXCIP=$(ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1)\n  while true; do\n    CHOICE=$(\n      whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"SUPPORT\" --menu \"Select option\" 11 58 3 \\\n        \"1\" \"Check for Grafana Updates\" \\\n        \"2\" \"Allow 0.0.0.0 for listening\" \\\n        \"3\" \"Allow only ${LXCIP} for listening\" 3>&2 2>&1 1>&3\n    )\n    exit_status=$?\n    if [ $exit_status == 1 ]; then\n      clear\n      exit-script\n    fi\n    header_info\n    case $CHOICE in\n    1)\n      apk update && apk upgrade\n      exit\n      ;;\n    2)\n      sed -i -e \"s/cfg:server.http_addr=.*/cfg:server.http_addr=0.0.0.0/g\" /etc/conf.d/grafana\n      service grafana restart\n      exit\n      ;;\n    3)\n      sed -i -e \"s/cfg:server.http_addr=.*/cfg:server.http_addr=$LXCIP/g\" /etc/conf.d/grafana\n      service grafana restart\n      exit\n      ;;\n    esac\n  done\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:3000${CL} \\n\"\n"
  },
  {
    "path": "ct/alpine-nextcloud.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\n  clear\n  cat <<\"EOF\"\n    _   __          __       __                __   __  __      __\n   / | / /__  _  __/ /______/ /___  __  ______/ /  / / / /_  __/ /_\n  /  |/ / _ \\| |/_/ __/ ___/ / __ \\/ / / / __  /  / /_/ / / / / __ \\\n / /|  /  __/>  </ /_/ /__/ / /_/ / /_/ / /_/ /  / __  / /_/ / /_/ /\n/_/ |_/\\___/_/|_|\\__/\\___/_/\\____/\\__,_/\\__,_/  /_/ /_/\\__,_/_.___/\nAlpine\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Alpine-Nextcloud\"\nvar_disk=\"2\"\nvar_cpu=\"2\"\nvar_ram=\"1024\"\nvar_os=\"alpine\"\nvar_version=\"3.19\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\n  if [[ ! -d /usr/share/webapps/nextcloud ]]; then\n    msg_error \"No ${APP} Installation Found!\"\n    exit\n  fi\n  if ! apk -e info newt >/dev/null 2>&1; then\n    apk add -q newt\n  fi\n  while true; do\n    CHOICE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"SUPPORT\" --radiolist --cancel-button Exit-Script \"Spacebar = Select\"  11 58 3 \\\n      \"1\" \"Nextcloud Login Credentials\" ON \\\n      \"2\" \"Renew Self-signed Certificate\" OFF \\\n      3>&1 1>&2 2>&3)      \n    exit_status=$?\n    if [ $exit_status == 1 ]; then\n      clear\n      exit-script\n    fi\n    header_info\n    case $CHOICE in\n    1)\n      cat nextcloud.creds\n      exit\n      ;;\n    2)\n      openssl req -x509 -nodes -days 365 -newkey rsa:4096 -keyout /etc/ssl/private/nextcloud-selfsigned.key -out /etc/ssl/certs/nextcloud-selfsigned.crt -subj \"/C=US/O=Nextcloud/OU=Domain Control Validated/CN=nextcloud.local\" > /dev/null 2>&1\n      rc-service nginx restart\n      exit\n      ;;\n    esac\n  done\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}https://${IP}${CL} \\n\"\n"
  },
  {
    "path": "ct/alpine-vaultwarden.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\n  clear\n  cat <<\"EOF\"\n _    __            ____                          __         \n| |  / /___ ___  __/ / /__      ______ __________/ /__  ____ \n| | / / __ `/ / / / / __/ | /| / / __ `/ ___/ __  / _ \\/ __ \\\n| |/ / /_/ / /_/ / / /_ | |/ |/ / /_/ / /  / /_/ /  __/ / / /\n|___/\\__,_/\\__,_/_/\\__/ |__/|__/\\__,_/_/   \\__,_/\\___/_/ /_/ \n Alpine                                                 \n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Alpine-Vaultwarden\"\nvar_disk=\"0.3\"\nvar_cpu=\"1\"\nvar_ram=\"256\"\nvar_os=\"alpine\"\nvar_version=\"3.19\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\n  if ! apk -e info newt >/dev/null 2>&1; then\n    apk add -q newt\n  fi\n  while true; do\n    CHOICE=$(\n      whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"SUPPORT\" --menu \"Select option\" 11 58 2 \\\n        \"1\" \"Update Vaultwarden\" \\\n        \"2\" \"Reset ADMIN_TOKEN\" 3>&2 2>&1 1>&3\n    )\n    exit_status=$?\n    if [ $exit_status == 1 ]; then\n      clear\n      exit-script\n    fi\n    header_info\n    case $CHOICE in\n    1)\n      apk update && apk upgrade && rc-service vaultwarden restart -q\n      exit\n      ;;\n    2)\n      if NEWTOKEN=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --passwordbox \"Setup your ADMIN_TOKEN (make it strong)\" 10 58 3>&1 1>&2 2>&3); then\n        if [[ -z \"$NEWTOKEN\" ]]; then exit-script; fi\n        if ! command -v argon2 >/dev/null 2>&1; then apk add argon2 &>/dev/null; fi\n        TOKEN=$(echo -n ${NEWTOKEN} | argon2 \"$(openssl rand -base64 32)\" -e -id -k 19456 -t 2 -p 1)\n        if [[ ! -f /var/lib/vaultwarden/config.json ]]; then\n          sed -i \"s|export ADMIN_TOKEN=.*|export ADMIN_TOKEN='${TOKEN}'|\" /etc/conf.d/vaultwarden\n        else\n          sed -i \"s|\\\"admin_token\\\": .*|\\\"admin_token\\\": \\\"${TOKEN}\\\",|\" /var/lib/vaultwarden/config.json\n        fi\n        rc-service vaultwarden restart -q\n      fi      \n      clear\n      exit\n      ;;\n    esac\n  done\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:8000${CL} \\n\"\n"
  },
  {
    "path": "ct/alpine-zigbee2mqtt.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\n  clear\n  cat <<\"EOF\"\n _____   _       __             ___   __  _______  ____________\n/__  /  (_)___ _/ /_  ___  ___ |__ \\ /  |/  / __ \\/_  __/_  __/\n  / /  / / __  / __ \\/ _ \\/ _ \\__/ // /|_/ / / / / / /   / /   \n / /__/ / /_/ / /_/ /  __/  __/ __// /  / / /_/ / / /   / /    \n/____/_/\\__, /_.___/\\___/\\___/____/_/  /_/\\___\\_\\/_/   /_/     \n       /____/ Alpine\n \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Alpine-Zigbee2MQTT\"\nvar_disk=\"0.3\"\nvar_cpu=\"1\"\nvar_ram=\"256\"\nvar_os=\"alpine\"\nvar_version=\"3.19\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"0\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\n  if ! apk -e info newt >/dev/null 2>&1; then\n    apk add -q newt\n  fi\n  while true; do\n    CHOICE=$(\n      whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"SUPPORT\" --menu \"Select option\" 11 58 1 \\\n        \"1\" \"Check for Zigbee2MQTT Updates\" 3>&2 2>&1 1>&3\n    )\n    exit_status=$?\n    if [ $exit_status == 1 ]; then\n      clear\n      exit-script\n    fi\n    header_info\n    case $CHOICE in\n    1)\n      apk update && apk upgrade\n      exit\n      ;;\n    esac\n  done\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\n"
  },
  {
    "path": "ct/alpine.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ___    __      _          \n   /   |  / /___  (_)___  ___ \n  / /| | / / __ \\/ / __ \\/ _ \\\n / ___ |/ / /_/ / / / / /  __/\n/_/  |_/_/ .___/_/_/ /_/\\___/ \n        /_/                   \n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Alpine\"\nvar_disk=\"0.1\"\nvar_cpu=\"1\"\nvar_ram=\"512\"\nvar_os=\"alpine\"\nvar_version=\"3.19\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"-password alpine\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nUPD=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"SUPPORT\" --radiolist --cancel-button Exit-Script \"Spacebar = Select\" 11 58 1 \\\n  \"1\" \"Check for Alpine Updates\" ON \\\n  3>&1 1>&2 2>&3)\n\nheader_info\nif [ \"$UPD\" == \"1\" ]; then\napk update && apk upgrade\nexit;\nfi\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\n"
  },
  {
    "path": "ct/apache-cassandra.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ___                     __            ______                                __\n   /   |  ____  ____ ______/ /_  ___     / ____/___ _______________ _____  ____/ /________ _\n  / /| | / __ \\/ __ `/ ___/ __ \\/ _ \\   / /   / __ `/ ___/ ___/ __ `/ __ \\/ __  / ___/ __ `/\n / ___ |/ /_/ / /_/ / /__/ / / /  __/  / /___/ /_/ (__  |__  ) /_/ / / / / /_/ / /  / /_/ /\n/_/  |_/ .___/\\__,_/\\___/_/ /_/\\___/   \\____/\\__,_/____/____/\\__,_/_/ /_/\\__,_/_/   \\__,_/\n      /_/\n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Apache-Cassandra\"\nvar_disk=\"4\"\nvar_cpu=\"1\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nVERBOSE=\"yes\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -f /etc/systemd/system/cassandra.service ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_error \"There is currently no update path available.\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\n"
  },
  {
    "path": "ct/apache-couchdb.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ___                     __            ______                 __    ____  ____ \n   /   |  ____  ____ ______/ /_  ___     / ____/___  __  _______/ /_  / __ \\/ __ )\n  / /| | / __ \\/ __ `/ ___/ __ \\/ _ \\   / /   / __ \\/ / / / ___/ __ \\/ / / / __  |\n / ___ |/ /_/ / /_/ / /__/ / / /  __/  / /___/ /_/ / /_/ / /__/ / / / /_/ / /_/ / \n/_/  |_/ .___/\\__,_/\\___/_/ /_/\\___/   \\____/\\____/\\__,_/\\___/_/ /_/_____/_____/  \n      /_/                                                                         \n                                \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Apache-CouchDB\"\nvar_disk=\"10\"\nvar_cpu=\"2\"\nvar_ram=\"4096\"\nvar_os=\"debian\"\nvar_version=\"12\"\nVERBOSE=\"yes\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -f /etc/systemd/system/couchdb.service ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_error \"There is currently no update path available.\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:5984/_utils/${CL} \\n\"\n"
  },
  {
    "path": "ct/apt-cacher-ng.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ___          __     ______           __                 _   ________\n   /   |  ____  / /_   / ____/___ ______/ /_  ___  _____   / | / / ____/\n  / /| | / __ \\/ __/__/ /   / __ `/ ___/ __ \\/ _ \\/ ___/__/  |/ / / __\n / ___ |/ /_/ / /_/__/ /___/ /_/ / /__/ / / /  __/ /  /__/ /|  / /_/ /\n/_/  |_/ .___/\\__/   \\____/\\__,_/\\___/_/ /_/\\___/_/     /_/ |_/\\____/\n      /_/\n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Apt-Cacher-NG\"\nvar_disk=\"2\"\nvar_cpu=\"1\"\nvar_ram=\"512\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /var ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating $APP LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated $APP LXC\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} maintenance page should be reachable by going to the following URL.\n         ${BL}http://${IP}:3142/acng-report.html${CL} \\n\"\n"
  },
  {
    "path": "ct/archivebox.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ___              __    _            ____\n   /   |  __________/ /_  (_)   _____  / __ )____  _  __\n  / /| | / ___/ ___/ __ \\/ / | / / _ \\/ __  / __ \\| |/_/\n / ___ |/ /  / /__/ / / / /| |/ /  __/ /_/ / /_/ />  <\n/_/  |_/_/   \\___/_/ /_/_/ |___/\\___/_____/\\____/_/|_|\n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"ArchiveBox\"\nvar_disk=\"8\"\nvar_cpu=\"2\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/archivebox ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nif (( $(df /boot | awk 'NR==2{gsub(\"%\",\"\",$5); print $5}') > 80 )); then\n  read -r -p \"Warning: Storage is dangerously low, continue anyway? <y/N> \" prompt\n  [[ ${prompt,,} =~ ^(y|yes)$ ]] || exit\nfi\nmsg_info \"Stopping ${APP}\"\nsystemctl stop archivebox\nmsg_ok \"Stopped ${APP}\"\n\nmsg_info \"Updating ${APP}\"\ncd /opt/archivebox/data\npip install --upgrade --ignore-installed archivebox\nsudo -u archivebox archivebox init\nmsg_ok \"Updated ${APP}\"\n\nmsg_info \"Starting ${APP}\"\nsystemctl start archivebox\nmsg_ok \"Started ${APP}\"\n\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:8000/admin/login${CL} \\n\"\n"
  },
  {
    "path": "ct/aria2.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ___         _      ___\n   /   |  _____(_)___ |__ \\\n  / /| | / ___/ / __ `/_/ /\n / ___ |/ /  / / /_/ / __/\n/_/  |_/_/  /_/\\__,_/____/\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Aria2\"\nvar_disk=\"8\"\nvar_cpu=\"2\"\nvar_ram=\"1028\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /var ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating $APP LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated $APP LXC\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:6880${CL}\"\n"
  },
  {
    "path": "ct/audiobookshelf.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n                   ___       __                __        __         ______\n  ____ ___  ______/ (_)___  / /_  ____  ____  / /_______/ /_  ___  / / __/\n / __ `/ / / / __  / / __ \\/ __ \\/ __ \\/ __ \\/ //_/ ___/ __ \\/ _ \\/ / /_  \n/ /_/ / /_/ / /_/ / / /_/ / /_/ / /_/ / /_/ / ,< (__  ) / / /  __/ / __/  \n\\__,_/\\__,_/\\__,_/_/\\____/_.___/\\____/\\____/_/|_/____/_/ /_/\\___/_/_/     \n                                                                          \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"audiobookshelf\"\nvar_disk=\"4\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -f /etc/apt/trusted.gpg.d/audiobookshelf-ppa.asc ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\necho \"This application receives updates through the APT package manager.\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:13378${CL} \\n\"\n"
  },
  {
    "path": "ct/autobrr.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ___         __        __             \n   /   | __  __/ /_____  / /_  __________\n  / /| |/ / / / __/ __ \\/ __ \\/ ___/ ___/\n / ___ / /_/ / /_/ /_/ / /_/ / /  / /    \n/_/  |_\\__,_/\\__/\\____/_.___/_/  /_/     \n                                         \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Autobrr\"\nvar_disk=\"8\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -f /root/.config/autobrr/config.toml ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Stopping ${APP} LXC\"\nsystemctl stop autobrr.service\nmsg_ok \"Stopped ${APP} LXC\"\n\nmsg_info \"Updating ${APP} LXC\"\nrm -rf /usr/local/bin/*\nwget -q $(curl -s https://api.github.com/repos/autobrr/autobrr/releases/latest | grep download | grep linux_x86_64 | cut -d\\\" -f4)\ntar -C /usr/local/bin -xzf autobrr*.tar.gz\nrm -rf autobrr*.tar.gz\nmsg_ok \"Updated ${APP} LXC\"\n\nmsg_info \"Starting ${APP} LXC\"\nsystemctl start autobrr.service\nmsg_ok \"Started ${APP} LXC\"\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:7474${CL} \\n\"\n"
  },
  {
    "path": "ct/bazarr.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ____\n   / __ )____ _____  ____ ___________\n  / __  / __ `/_  / / __ `/ ___/ ___/\n / /_/ / /_/ / / /_/ /_/ / /  / /\n/_____/\\__,_/ /___/\\__,_/_/  /_/\n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Bazarr\"\nvar_disk=\"4\"\nvar_cpu=\"2\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /var/lib/bazarr/ ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating $APP LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated $APP LXC\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:6767${CL} \\n\"\n"
  },
  {
    "path": "ct/blocky.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ____  __           __        \n   / __ )/ /___  _____/ /____  __\n  / __  / / __ \\/ ___/ //_/ / / /\n / /_/ / / /_/ / /__/ ,< / /_/ / \n/_____/_/\\____/\\___/_/|_|\\__, /  \n                        /____/   \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Blocky\"\nvar_disk=\"2\"\nvar_cpu=\"1\"\nvar_ram=\"512\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /var ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating $APP LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated $APP LXC\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\n"
  },
  {
    "path": "ct/bunkerweb.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ____              __            _       __     __\n   / __ )__  ______  / /_____  ____| |     / /__  / /_\n  / __  / / / / __ \\/ //_/ _ \\/ ___/ | /| / / _ \\/ __ \\\n / /_/ / /_/ / / / / ,< /  __/ /   | |/ |/ /  __/ /_/ /\n/_____/\\__,_/_/ /_/_/|_|\\___/_/    |__/|__/\\___/_.___/\n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"BunkerWeb\"\nvar_disk=\"4\"\nvar_cpu=\"2\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /etc/bunkerweb ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\n\nRELEASE=$(curl -s https://api.github.com/repos/bunkerity/bunkerweb/releases/latest | grep \"tag_name\" | awk '{print substr($2, 3, length($2)-4) }')\nif [[ ! -f /opt/${APP}_version.txt ]] || [[ \"${RELEASE}\" != \"$(cat /opt/${APP}_version.txt)\" ]]; then\n\n  msg_info \"Updating ${APP} to ${RELEASE}\"\n  cat <<EOF >/etc/apt/preferences.d/bunkerweb\nPackage: bunkerweb\nPin: version ${RELEASE}\nPin-Priority: 1001\nEOF\n  apt-get update\n  apt-get install -y nginx=1.26.2*\n  apt-get install -y bunkerweb=${RELEASE}\n  echo \"${RELEASE}\" >/opt/${APP}_version.txt\n  msg_ok \"Updated ${APP} to ${RELEASE}\"\n\nelse\n  msg_ok \"No update required. ${APP} is already at ${RELEASE}\"\nfi\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} setup should be reachable by going to the following URL.\n         ${BL}http://${IP}/setup${CL} \\n\"\n"
  },
  {
    "path": "ct/caddy.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n   ______          __    __\n  / ____/___ _____/ /___/ /_  __\n / /   / __ `/ __  / __  / / / /\n/ /___/ /_/ / /_/ / /_/ / /_/ /\n\\____/\\__,_/\\__,_/\\__,_/\\__, /\n                       /____/\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Caddy\"\nvar_disk=\"2\"\nvar_cpu=\"1\"\nvar_ram=\"512\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /etc/caddy ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating $APP LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated $APP LXC\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\n"
  },
  {
    "path": "ct/calibre-web.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# Co-Author: remz1337\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n   ______      ___ __                _       __     __\n  / ____/___ _/ (_) /_  ________    | |     / /__  / /_\n / /   / __ `/ / / __ \\/ ___/ _ \\___| | /| / / _ \\/ __ \\\n/ /___/ /_/ / / / /_/ / /  /  __/___/ |/ |/ /  __/ /_/ /\n\\____/\\__,_/_/_/_.___/_/   \\___/    |__/|__/\\___/_.___/\n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Calibre-Web\"\nvar_disk=\"4\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\n  if [[ ! -f /etc/systemd/system/cps.service ]]; then\n    msg_error \"No ${APP} Installation Found!\"\n    exit\n  fi\n  header_info\n  msg_info \"Updating $APP LXC\"\n  systemctl stop cps\n  cd /opt/kepubify\n  rm kepubify-linux-64bit\n  curl -fsSLO https://github.com/pgaskin/kepubify/releases/latest/download/kepubify-linux-64bit &>/dev/null\n  chmod +x kepubify-linux-64bit\n  menu_array=(\"1\" \"Enables gdrive as storage backend for your ebooks\" OFF \\\n    \"2\" \"Enables sending emails via a googlemail account without enabling insecure apps\" OFF \\\n    \"3\" \"Enables displaying of additional author infos on the authors page\" OFF \\\n    \"4\" \"Enables login via LDAP server\" OFF \\\n    \"5\" \"Enables login via google or github oauth\" OFF \\\n    \"6\" \"Enables extracting of metadata from epub, fb2, pdf files, and also extraction of covers from cbr, cbz, cbt files\" OFF \\\n    \"7\" \"Enables extracting of metadata from cbr, cbz, cbt files\" OFF \\\n    \"8\" \"Enables syncing with your kobo reader\" OFF )\n  if [ -f \"/opt/calibre-web/options.txt\" ]; then\n    cps_options=\"$(cat /opt/calibre-web/options.txt)\"\n    IFS=',' read -ra ADDR <<< \"$cps_options\"\n    for i in \"${ADDR[@]}\"; do\n\t  if [ $i == \"gdrive\" ]; then\n\t    line=0\n\t  elif [ $i == \"gmail\" ]; then\n\t    line=1\n          elif [ $i == \"goodreads\" ]; then\n\t    line=2\n\t  elif [ $i == \"ldap\" ]; then\n\t    line=3\n\t  elif [ $i == \"oauth\" ]; then\n\t    line=4\n\t  elif [ $i == \"metadata\" ]; then\n\t    line=5\n\t  elif [ $i == \"comics\" ]; then\n\t    line=6\n\t  elif [ $i == \"kobo\" ]; then\n\t    line=7\n\t  fi\n      array_index=$(( 3*line + 2 ))\n      menu_array[$array_index]=ON\n    done\n  fi\n  if [ -n \"$SPINNER_PID\" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi\n  CHOICES=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"CALIBRE-WEB OPTIONS\" --separate-output --checklist \"Choose Additional Options\" 15 125 8 \"${menu_array[@]}\" 3>&1 1>&2 2>&3)\n  spinner &\n  SPINNER_PID=$!\n  options=()\n  if [ ! -z \"$CHOICES\" ]; then\n    for CHOICE in $CHOICES; do\n      case \"$CHOICE\" in\n      \"1\")\n        options+=( gdrive )\n        ;;\n      \"2\")\n        options+=( gmail )\n        ;;\n      \"3\")\n        options+=( goodreads )\n        ;;\n      \"4\")\n        options+=( ldap )\n        apt-get install -qqy libldap2-dev libsasl2-dev\n        ;;\n      \"5\")\n        options+=( oauth )\n        ;;\n      \"6\")\n        options+=( metadata )\n        ;;\n      \"7\")\n        options+=( comics )\n        ;;\n      \"8\")\n        options+=( kobo )\n        ;;\n      *)\n        echo \"Unsupported item $CHOICE!\" >&2\n        exit 1\n        ;;\n      esac\n    done\n  fi\n  if [ ! -z \"$options\" ] && [ ${#options[@]} -gt 0 ]; then\n    cps_options=$(IFS=, ; echo \"${options[*]}\")\n    echo $cps_options > /opt/calibre-web/options.txt\n    pip install --upgrade calibreweb[$cps_options]\n  else\n    rm /opt/calibre-web/options.txt 2> /dev/null\n    pip install --upgrade calibreweb\n  fi\n  systemctl start cps\n  msg_ok \"Updated $APP LXC\"\n  exit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_info \"Setting Container to Normal Resources\"\npct set $CTID -memory 512\npct set $CTID -cores 1\nmsg_ok \"Set Container to Normal Resources\"\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:8083${CL} \\n\"\n"
  },
  {
    "path": "ct/casaos.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n   ______                 ____  _____\n  / ____/___ __________ _/ __ \\/ ___/\n / /   / __ `/ ___/ __ `/ / / /\\__ \\ \n/ /___/ /_/ (__  ) /_/ / /_/ /___/ / \n\\____/\\__,_/____/\\__,_/\\____//____/  \n                                     \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"CasaOS\"\nvar_disk=\"8\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /var ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating ${APP} LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated ${APP} LXC\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} Setup should be reachable by going to the following URL.\n         ${BL}http://${IP} ${CL} \\n\"\n"
  },
  {
    "path": "ct/changedetection.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n   ________                              ____       __            __  _           \n  / ____/ /_  ____ _____  ____ ____     / __ \\___  / /____  _____/ /_(_)___  ____ \n / /   / __ \\/ __ `/ __ \\/ __ `/ _ \\   / / / / _ \\/ __/ _ \\/ ___/ __/ / __ \\/ __ \\\n/ /___/ / / / /_/ / / / / /_/ /  __/  / /_/ /  __/ /_/  __/ /__/ /_/ / /_/ / / / /\n\\____/_/ /_/\\__,_/_/ /_/\\__, /\\___/  /_____/\\___/\\__/\\___/\\___/\\__/_/\\____/_/ /_/ \n                       /____/                                                     \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Change Detection\"\nvar_disk=\"8\"\nvar_cpu=\"2\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -f /etc/systemd/system/changedetection.service ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating ${APP} LXC\"\nif ! dpkg -s libjpeg-dev >/dev/null 2>&1; then\n  apt-get update\n  apt-get install -y libjpeg-dev\nfi\npip3 install changedetection.io --upgrade &>/dev/null\npip3 install playwright --upgrade &>/dev/null\nif [[ -f /etc/systemd/system/browserless.service ]]; then\n  git -C /opt/browserless/ fetch --all &>/dev/null\n  git -C /opt/browserless/ reset --hard origin/main &>/dev/null\n  npm update --prefix /opt/browserless &>/dev/null\n  npm run build --prefix /opt/browserless &>/dev/null\n  npm run build:function --prefix /opt/browserless &>/dev/null\n  npm prune production --prefix /opt/browserless &>/dev/null\n  systemctl restart browserless\nelse\n  msg_error \"No Browserless Installation Found!\"\nfi\nsystemctl restart changedetection\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:5000${CL} \\n\"\n"
  },
  {
    "path": "ct/channels.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n   ________                           __        ____ _    ______     _____\n  / ____/ /_  ____ _____  ____  ___  / /____   / __ \\ |  / / __ \\   / ___/___  ______   _____  _____\n / /   / __ \\/ __ `/ __ \\/ __ \\/ _ \\/ / ___/  / / / / | / / /_/ /   \\__ \\/ _ \\/ ___/ | / / _ \\/ ___/\n/ /___/ / / / /_/ / / / / / / /  __/ (__  )  / /_/ /| |/ / _, _/   ___/ /  __/ /   | |/ /  __/ /\n\\____/_/ /_/\\__,_/_/ /_/_/ /_/\\___/_/____/  /_____/ |___/_/ |_|   /____/\\___/_/    |___/\\___/_/\n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Channels\"\nvar_disk=\"8\"\nvar_cpu=\"2\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"0\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/channels-dvr ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_error \"There is currently no update path available.\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} Setup should be reachable by going to the following URL.\n         ${BL}http://${IP}:8089 ${CL} \\n\"\n"
  },
  {
    "path": "ct/cloudflared.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n   ________                ________                    __\n  / ____/ /___  __  ______/ / __/ /___ _________  ____/ /\n / /   / / __ \\/ / / / __  / /_/ / __ `/ ___/ _ \\/ __  / \n/ /___/ / /_/ / /_/ / /_/ / __/ / /_/ / /  /  __/ /_/ /  \n\\____/_/\\____/\\__,_/\\__,_/_/ /_/\\__,_/_/   \\___/\\__,_/   \n                                                         \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Cloudflared\"\nvar_disk=\"2\"\nvar_cpu=\"1\"\nvar_ram=\"512\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /var ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating $APP LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated $APP LXC\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\n"
  },
  {
    "path": "ct/cockpit.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck\n# Co-Author: havardthom\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"     \n   ______           __         _ __\n  / ____/___  _____/ /______  (_) /_\n / /   / __ \\/ ___/ //_/ __ \\/ / __/\n/ /___/ /_/ / /__/ ,< / /_/ / / /_\n\\____/\\____/\\___/_/|_/ .___/_/\\__/\n                    /_/\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Cockpit\"\nvar_disk=\"4\"\nvar_cpu=\"2\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nif [[ ! -d /etc/cockpit ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nUPD=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"SUPPORT\" --radiolist --cancel-button Exit-Script \"Spacebar = Select\" 11 58 4 \\\n  \"1\" \"Update LXC\" ON \\\n  \"2\" \"Install cockpit-file-sharing\" OFF \\\n  \"3\" \"Install cockpit-identities\" OFF \\\n  \"4\" \"Install cockpit-navigator\" OFF \\\n  3>&1 1>&2 2>&3)\n\nheader_info\nif [ \"$UPD\" == \"1\" ]; then\n  msg_info \"Updating ${APP} LXC\"\n  apt-get update &>/dev/null\n  apt-get -y upgrade &>/dev/null\n  msg_ok \"Updated ${APP} LXC\"\n  exit\nfi\nif [ \"$UPD\" == \"2\" ]; then\n  msg_info \"Installing dependencies (patience)\"\n  apt-get install -y attr &>/dev/null\n  apt-get install -y nfs-kernel-server &>/dev/null\n  apt-get install -y samba &>/dev/null\n  apt-get install -y samba-common-bin &>/dev/null\n  apt-get install -y winbind &>/dev/null\n  apt-get install -y gawk &>/dev/null\n  msg_ok \"Installed dependencies\"\n  msg_info \"Installing Cockpit file sharing\"\n  LATEST=$(curl -s https://api.github.com/repos/45Drives/cockpit-file-sharing/releases/latest  | grep \"tag_name\" | awk '{print substr($2, 3, length($2)-4) }')\n  wget -q https://github.com/45Drives/cockpit-file-sharing/releases/download/v${LATEST}/cockpit-file-sharing_${LATEST}-1focal_all.deb\n  dpkg -i cockpit-file-sharing_${LATEST}-1focal_all.deb &>/dev/null\n  rm cockpit-file-sharing_${LATEST}-1focal_all.deb\n  msg_ok \"Installed Cockpit file sharing\"\n  exit\nfi\nif [ \"$UPD\" == \"3\" ]; then\n  msg_info \"Installing dependencies (patience)\"\n  apt-get install -y psmisc &>/dev/null\n  apt-get install -y samba &>/dev/null\n  apt-get install -y samba-common-bin &>/dev/null\n  msg_ok \"Installed dependencies\"\n  msg_info \"Installing Cockpit identities\"\n  LATEST=$(curl -s https://api.github.com/repos/45Drives/cockpit-identities/releases/latest  | grep \"tag_name\" | awk '{print substr($2, 3, length($2)-4) }')\n  wget -q https://github.com/45Drives/cockpit-identities/releases/download/v${LATEST}/cockpit-identities_${LATEST}-1focal_all.deb\n  dpkg -i cockpit-identities_${LATEST}-1focal_all.deb &>/dev/null\n  rm cockpit-identities_${LATEST}-1focal_all.deb\n  msg_ok \"Installed Cockpit identities\"\n  exit\nfi\nif [ \"$UPD\" == \"4\" ]; then\n  msg_info \"Installing dependencies\"\n  apt-get install -y rsync &>/dev/null\n  apt-get install -y zip &>/dev/null\n  msg_ok \"Installed dependencies\"\n  msg_info \"Installing Cockpit navigator\"\n  LATEST=$(curl -s https://api.github.com/repos/45Drives/cockpit-navigator/releases/latest  | grep \"tag_name\" | awk '{print substr($2, 3, length($2)-4) }')\n  wget -q https://github.com/45Drives/cockpit-navigator/releases/download/v${LATEST}/cockpit-navigator_${LATEST}-1focal_all.deb\n  dpkg -i cockpit-navigator_${LATEST}-1focal_all.deb &>/dev/null\n  rm cockpit-navigator_${LATEST}-1focal_all.deb\n  msg_ok \"Installed Cockpit navigator\"\n  exit\nfi\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:9090${CL} \\n\"\n"
  },
  {
    "path": "ct/commafeed.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n   ______                                ______              __\n  / ____/___  ____ ___  ____ ___  ____ _/ ____/__  ___  ____/ /\n / /   / __ \\/ __ `__ \\/ __ `__ \\/ __ `/ /_  / _ \\/ _ \\/ __  /\n/ /___/ /_/ / / / / / / / / / / / /_/ / __/ /  __/  __/ /_/ /\n\\____/\\____/_/ /_/ /_/_/ /_/ /_/\\__,_/_/    \\___/\\___/\\__,_/\n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"CommaFeed\"\nvar_disk=\"4\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/commafeed ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nRELEASE=$(curl -sL https://api.github.com/repos/Athou/commafeed/releases/latest | grep '\"tag_name\":' | cut -d'\"' -f4)\nif [[ ! -f /opt/${APP}_version.txt ]] || [[ \"${RELEASE}\" != \"$(cat /opt/${APP}_version.txt)\" ]]; then\n  msg_info \"Stopping ${APP}\"\n  systemctl stop commafeed\n  msg_ok \"Stopped ${APP}\"\n\n  msg_info \"Updating ${APP} to ${RELEASE}\"\n  wget -q https://github.com/Athou/commafeed/releases/download/${RELEASE}/commafeed-${RELEASE}-h2-jvm.zip\n  unzip -q commafeed-${RELEASE}-h2-jvm.zip\n  rsync -a --exclude 'data/' commafeed-${RELEASE}-h2/ /opt/commafeed/\n  rm -rf commafeed-${RELEASE}-h2  commafeed-${RELEASE}-h2-jvm.zip\n  echo \"${RELEASE}\" >/opt/${APP}_version.txt\n  msg_ok \"Updated ${APP} to ${RELEASE}\"\n\n  msg_info \"Starting ${APP}\"\n  systemctl start commafeed\n  msg_ok \"Started ${APP}\"\n  msg_ok \"Updated Successfully\"\nelse\n  msg_ok \"No update required. ${APP} is already at ${RELEASE}\"\nfi\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:8082${CL} \\n\"\n"
  },
  {
    "path": "ct/create_lxc.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\n# This sets verbose mode if the global variable is set to \"yes\"\n# if [ \"$VERBOSE\" == \"yes\" ]; then set -x; fi\n\n# This function sets color variables for formatting output in the terminal\nYW=$(echo \"\\033[33m\")\nBL=$(echo \"\\033[36m\")\nRD=$(echo \"\\033[01;31m\")\nGN=$(echo \"\\033[1;92m\")\nCL=$(echo \"\\033[m\")\nCM=\"${GN}✓${CL}\"\nCROSS=\"${RD}✗${CL}\"\nBFR=\"\\\\r\\\\033[K\"\nHOLD=\" \"\n\n# This sets error handling options and defines the error_handler function to handle errors\nset -Eeuo pipefail\ntrap 'error_handler $LINENO \"$BASH_COMMAND\"' ERR\n\n# This function handles errors\nfunction error_handler() {\n  if [ -n \"$SPINNER_PID\" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi\n  printf \"\\e[?25h\"\n  local exit_code=\"$?\"\n  local line_number=\"$1\"\n  local command=\"$2\"\n  local error_message=\"${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}\"\n  echo -e \"\\n$error_message\\n\"\n}\n\n# This function displays a spinner.\nfunction spinner() {\n    local chars=\"/-\\|\"\n    local spin_i=0\n    printf \"\\e[?25l\"\n    while true; do\n        printf \"\\r \\e[36m%s\\e[0m\" \"${chars:spin_i++%${#chars}:1}\"\n        sleep 0.1\n    done\n}\n\n# This function displays an informational message with a yellow color.\nfunction msg_info() {\n  local msg=\"$1\"\n  echo -ne \" ${HOLD} ${YW}${msg}   \"\n  spinner &\n  SPINNER_PID=$!\n}\n\n# This function displays a success message with a green color.\nfunction msg_ok() {\n  if [ -n \"$SPINNER_PID\" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi\n  printf \"\\e[?25h\"\n  local msg=\"$1\"\n  echo -e \"${BFR} ${CM} ${GN}${msg}${CL}\"\n}\n\n# This function displays a error message with a red color.\nfunction msg_error() {\n  if [ -n \"$SPINNER_PID\" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi\n  printf \"\\e[?25h\"\n  local msg=\"$1\"\n  echo -e \"${BFR} ${CROSS} ${RD}${msg}${CL}\"\n}\n\n# This checks for the presence of valid Container Storage and Template Storage locations\nmsg_info \"Validating Storage\"\nVALIDCT=$(pvesm status -content rootdir | awk 'NR>1')\nif [ -z \"$VALIDCT\" ]; then\n  msg_error \"Unable to detect a valid Container Storage location.\"\n  exit 1\nfi\nVALIDTMP=$(pvesm status -content vztmpl | awk 'NR>1')\nif [ -z \"$VALIDTMP\" ]; then\n  msg_error \"Unable to detect a valid Template Storage location.\"\n  exit 1\nfi\n\n# This function is used to select the storage class and determine the corresponding storage content type and label.\nfunction select_storage() {\n  local CLASS=$1\n  local CONTENT\n  local CONTENT_LABEL\n  case $CLASS in\n  container)\n    CONTENT='rootdir'\n    CONTENT_LABEL='Container'\n    ;;\n  template)\n    CONTENT='vztmpl'\n    CONTENT_LABEL='Container template'\n    ;;\n  *) false || exit \"Invalid storage class.\" ;;\n  esac\n  \n  # This Queries all storage locations\n  local -a MENU\n  while read -r line; do\n    local TAG=$(echo $line | awk '{print $1}')\n    local TYPE=$(echo $line | awk '{printf \"%-10s\", $2}')\n    local FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( \"%9sB\", $6)}')\n    local ITEM=\"  Type: $TYPE Free: $FREE \"\n    local OFFSET=2\n    if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then\n      local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET))\n    fi\n    MENU+=(\"$TAG\" \"$ITEM\" \"OFF\")\n  done < <(pvesm status -content $CONTENT | awk 'NR>1')\n  \n  # Select storage location\n  if [ $((${#MENU[@]}/3)) -eq 1 ]; then\n    printf ${MENU[0]}\n  else\n    local STORAGE\n    while [ -z \"${STORAGE:+x}\" ]; do\n      STORAGE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"Storage Pools\" --radiolist \\\n      \"Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\\nTo make a selection, use the Spacebar.\\n\" \\\n      16 $(($MSG_MAX_LENGTH + 23)) 6 \\\n      \"${MENU[@]}\" 3>&1 1>&2 2>&3) || exit \"Menu aborted.\"\n    done\n    printf $STORAGE\n  fi\n}\n\n# Test if required variables are set\n[[ \"${CTID:-}\" ]] || exit \"You need to set 'CTID' variable.\"\n[[ \"${PCT_OSTYPE:-}\" ]] || exit \"You need to set 'PCT_OSTYPE' variable.\"\n\n# Test if ID is valid\n[ \"$CTID\" -ge \"100\" ] || exit \"ID cannot be less than 100.\"\n\n# Test if ID is in use\nif pct status $CTID &>/dev/null; then\n  echo -e \"ID '$CTID' is already in use.\"\n  unset CTID\n  exit \"Cannot use ID that is already in use.\"\nfi\n\n# Get template storage\nTEMPLATE_STORAGE=$(select_storage template) || exit\nmsg_ok \"Using ${BL}$TEMPLATE_STORAGE${CL} ${GN}for Template Storage.\"\n\n# Get container storage\nCONTAINER_STORAGE=$(select_storage container) || exit\nmsg_ok \"Using ${BL}$CONTAINER_STORAGE${CL} ${GN}for Container Storage.\"\n\n# Update LXC template list\nmsg_info \"Updating LXC Template List\"\npveam update >/dev/null\nmsg_ok \"Updated LXC Template List\"\n\n# Get LXC template string\nTEMPLATE_SEARCH=${PCT_OSTYPE}-${PCT_OSVERSION:-}\nmapfile -t TEMPLATES < <(pveam available -section system | sed -n \"s/.*\\($TEMPLATE_SEARCH.*\\)/\\1/p\" | sort -t - -k 2 -V)\n[ ${#TEMPLATES[@]} -gt 0 ] || exit \"Unable to find a template when searching for '$TEMPLATE_SEARCH'.\"\nTEMPLATE=\"${TEMPLATES[-1]}\"\n\n# Download LXC template if needed\nif ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then\n  msg_info \"Downloading LXC Template\"\n  pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null ||\n    exit \"A problem occured while downloading the LXC template.\"\n  msg_ok \"Downloaded LXC Template\"\nfi\n\n# Combine all options\nDEFAULT_PCT_OPTIONS=(\n  -arch $(dpkg --print-architecture))\n\nPCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}})\n[[ \" ${PCT_OPTIONS[@]} \" =~ \" -rootfs \" ]] || PCT_OPTIONS+=(-rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8})\n\n# Create container\nmsg_info \"Creating LXC Container\"\npct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null ||\n  exit \"A problem occured while trying to create container.\"\nmsg_ok \"LXC Container ${BL}$CTID${CL} ${GN}was successfully created.\"\n"
  },
  {
    "path": "ct/cronicle.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n   ______                 _      __   \n  / ____/________  ____  (_)____/ /__ \n / /   / ___/ __ \\/ __ \\/ / ___/ / _ \\\n/ /___/ /  / /_/ / / / / / /__/ /  __/\n\\____/_/   \\____/_/ /_/_/\\___/_/\\___/ \n                                      \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Cronicle\"\nvar_disk=\"2\"\nvar_cpu=\"1\"\nvar_ram=\"512\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nUPD=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"SUPPORT\" --radiolist --cancel-button Exit-Script \"Spacebar = Select\" 11 58 2 \\\n  \"1\" \"Update ${APP}\" ON \\\n  \"2\" \"Install ${APP} Worker\" OFF \\\n  3>&1 1>&2 2>&3)\n\nif [ \"$UPD\" == \"1\" ]; then\nheader_info\nif [[ ! -d /opt/cronicle ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\n  if [[ \"$(node -v | cut -d 'v' -f 2)\" == \"18.\"* ]]; then\n    if ! command -v npm >/dev/null 2>&1; then\n      echo \"Installing NPM...\"\n      apt-get install -y npm >/dev/null 2>&1\n      echo \"Installed NPM...\"\n    fi\n  fi\nmsg_info \"Updating ${APP}\"\n/opt/cronicle/bin/control.sh upgrade &>/dev/null\nmsg_ok \"Updated ${APP}\"\nexit\nfi\nif [ \"$UPD\" == \"2\" ]; then\n  if [[ \"$(node -v | cut -d 'v' -f 2)\" == \"18.\"* ]]; then\n    if ! command -v npm >/dev/null 2>&1; then\n      echo \"Installing NPM...\"\n      apt-get install -y npm >/dev/null 2>&1\n      echo \"Installed NPM...\"\n    fi\n  fi\nLATEST=$(curl -sL https://api.github.com/repos/jhuckaby/Cronicle/releases/latest | grep '\"tag_name\":' | cut -d'\"' -f4)\nIP=$(hostname -I | awk '{print $1}')\nmsg_info \"Installing Dependencies\"\n\napt-get install -y git &>/dev/null\napt-get install -y make &>/dev/null\napt-get install -y g++ &>/dev/null\napt-get install -y gcc &>/dev/null\napt-get install -y ca-certificates &>/dev/null\napt-get install -y gnupg &>/dev/null\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Setting up Node.js Repository\"\nmkdir -p /etc/apt/keyrings\ncurl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg\necho \"deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main\" >/etc/apt/sources.list.d/nodesource.list\nmsg_ok \"Set up Node.js Repository\"\n\nmsg_info \"Installing Node.js\"\napt-get update &>/dev/null\napt-get install -y nodejs &>/dev/null\nmsg_ok \"Installed Node.js\"\n\nmsg_info \"Installing Cronicle Worker\"\nmkdir -p /opt/cronicle\ncd /opt/cronicle\ntar zxvf <(curl -fsSL https://github.com/jhuckaby/Cronicle/archive/${LATEST}.tar.gz) --strip-components 1 &>/dev/null\nnpm install &>/dev/null\nnode bin/build.js dist &>/dev/null\nsed -i \"s/localhost:3012/${IP}:3012/g\" /opt/cronicle/conf/config.json\n/opt/cronicle/bin/control.sh start &>/dev/null\ncp /opt/cronicle/bin/cronicled.init /etc/init.d/cronicled &>/dev/null\nchmod 775 /etc/init.d/cronicled\nupdate-rc.d cronicled defaults &>/dev/null\nmsg_ok \"Installed Cronicle Worker\"\necho -e \"\\n Add Masters secret key to /opt/cronicle/conf/config.json \\n\"\nexit\nfi\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} Primary should be reachable by going to the following URL.\n         ${BL}http://${IP}:3012${CL} \\n\"\n"
  },
  {
    "path": "ct/daemonsync.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ____                                      _____                 \n   / __ \\____ ____  ____ ___  ____  ____     / ___/__  ______  _____\n  / / / / __  / _ \\/ __  __ \\/ __ \\/ __ \\    \\__ \\/ / / / __ \\/ ___/\n / /_/ / /_/ /  __/ / / / / / /_/ / / / /   ___/ / /_/ / / / / /__  \n/_____/\\__,_/\\___/_/ /_/ /_/\\____/_/ /_/   /____/\\__, /_/ /_/\\___/  \n                                                /____/              \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Daemon Sync\"\nvar_disk=\"8\"\nvar_cpu=\"1\"\nvar_ram=\"512\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /var ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating $APP LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated $APP LXC\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:8084${CL} \\n\"\n"
  },
  {
    "path": "ct/dashy.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ____             __         \n   / __ \\____ ______/ /_  __  __\n  / / / / __  / ___/ __ \\/ / / /\n / /_/ / /_/ (__  ) / / / /_/ / \n/_____/\\__,_/____/_/ /_/\\__, /  \n                       /____/   \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Dashy\"\nvar_disk=\"6\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/dashy/public/ ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\n\nRELEASE=$(curl -sL https://api.github.com/repos/Lissy93/dashy/releases/latest | grep '\"tag_name\":' | cut -d'\"' -f4)\nif [[ \"${RELEASE}\" != \"$(cat /opt/${APP}_version.txt)\" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then\n  msg_info \"Stopping ${APP}\"\n  systemctl stop dashy\n  msg_ok \"Stopped ${APP}\"\n\n  msg_info \"Backing up conf.yml\"\n  cd ~\n  if [[ -f /opt/dashy/public/conf.yml ]]; then\n    cp -R /opt/dashy/public/conf.yml conf.yml\n  else\n    cp -R /opt/dashy/user-data/conf.yml conf.yml\n  fi\n  msg_ok \"Backed up conf.yml\"\n\n  msg_info \"Updating ${APP} to ${RELEASE}\"\n  rm -rf /opt/dashy\n  mkdir -p /opt/dashy\n  wget -qO- https://github.com/Lissy93/dashy/archive/refs/tags/${RELEASE}.tar.gz | tar -xz -C /opt/dashy --strip-components=1\n  cd /opt/dashy\n  npm install\n  npm run build\n  echo \"${RELEASE}\" >/opt/${APP}_version.txt\n  msg_ok \"Updated ${APP} to ${RELEASE}\"\n\n  msg_info \"Restoring conf.yml\"\n  cd ~\n  cp -R conf.yml /opt/dashy/user-data\n  msg_ok \"Restored conf.yml\"\n\n  msg_info \"Cleaning\"\n  rm -rf conf.yml /opt/dashy/public/conf.yml\n  msg_ok \"Cleaned\"\n\n  msg_info \"Starting Dashy\"\n  systemctl start dashy\n  msg_ok \"Started Dashy\"\n  msg_ok \"Updated Successfully\"\nelse\n  msg_ok \"No update required. ${APP} is already at ${RELEASE}\"\nfi\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:4000${CL} \\n\"\n"
  },
  {
    "path": "ct/debian.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ____       __    _           \n   / __ \\___  / /_  (_)___  ____ \n  / / / / _ \\/ __ \\/ / __ `/ __ \\\n / /_/ /  __/ /_/ / / /_/ / / / /\n/_____/\\___/_.___/_/\\__,_/_/ /_/ \n                                 \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Debian\"\nvar_disk=\"2\"\nvar_cpu=\"1\"\nvar_ram=\"512\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /var ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating $APP LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated $APP LXC\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\n"
  },
  {
    "path": "ct/deconz.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n       __     __________  _   _______\n  ____/ /__  / ____/ __ \\/ | / /__  /\n / __  / _ \\/ /   / / / /  |/ /  / / \n/ /_/ /  __/ /___/ /_/ / /|  /  / /__\n\\__,_/\\___/\\____/\\____/_/ |_/  /____/\n \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"deCONZ\"\nvar_disk=\"4\"\nvar_cpu=\"2\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"0\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -f /etc/apt/sources.list.d/deconz.list ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating $APP LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated $APP LXC\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n             ${BL}http://${IP}${CL}\\n\"\n"
  },
  {
    "path": "ct/deluge.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ____       __               \n   / __ \\___  / /_  ______ ____ \n  / / / / _ \\/ / / / / __ `/ _ \\\n / /_/ /  __/ / /_/ / /_/ /  __/\n/_____/\\___/_/\\__,_/\\__, /\\___/ \n                   /____/       \n \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Deluge\"\nvar_disk=\"4\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -f /etc/systemd/system/deluged.service ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating $APP LXC\"\napt-get update &>/dev/null\npip3 install deluge[all] --upgrade\nmsg_ok \"Updated $APP LXC\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:8112${CL} \\n\"\n"
  },
  {
    "path": "ct/docker.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ____             __            \n   / __ \\____  _____/ /_  __  _____\n  / / / / __ \\/ ___/ //_/ _ \\/ ___/\n / /_/ / /_/ / /__/ ,< /  __/ /    \n/_____/\\____/\\___/_/|_|\\___/_/     \n \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Docker\"\nvar_disk=\"4\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /var ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating ${APP} LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated ${APP} LXC\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\n"
  },
  {
    "path": "ct/dockge.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ____             __\n   / __ \\____  _____/ /______ ____\n  / / / / __ \\/ ___/ //_/ __ `/ _ \\\n / /_/ / /_/ / /__/ ,< / /_/ /  __/\n/_____/\\____/\\___/_/|_|\\__, /\\___/\n                      /____/\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Dockge\"\nvar_disk=\"18\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/dockge ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating ${APP}\"\ncd /opt/dockge\ndocker compose pull\ndocker compose up -d\nmsg_ok \"Updated ${APP}\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:5001${CL} \\n\"\n"
  },
  {
    "path": "ct/emby.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ______          __         \n   / ____/___ ___  / /_  __  __\n  / __/ / __  __ \\/ __ \\/ / / /\n / /___/ / / / / / /_/ / /_/ / \n/_____/_/ /_/ /_/_.___/\\__, /  \n                      /____/   \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Emby\"\nvar_disk=\"8\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"ubuntu\"\nvar_version=\"22.04\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/emby-server ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nLATEST=$(curl -sL https://api.github.com/repos/MediaBrowser/Emby.Releases/releases/latest | grep '\"tag_name\":' | cut -d'\"' -f4)\nmsg_info \"Stopping ${APP}\"\nsystemctl stop emby-server\nmsg_ok \"Stopped ${APP}\"\n\nmsg_info \"Updating ${APP}\"\nwget https://github.com/MediaBrowser/Emby.Releases/releases/download/${LATEST}/emby-server-deb_${LATEST}_amd64.deb &>/dev/null\ndpkg -i emby-server-deb_${LATEST}_amd64.deb &>/dev/null\nrm emby-server-deb_${LATEST}_amd64.deb\nmsg_ok \"Updated ${APP}\"\n\nmsg_info \"Starting ${APP}\"\nsystemctl start emby-server\nmsg_ok \"Started ${APP}\"\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n             ${BL}http://${IP}:8096${CL}\\n\"\n"
  },
  {
    "path": "ct/emqx.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ________  _______   _  __\n   / ____/  |/  / __ \\ | |/ /\n  / __/ / /|_/ / / / / |   / \n / /___/ /  / / /_/ / /   |  \n/_____/_/  /_/\\___\\_\\/_/|_|  \n                             \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"EMQX\"\nvar_disk=\"4\"\nvar_cpu=\"2\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /var ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating $APP LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated $APP LXC\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} Setup should be reachable by going to the following URL.\n         ${BL}http://${IP}:18083${CL} \\n\"\n"
  },
  {
    "path": "ct/ersatztv.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck\n# Co-Author: MickLesk (Canbiz)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n# Source: https://github.com/ErsatzTV/ErsatzTV/\n\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ______                __      _______    __\n   / ____/_____________ _/ /_____/_  __/ |  / /\n  / __/ / ___/ ___/ __ `/ __/_  / / /  | | / / \n / /___/ /  (__  ) /_/ / /_  / /_/ /   | |/ /  \n/_____/_/  /____/\\__,_/\\__/ /___/_/    |___/   \n                                                         \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"ErsatzTV\"\nvar_disk=\"5\"\nvar_cpu=\"1\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/ErsatzTV ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\n\nmsg_info \"Stopping ErsatzTV\"\nsystemctl stop ersatzTV\nmsg_ok \"Stopped ErsatzTV\"\n\nmsg_info \"Updating ErsatzTV\"\nRELEASE=$(curl -s https://api.github.com/repos/ErsatzTV/ErsatzTV/releases | grep -oP '\"tag_name\": \"\\K[^\"]+' | head -n 1)\ncp -R /opt/ErsatzTV/ ErsatzTV-backup\nrm ErsatzTV-backup/ErsatzTV\nrm -rf /opt/ErsatzTV\nwget -qO- \"https://github.com/ErsatzTV/ErsatzTV/releases/download/${RELEASE}/ErsatzTV-${RELEASE}-linux-x64.tar.gz\" | tar -xz -C /opt\nmv \"/opt/ErsatzTV-${RELEASE}-linux-x64\" /opt/ErsatzTV\ncp -R ErsatzTV-backup/* /opt/ErsatzTV/\nrm -rf ErsatzTV-backup\nmsg_ok \"Updated ErsatzTV\"\n\nmsg_info \"Starting ErsatzTV\"\nsystemctl start ersatzTV\nmsg_ok \"Started ErsatzTV\"\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} Setup should be reachable by going to the following URL.\n         ${BL}http://${IP}:8409${CL} \\n\"\n"
  },
  {
    "path": "ct/esphome.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ___________ ____  __  __                   \n   / ____/ ___// __ \\/ / / /___  ____ ___  ___ \n  / __/  \\__ \\/ /_/ / /_/ / __ \\/ __ `__ \\/ _ \\\n / /___ ___/ / ____/ __  / /_/ / / / / / /  __/\n/_____//____/_/   /_/ /_/\\____/_/ /_/ /_/\\___/ \n                                               \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"ESPHome\"\nvar_disk=\"4\"\nvar_cpu=\"2\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -f /etc/systemd/system/esphomeDashboard.service ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Stopping ESPHome\"\nsystemctl stop esphomeDashboard\nmsg_ok \"Stopped ESPHome\"\n\nmsg_info \"Updating ESPHome\"\nif [[ -d /srv/esphome ]]; then\n  source /srv/esphome/bin/activate &>/dev/null\nfi\npip3 install -U esphome &>/dev/null\nmsg_ok \"Updated ESPHome\"\n\nmsg_info \"Starting ESPHome\"\nsystemctl start esphomeDashboard\nmsg_ok \"Started ESPHome\"\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:6052${CL} \\n\"\n"
  },
  {
    "path": "ct/evcc.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: MickLesk (Canbiz)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"     \n  ___ _   ____________\n / _ \\ | / / ___/ ___/\n/  __/ |/ / /__/ /__  \n\\___/|___/\\___/\\___/  \n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"evcc\"\nvar_disk=\"4\"\nvar_cpu=\"1\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -f /etc/apt/sources.list.d/evcc-stable.list ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating evcc LXC\"\napt update &>/dev/null\napt --only-upgrade install -y evcc &>/dev/null\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} Setup should be reachable by going to the following URL.\n         ${BL}http://${IP}:7070${CL} \\n\"\n"
  },
  {
    "path": "ct/fenrus.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# Co-Author: Scorpoon\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ______\n   / ____/__  ____  _______  _______\n  / /_  / _ \\/ __ \\/ ___/ / / / ___/\n / __/ /  __/ / / / /  / /_/ (__  )\n/_/    \\___/_/ /_/_/   \\__,_/____/\n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Fenrus\"\nvar_disk=\"4\"\nvar_cpu=\"1\"\nvar_ram=\"512\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/${APP} ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_error \"There is currently no update path available.\"\nexit\nmsg_info \"Updating ${APP}\"\nsystemctl stop ${APP}\ngit clone https://github.com/revenz/Fenrus.git\ncd Fenrus || exit\ngitVersionNumber=$(git rev-parse HEAD)\n\nif [[ \"${gitVersionNumber}\" != \"$(cat /opt/${APP}_version.txt)\" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then\n  mkdir /opt/fenrus-data-backup\n  cp -r \"/opt/${APP}/data/\" /opt/fenrus-data-backup/data\n  if [[ ! -d /opt/fenrus-data-backup/data ]]; then msg_error \"Backup of data folder failed! exiting...\"; rm -r /opt/fenrus-data-backup/; exit; fi \n  export DOTNET_CLI_TELEMETRY_OPTOUT=1\n  dotnet publish -c Release -o \"/opt/${APP}/\" Fenrus.csproj\n  cp -r /opt/fenrus-data-backup/data/ \"/opt/${APP}/\"\n  echo \"${gitVersionNumber}\" >\"/opt/${APP}_version.txt\"\n  rm -r /opt/fenrus-data-backup/\n  msg_ok \"Updated $APP\"\nelse\n  msg_ok \"No update required. ${APP} is already up to date\"\nfi\ncd ..\nrm -r Fenrus/\n\nsystemctl start ${APP}\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:5000${CL} \\n\"\n"
  },
  {
    "path": "ct/fhem.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ________                 \n   / ____/ /_  ___  ____ ___ \n  / /_  / __ \\/ _ \\/ __ `__ \\\n / __/ / / / /  __/ / / / / /\n/_/   /_/ /_/\\___/_/ /_/ /_/ \n                             \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Fhem\"\nvar_disk=\"8\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -f /etc/systemd/system/fhem.service ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating ${APP} LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:8083${CL} \\n\"\n"
  },
  {
    "path": "ct/flaresolverr.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# Co-Author: remz1337\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ________               _____       __                    \n   / ____/ /___ _________ / ___/____  / /   _____  __________\n  / /_  / / __ `/ ___/ _ \\\\__ \\/ __ \\/ / | / / _ \\/ ___/ ___/\n / __/ / / /_/ / /  /  __/__/ / /_/ / /| |/ /  __/ /  / /    \n/_/   /_/\\__,_/_/   \\___/____/\\____/_/ |___/\\___/_/  /_/     \n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"FlareSolverr\"\nvar_disk=\"4\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\n  header_info\n  if [[ ! -f /etc/systemd/system/flaresolverr.service ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\n  whiptail --backtitle \"Proxmox VE Helper Scripts\" --msgbox --title \"SET RESOURCES\" \"Please set the resources in your ${APP} LXC to ${var_cpu}vCPU and ${var_ram}RAM for the build process before continuing\" 10 75\n  RELEASE=$(wget -q https://github.com/FlareSolverr/FlareSolverr/releases/latest -O - | grep \"title>Release\" | cut -d \" \" -f 4)\n  if [[ \"${RELEASE}\" != \"$(cat /opt/${APP}_version.txt)\" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then\n    msg_info \"Updating $APP LXC\"\n    systemctl stop flaresolverr\n    wget -q https://github.com/FlareSolverr/FlareSolverr/releases/download/$RELEASE/flaresolverr_linux_x64.tar.gz\n    tar -xzf flaresolverr_linux_x64.tar.gz -C /opt\n    rm flaresolverr_linux_x64.tar.gz\n    systemctl start flaresolverr\n    echo \"${RELEASE}\" >/opt/${APP}_version.txt\n    msg_ok \"Updated $APP LXC\"\n  else\n    msg_ok \"No update required. ${APP} is already at ${RELEASE}\"\n  fi\n  exit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_info \"Setting Container to Normal Resources\"\npct set $CTID -memory 512\npct set $CTID -cores 1\nmsg_ok \"Set Container to Normal Resources\"\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:8191${CL} \\n\"\n"
  },
  {
    "path": "ct/flowiseai.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ________              _           ___    ____\n   / ____/ /___ _      __(_)_______  /   |  /  _/\n  / /_  / / __ \\ | /| / / / ___/ _ \\/ /| |  / /\n / __/ / / /_/ / |/ |/ / (__  )  __/ ___ |_/ /\n/_/   /_/\\____/|__/|__/_/____/\\___/_/  |_/___/\n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"FlowiseAI\"\nvar_disk=\"10\"\nvar_cpu=\"4\"\nvar_ram=\"4096\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -f /etc/systemd/system/flowise.service ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nwhiptail --backtitle \"Proxmox VE Helper Scripts\" --msgbox --title \"SET RESOURCES\" \"Please set the resources in your ${APP} LXC to ${var_cpu}vCPU and ${var_ram}RAM for the build process before continuing\" 10 75\nmsg_info \"Updating ${APP}\"\nsystemctl stop flowise\nnpm install -g flowise --upgrade\nsystemctl start flowise\nmsg_ok \"Updated ${APP}\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_info \"Setting Container to Normal Resources\"\npct set $CTID -memory 2048\npct set $CTID -cores 2\nmsg_ok \"Set Container to Normal Resources\"\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:3000${CL} \\n\"\n"
  },
  {
    "path": "ct/forgejo.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\n  clear\n  cat <<\"EOF\"\n    ______                        _     \n   / ____/___  _________  ___    (_)___ \n  / /_  / __ \\/ ___/ __ `/ _ \\  / / __ \\\n / __/ / /_/ / /  / /_/ /  __/ / / /_/ /\n/_/    \\____/_/   \\__, /\\___/_/ /\\____/ \n                 /____/    /___/        \n \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Forgejo\"\nvar_disk=\"10\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/forgejo ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Stopping ${APP}\"\nsystemctl stop forgejo\nmsg_ok \"Stopped ${APP}\"\n\nmsg_info \"Updating ${APP}\"\nRELEASE=$(curl -s https://codeberg.org/api/v1/repos/forgejo/forgejo/releases/latest | grep -oP '\"tag_name\":\\s*\"\\K[^\"]+' | sed 's/^v//')\nwget -qO forgejo-$RELEASE-linux-amd64 \"https://codeberg.org/forgejo/forgejo/releases/download/v${RELEASE}/forgejo-${RELEASE}-linux-amd64\"\nrm -rf /opt/forgejo/*\ncp -r forgejo-$RELEASE-linux-amd64 /opt/forgejo/forgejo-$RELEASE-linux-amd64\nchmod +x /opt/forgejo/forgejo-$RELEASE-linux-amd64\nln -sf /opt/forgejo/forgejo-$RELEASE-linux-amd64 /usr/local/bin/forgejo\nmsg_ok \"Updated ${APP}\"\n\nmsg_info \"Cleaning\"\nrm -rf forgejo-$RELEASE-linux-amd64\nmsg_ok \"Cleaned\"\n\nmsg_info \"Starting ${APP}\"\nsystemctl start forgejo\nmsg_ok \"Started ${APP}\"\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:3000${CL} \\n\"\n"
  },
  {
    "path": "ct/frigate.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Authors: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\n  clear\n  cat <<\"EOF\"\n    ______     _             __\n   / ____/____(_)___ _____ _/ /____\n  / /_  / ___/ / __ `/ __ `/ __/ _ \\\n / __/ / /  / / /_/ / /_/ / /_/  __/\n/_/   /_/  /_/\\__, /\\__,_/\\__/\\___/\n             /____/\n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Frigate\"\nvar_disk=\"20\"\nvar_cpu=\"4\"\nvar_ram=\"4096\"\nvar_os=\"debian\"\nvar_version=\"11\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"0\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\n  if [[ ! -f /etc/systemd/system/frigate.service ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\n  msg_error \"To update Frigate, create a new container and transfer your configuration.\"\n  exit  \n}\n\nstart\nbuild_container\ndescription\n\nmsg_info \"Setting Container to Normal Resources\"\npct set $CTID -memory 1024\nmsg_ok \"Set Container to Normal Resources\"\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:5000${CL} \\n\"\necho -e \"go2rtc should be reachable by going to the following URL.\n         ${BL}http://${IP}:1984${CL} \\n\"\n"
  },
  {
    "path": "ct/gitea.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# Co-author: Rogue-King\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n   ______ _  __\n  / ____/(_)/ /____  ____ _\n / / __// // __/ _ \\/ __  /\n/ /_/ // // /_/  __/ /_/ /\n\\____//_/ \\__/\\___/\\__,_/\n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Gitea\"\nvar_disk=\"8\"\nvar_cpu=\"1\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[  ! -f /usr/local/bin/gitea ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nRELEASE=$(wget -q https://github.com/go-gitea/gitea/releases/latest -O - | grep \"title>Release\" | cut -d \" \" -f 4 | sed 's/^v//')\nmsg_info \"Updating $APP to ${RELEASE}\"\nwget -q https://github.com/go-gitea/gitea/releases/download/v$RELEASE/gitea-$RELEASE-linux-amd64\nsystemctl stop gitea\nrm -rf /usr/local/bin/gitea \nmv gitea* /usr/local/bin/gitea\nchmod +x /usr/local/bin/gitea\nsystemctl start gitea\nmsg_ok \"Updated $APP Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:3000${CL} \\n\"\n"
  },
  {
    "path": "ct/go2rtc.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n               ___        __      \n   ____ _____ |__ \\ _____/ /______\n  / __ `/ __ \\__/ // ___/ __/ ___/\n / /_/ / /_/ / __// /  / /_/ /__  \n \\__, /\\____/____/_/   \\__/\\___/  \n/____/                            \n \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"go2rtc\"\nvar_disk=\"4\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/go2rtc ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating $APP\"\nsystemctl stop go2rtc\ncd /opt/go2rtc\nrm go2rtc_linux_amd64\nwget -q https://github.com/AlexxIT/go2rtc/releases/latest/download/go2rtc_linux_amd64\nchmod +x go2rtc_linux_amd64\nsystemctl start go2rtc\nmsg_ok \"Updated $APP\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:1984${CL} \\n\"\n"
  },
  {
    "path": "ct/gokapi.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n   ______      __               _\n  / ____/___  / /______ _____  (_)\n / / __/ __ \\/ //_/ __ `/ __ \\/ /\n/ /_/ / /_/ / ,< / /_/ / /_/ / /\n\\____/\\____/_/|_|\\__,_/ .___/_/\n                     /_/\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Gokapi\"\nvar_disk=\"4\"\nvar_cpu=\"1\"\nvar_ram=\"512\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/gokapi ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_error \"There is currently no update path available.\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} Setup should be reachable by going to the following URL.\n         ${BL}http://${IP}:53842/setup${CL} \\n\"\n"
  },
  {
    "path": "ct/gotify.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n   ______      __  _ ____\n  / ____/___  / /_(_) __/_  __\n / / __/ __ \\/ __/ / /_/ / / /\n/ /_/ / /_/ / /_/ / __/ /_/ /\n\\____/\\____/\\__/_/_/  \\__, /\n                     /____/\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Gotify\"\nvar_disk=\"2\"\nvar_cpu=\"1\"\nvar_ram=\"512\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/gotify ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\n\nRELEASE=$(curl -s https://api.github.com/repos/gotify/server/releases/latest | grep \"tag_name\" | awk '{print substr($2, 3, length($2)-4) }')\nif [[ ! -f /opt/${APP}_version.txt ]] || [[ \"${RELEASE}\" != \"$(cat /opt/${APP}_version.txt)\" ]]; then\n  msg_info \"Stopping ${APP}\"\n  systemctl stop gotify\n  msg_ok \"Stopped ${APP}\"\n\n  msg_info \"Updating ${APP} to ${RELEASE}\"\n  cd /opt/gotify\n  wget -q https://github.com/gotify/server/releases/download/v${RELEASE}/gotify-linux-amd64.zip\n  unzip -oq gotify-linux-amd64.zip\n  rm -rf gotify-linux-amd64.zip\n  chmod +x gotify-linux-amd64\n  echo \"${RELEASE}\" >/opt/${APP}_version.txt\n  msg_ok \"Updated ${APP} to ${RELEASE}\"\n\n  msg_info \"Starting ${APP}\"\n  systemctl start gotify\n  msg_ok \"Started ${APP}\"\n  msg_ok \"Updated Successfully\"\nelse\n  msg_ok \"No update required. ${APP} is already at ${RELEASE}\"\nfi\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP} ${CL} \\n\"\n"
  },
  {
    "path": "ct/grafana.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n   ______           ____                 \n  / ____/________ _/ __/___ _____  ____ _\n / / __/ ___/ __  / /_/ __  / __ \\/ __  /\n/ /_/ / /  / /_/ / __/ /_/ / / / / /_/ / \n\\____/_/   \\__,_/_/  \\__,_/_/ /_/\\__,_/  \n \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Grafana\"\nvar_disk=\"2\"\nvar_cpu=\"1\"\nvar_ram=\"512\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -f /etc/apt/sources.list.d/grafana.list ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating ${APP}\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:3000${CL} \\n\"\n"
  },
  {
    "path": "ct/grocy.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n   ____ __________  _______  __\n  / __  / ___/ __ \\/ ___/ / / /\n / /_/ / /  / /_/ / /__/ /_/ / \n \\__, /_/   \\____/\\___/\\__, /  \n/____/                /____/   \n \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"grocy\"\nvar_disk=\"2\"\nvar_cpu=\"1\"\nvar_ram=\"512\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -f /etc/apache2/sites-available/grocy.conf ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nphp_version=$(php -v | head -n 1 | awk '{print $2}')\nif [[ ! $php_version == \"8.3\"* ]]; then\n  msg_info \"Updating PHP\"\n  curl -sSLo /usr/share/keyrings/deb.sury.org-php.gpg https://packages.sury.org/php/apt.gpg\n  echo \"deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ bookworm main\" >/etc/apt/sources.list.d/php.list\n  apt-get update\n  apt-get install -y php8.3 php8.3-cli php8.3-{bz2,curl,mbstring,intl,sqlite3,fpm,gd,zip,xml}\n  systemctl reload apache2\n  apt autoremove\n  msg_ok \"Updated PHP\"\nfi\nmsg_info \"Updating ${APP}\"\nbash /var/www/html/update.sh\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}${CL} \\n\"\n"
  },
  {
    "path": "ct/headscale.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    __  __               __                __\n   / / / /__  ____ _____/ /_____________ _/ /__\n  / /_/ / _ \\/ __ `/ __  / ___/ ___/ __ `/ / _ \\\n / __  /  __/ /_/ / /_/ (__  ) /__/ /_/ / /  __/\n/_/ /_/\\___/\\__,_/\\__,_/____/\\___/\\__,_/_/\\___/\n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Headscale\"\nvar_disk=\"2\"\nvar_cpu=\"1\"\nvar_ram=\"512\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /etc/headscale ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\n\nRELEASE=$(curl -s https://api.github.com/repos/juanfont/headscale/releases/latest | grep \"tag_name\" | awk '{print substr($2, 3, length($2)-4) }')\nif [[ \"${RELEASE}\" != \"$(cat /opt/${APP}_version.txt)\" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then\n  msg_info \"Stopping ${APP}\"\n  systemctl stop headscale\n  msg_ok \"Stopped ${APP}\"\n\n  msg_info \"Updating $APP to v${RELEASE}\"\n  wget -q https://github.com/juanfont/headscale/releases/download/v${RELEASE}/headscale_${RELEASE}_linux_amd64.deb\n  dpkg -i headscale_${RELEASE}_linux_amd64.deb\n  rm headscale_${RELEASE}_linux_amd64.deb\n  echo \"${RELEASE}\" >/opt/${APP}_version.txt\n  msg_ok \"Updated $APP to ${RELEASE}\"\n  \n  msg_info \"Starting ${APP}\"\n  systemctl start headscale\n  msg_ok \"Started ${APP}\"\n  msg_ok \"Updated Successfully\"\nelse\n  msg_ok \"No update required. ${APP} is already at ${RELEASE}\"\nfi\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\n"
  },
  {
    "path": "ct/heimdall-dashboard.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n            _               _       _ _      ___          _     _                         _ \n  /\\  /\\___(_)_ __ ___   __| | __ _| | |    /   \\__ _ ___| |__ | |__   ___   __ _ _ __ __| |\n / /_/ / _ \\ | '_ ` _ \\ / _` |/ _` | | |   / /\\ / _` / __| '_ \\| '_ \\ / _ \\ / _` | '__/ _` |\n/ __  /  __/ | | | | | | (_| | (_| | | |  / /_// (_| \\__ \\ | | | |_) | (_) | (_| | | | (_| |\n\\/ /_/ \\___|_|_| |_| |_|\\__,_|\\__,_|_|_| /___,' \\__,_|___/_| |_|_.__/ \\___/ \\__,_|_|  \\__,_|\n                                                                                            \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Heimdall-Dashboard\"\nvar_disk=\"2\"\nvar_cpu=\"1\"\nvar_ram=\"512\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/Heimdall ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nRELEASE=$(curl -sX GET \"https://api.github.com/repos/linuxserver/Heimdall/releases/latest\" | awk '/tag_name/{print $4;exit}' FS='[\"\"]')\nif [[ \"${RELEASE}\" != \"$(cat /opt/${APP}_version.txt)\" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then\n  msg_info \"Stopping ${APP}\"\n  systemctl stop heimdall\n  sleep 1\n  msg_ok \"Stopped ${APP}\"\n\n  msg_info \"Backing up Data\"\n  cp -R /opt/Heimdall/database database-backup\n  cp -R /opt/Heimdall/public public-backup\n  sleep 1\n  msg_ok \"Backed up Data\"\n\n  msg_info \"Updating Heimdall Dashboard to ${RELEASE}\"\n  wget -q https://github.com/linuxserver/Heimdall/archive/${RELEASE}.tar.gz\n  tar xzf ${RELEASE}.tar.gz\n  VER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest | grep \"tag_name\" | awk '{print substr($2, 3, length($2)-4) }')\n  cp -R Heimdall-${VER}/* /opt/Heimdall\n  cd /opt/Heimdall\n  apt-get install -y composer &>/dev/null\n  COMPOSER_ALLOW_SUPERUSER=1 composer dump-autoload &>/dev/null\n  echo \"${RELEASE}\" >/opt/${APP}_version.txt\n  msg_ok \"Updated Heimdall Dashboard to ${RELEASE}\"\n\n  msg_info \"Restoring Data\"\n  cd ~\n  cp -R database-backup/* /opt/Heimdall/database\n  cp -R public-backup/* /opt/Heimdall/public\n  sleep 1\n  msg_ok \"Restored Data\"\n\n  msg_info \"Cleanup\"\n  rm -rf {${RELEASE}.tar.gz,Heimdall-${VER},public-backup,database-backup,Heimdall}\n  sleep 1\n  msg_ok \"Cleaned\"\n\n  msg_info \"Starting ${APP}\"\n  systemctl start heimdall.service\n  sleep 2\n  msg_ok \"Started ${APP}\"\n  msg_ok \"Updated Successfully\"\nelse\n  msg_ok \"No update required.  ${APP} is already at ${RELEASE}.\"\nfi\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:7990${CL} \\n\"\n"
  },
  {
    "path": "ct/hivemq.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    __  ___            __  _______      ____________\n   / / / (_)   _____  /  |/  / __ \\    / ____/ ____/\n  / /_/ / / | / / _ \\/ /|_/ / / / /   / /   / __/\n / __  / /| |/ /  __/ /  / / /_/ /   / /___/ /___\n/_/ /_/_/ |___/\\___/_/  /_/\\___\\_\\   \\____/_____/\n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"HiveMQ\"\nvar_disk=\"4\"\nvar_cpu=\"1\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /var ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_error \"There is currently no update path available.\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\n"
  },
  {
    "path": "ct/homarr.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    __  __\n   / / / /___  ____ ___  ____ ___________\n  / /_/ / __ \\/ __ `__ \\/ __ `/ ___/ ___/\n / __  / /_/ / / / / / / /_/ / /  / /\n/_/ /_/\\____/_/ /_/ /_/\\__,_/_/  /_/\n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Homarr\"\nvar_disk=\"8\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/homarr ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating $APP (Patience)\"\nsystemctl stop homarr\ncd /opt/homarr\nif ! git pull; then\n  echo \"Already up to date.\"\n  systemctl start homarr\n  echo \"No update required.\"\n  exit\nfi\nyarn install\nyarn build\nsystemctl start homarr\nmsg_ok \"Updated $APP\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:3000${CL} \\n\"\n"
  },
  {
    "path": "ct/homeassistant-core.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\n  clear\n  cat <<\"EOF\"\n                                _           _     _              _       ___               \n  /\\  /\\___  _ __ ___   ___    /_\\  ___ ___(_)___| |_ __ _ _ __ | |_    / __\\___  _ __ ___ \n / /_/ / _ \\| '_ ` _ \\ / _ \\  //_\\\\/ __/ __| / __| __/ _` | '_ \\| __|  / /  / _ \\| '__/ _ \\\n/ __  / (_) | | | | | |  __/ /  _  \\__ \\__ \\ \\__ \\ || (_| | | | | |_  / /__| (_) | | |  __/\n\\/ /_/ \\___/|_| |_| |_|\\___| \\_/ \\_/___/___/_|___/\\__\\__,_|_| |_|\\__| \\____/\\___/|_|  \\___|\n                                                                                           \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Home Assistant-Core\"\nvar_disk=\"8\"\nvar_cpu=\"2\"\nvar_ram=\"1024\"\nvar_os=\"ubuntu\"\nvar_version=\"24.04\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\n  if [[ ! -d /srv/homeassistant ]]; then\n    msg_error \"No ${APP} Installation Found!\"\n    exit\n  fi\n  PY=$(ls /srv/homeassistant/lib/)\n  IP=$(hostname -I | awk '{print $1}')\n  UPD=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"UPDATE\" --radiolist --cancel-button Exit-Script \"Spacebar = Select\" 11 58 4 \\\n    \"1\" \"Update Core\" ON \\\n    \"2\" \"Install HACS\" OFF \\\n    \"3\" \"Install FileBrowser\" OFF \\\n    3>&1 1>&2 2>&3)\n  header_info\n  if [ \"$UPD\" == \"1\" ]; then\n    if (whiptail --backtitle \"Proxmox VE Helper Scripts\" --defaultno --title \"SELECT BRANCH\" --yesno \"Use Beta Branch?\" 10 58); then\n      clear\n      header_info\n      echo -e \"${GN}Updating to Beta Version${CL}\"\n      BR=\"--pre \"\n    else\n      clear\n      header_info\n      echo -e \"${GN}Updating to Stable Version${CL}\"\n      BR=\"\"\n    fi\n    if [[ \"$PY\" == \"python3.11\" ]]; then echo -e \"⚠️  Home Assistant will soon require Python 3.12.\"; fi\n\n    msg_info \"Stopping Home Assistant\"\n    systemctl stop homeassistant\n    msg_ok \"Stopped Home Assistant\"\n\n    msg_info \"Updating Home Assistant\"\n    source /srv/homeassistant/bin/activate\n    uv pip install ${BR}--upgrade homeassistant &>/dev/null\n    msg_ok \"Updated Home Assistant\"\n\n    msg_info \"Starting Home Assistant\"\n    systemctl start homeassistant\n    sleep 2\n    msg_ok \"Started Home Assistant\"\n    msg_ok \"Update Successful\"\n    echo -e \"\\n  Go to http://${IP}:8123 \\n\"\n    exit\n  fi\n  if [ \"$UPD\" == \"2\" ]; then\n    msg_info \"Installing Home Assistant Community Store (HACS)\"\n    apt update &>/dev/null\n    apt install unzip &>/dev/null\n    cd .homeassistant\n    bash <(curl -fsSL https://get.hacs.xyz) &>/dev/null\n    msg_ok \"Installed Home Assistant Community Store (HACS)\"\n    echo -e \"\\n Reboot Home Assistant and clear browser cache then Add HACS integration.\\n\"\n    exit\n  fi\n  if [ \"$UPD\" == \"3\" ]; then\n    set +Eeuo pipefail\n    read -r -p \"Would you like to use No Authentication? <y/N> \" prompt\n    msg_info \"Installing FileBrowser\"\n    RELEASE=$(curl -fsSL https://api.github.com/repos/filebrowser/filebrowser/releases/latest | grep -o '\"tag_name\": \".*\"' | sed 's/\"//g' | sed 's/tag_name: //g')\n    curl -fsSL https://github.com/filebrowser/filebrowser/releases/download/$RELEASE/linux-amd64-filebrowser.tar.gz | tar -xzv -C /usr/local/bin &>/dev/null\n\n    if [[ \"${prompt,,}\" =~ ^(y|yes)$ ]]; then\n      filebrowser config init -a '0.0.0.0' &>/dev/null\n      filebrowser config set -a '0.0.0.0' &>/dev/null\n      filebrowser config set --auth.method=noauth &>/dev/null\n      filebrowser users add ID 1 --perm.admin &>/dev/null  \n    else\n      filebrowser config init -a '0.0.0.0' &>/dev/null\n      filebrowser config set -a '0.0.0.0' &>/dev/null\n      filebrowser users add admin helper-scripts.com --perm.admin &>/dev/null\n    fi\n    msg_ok \"Installed FileBrowser\"\n\n    msg_info \"Creating Service\"\n    service_path=\"/etc/systemd/system/filebrowser.service\"\n    echo \"[Unit]\nDescription=Filebrowser\nAfter=network-online.target\n[Service]\nUser=root\nWorkingDirectory=/root/\nExecStart=/usr/local/bin/filebrowser -r /root/.homeassistant\n[Install]\nWantedBy=default.target\" >$service_path\n\n    systemctl enable --now -q filebrowser.service\n    msg_ok \"Created Service\"\n\n    msg_ok \"Completed Successfully!\\n\"\n    echo -e \"FileBrowser should be reachable by going to the following URL.\n         ${BL}http://$IP:8080${CL}   admin|helper-scripts.com\\n\"\n    exit\n  fi\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:8123${CL}\"\n"
  },
  {
    "path": "ct/homeassistant.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\n  clear\n  cat <<\"EOF\"\n    __  __                        ___              _      __              __ \n   / / / /___  ____ ___  ___     /   |  __________(_)____/ /_____ _____  / /_\n  / /_/ / __ \\/ __  __ \\/ _ \\   / /| | / ___/ ___/ / ___/ __/ __  / __ \\/ __/\n / __  / /_/ / / / / / /  __/  / ___ |(__  |__  ) (__  ) /_/ /_/ / / / / /_  \n/_/ /_/\\____/_/ /_/ /_/\\___/  /_/  |_/____/____/_/____/\\__/\\__,_/_/ /_/\\__/  \n \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Home Assistant\"\nvar_disk=\"16\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\n  if [[ ! -d /var/lib/docker/volumes/hass_config/_data ]]; then\n    msg_error \"No ${APP} Installation Found!\"\n    exit\n  fi\n  UPD=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"UPDATE\" --radiolist --cancel-button Exit-Script \"Spacebar = Select\" 11 58 4 \\\n    \"1\" \"Update ALL Containers\" ON \\\n    \"2\" \"Remove ALL Unused Images\" OFF \\\n    \"3\" \"Install HACS\" OFF \\\n    \"4\" \"Install FileBrowser\" OFF \\\n    3>&1 1>&2 2>&3)\n  header_info\n  if [ \"$UPD\" == \"1\" ]; then\n    msg_info \"Updating All Containers\"\n    CONTAINER_LIST=\"${1:-$(docker ps -q)}\"\n    for container in ${CONTAINER_LIST}; do\n      CONTAINER_IMAGE=\"$(docker inspect --format \"{{.Config.Image}}\" --type container ${container})\"\n      RUNNING_IMAGE=\"$(docker inspect --format \"{{.Image}}\" --type container \"${container}\")\"\n      docker pull \"${CONTAINER_IMAGE}\"\n      LATEST_IMAGE=\"$(docker inspect --format \"{{.Id}}\" --type image \"${CONTAINER_IMAGE}\")\"\n      if [[ \"${RUNNING_IMAGE}\" != \"${LATEST_IMAGE}\" ]]; then\n        echo \"Updating ${container} image ${CONTAINER_IMAGE}\"\n        DOCKER_COMMAND=\"$(runlike \"${container}\")\"\n        docker rm --force \"${container}\"\n        eval ${DOCKER_COMMAND}\n      fi\n    done\n    msg_ok \"Updated All Containers\"\n    exit\n  fi\n  if [ \"$UPD\" == \"2\" ]; then\n    msg_info \"Removing ALL Unused Images\"\n    docker image prune -af\n    msg_ok \"Removed ALL Unused Images\"\n    exit\n  fi\n  if [ \"$UPD\" == \"3\" ]; then\n    msg_info \"Installing Home Assistant Community Store (HACS)\"\n    apt update &>/dev/null\n    apt install unzip &>/dev/null\n    cd /var/lib/docker/volumes/hass_config/_data\n    bash <(curl -fsSL https://get.hacs.xyz) &>/dev/null\n    msg_ok \"Installed Home Assistant Community Store (HACS)\"\n    echo -e \"\\n Reboot Home Assistant and clear browser cache then Add HACS integration.\\n\"\n    exit\n  fi\n  if [ \"$UPD\" == \"4\" ]; then\n    IP=$(hostname -I | awk '{print $1}')\n    msg_info \"Installing FileBrowser\"\n    RELEASE=$(curl -fsSL https://api.github.com/repos/filebrowser/filebrowser/releases/latest | grep -o '\"tag_name\": \".*\"' | sed 's/\"//g' | sed 's/tag_name: //g')\n    curl -fsSL https://github.com/filebrowser/filebrowser/releases/download/v2.23.0/linux-amd64-filebrowser.tar.gz | tar -xzv -C /usr/local/bin &>/dev/null\n    filebrowser config init -a '0.0.0.0' &>/dev/null\n    filebrowser config set -a '0.0.0.0' &>/dev/null\n    filebrowser users add admin helper-scripts.com --perm.admin &>/dev/null\n    msg_ok \"Installed FileBrowser\"\n\n    msg_info \"Creating Service\"\n    service_path=\"/etc/systemd/system/filebrowser.service\"\n    echo \"[Unit]\nDescription=Filebrowser\nAfter=network-online.target\n[Service]\nUser=root\nWorkingDirectory=/root/\nExecStart=/usr/local/bin/filebrowser -r /\n[Install]\nWantedBy=default.target\" >$service_path\n\n    systemctl enable --now filebrowser.service &>/dev/null\n    msg_ok \"Created Service\"\n\n    msg_ok \"Completed Successfully!\\n\"\n    echo -e \"FileBrowser should be reachable by going to the following URL.\n         ${BL}http://$IP:8080${CL}   admin|helper-scripts.com\\n\"\n    exit\n  fi\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:8123${CL}\nPortainer should be reachable by going to the following URL.\n         ${BL}https://${IP}:9443${CL}\\n\"\n"
  },
  {
    "path": "ct/homebox.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck\n# Co-Author: MickLesk (Canbiz)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    __  __                     ____            \n   / / / /___  ____ ___  ___  / __ )____  _  __\n  / /_/ / __ \\/ __ `__ \\/ _ \\/ __  / __ \\| |/_/\n / __  / /_/ / / / / / /  __/ /_/ / /_/ />  <\n/_/ /_/\\____/_/ /_/ /_/\\___/_____/\\____/_/|_|\n                                                   \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"HomeBox\"\nvar_disk=\"4\"\nvar_cpu=\"1\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\nfunction update_script() {\nheader_info\nif [[ ! -f /opt/homebox ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nif (( $(df /boot | awk 'NR==2{gsub(\"%\",\"\",$5); print $5}') > 80 )); then\n  read -r -p \"Warning: Storage is dangerously low, continue anyway? <y/N> \" prompt\n  [[ ${prompt,,} =~ ^(y|yes)$ ]] || exit\nfi\nRELEASE=$(curl -s https://api.github.com/repos/sysadminsmedia/homebox/releases/latest | grep \"tag_name\" | awk '{print substr($2, 2, length($2)-3) }')\nif [[ ! -f /opt/${APP}_version.txt ]] || [[ \"${RELEASE}\" != \"$(cat /opt/${APP}_version.txt)\" ]]; then\n  msg_info \"Stopping ${APP}\"\n  systemctl stop homebox\n  msg_ok \"${APP} Stopped\"\n\n  msg_info \"Updating ${APP} to ${RELEASE}\"\n  cd /opt\n  rm -rf homebox_bak\n  mv homebox homebox_bak\n  wget -qO- https://github.com/sysadminsmedia/homebox/releases/download/${RELEASE}/homebox_Linux_x86_64.tar.gz | tar -xzf - -C /opt\n  chmod +x /opt/homebox\n  echo \"${RELEASE}\" >/opt/${APP}_version.txt\n  msg_ok \"Updated Homebox\"\n\n  msg_info \"Starting ${APP}\"\n  systemctl start homebox\n  msg_ok \"Started ${APP}\"\n\n  msg_ok \"Updated Successfully\"\nelse\n  msg_ok \"No update required. ${APP} is already at ${RELEASE}\"\nfi\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} Setup should be reachable by going to the following URL.\n         ${BL}http://${IP}:7745${CL} \\n\"\n"
  },
  {
    "path": "ct/homebridge.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    __  ______  __  _____________  ____  ________  ____________\n   / / / / __ \\/  |/  / ____/ __ )/ __ \\/  _/ __ \\/ ____/ ____/\n  / /_/ / / / / /|_/ / __/ / __  / /_/ // // / / / / __/ __/   \n / __  / /_/ / /  / / /___/ /_/ / _, _// // /_/ / /_/ / /___   \n/_/ /_/\\____/_/  /_/_____/_____/_/ |_/___/_____/\\____/_____/   \n \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Homebridge\"\nvar_disk=\"4\"\nvar_cpu=\"1\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -f /etc/apt/sources.list.d/homebridge.list ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating ${APP} LXC\"\napt-get update &>/dev/null\napt-get install -y homebridge &>/dev/null\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:8581${CL} \\n\"\n"
  },
  {
    "path": "ct/homepage.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    __  __                                          \n   / / / /___  ____ ___  ___  ____  ____ _____ ____ \n  / /_/ / __ \\/ __ `__ \\/ _ \\/ __ \\/ __ `/ __ `/ _ \\\n / __  / /_/ / / / / / /  __/ /_/ / /_/ / /_/ /  __/\n/_/ /_/\\____/_/ /_/ /_/\\___/ .___/\\__,_/\\__, /\\___/ \n                          /_/          /____/       \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Homepage\"\nvar_disk=\"3\"\nvar_cpu=\"2\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/homepage ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nif [[ \"$(node -v | cut -d 'v' -f 2)\" == \"18.\"* ]]; then\n  if ! command -v npm >/dev/null 2>&1; then\n    echo \"Installing NPM...\"\n    apt-get install -y npm >/dev/null 2>&1\n    npm install -g pnpm >/dev/null 2>&1\n    echo \"Installed NPM...\"\n  fi\nfi\nRELEASE=$(curl -s https://api.github.com/repos/gethomepage/homepage/releases/latest | grep \"tag_name\" | awk '{print substr($2, 3, length($2)-4) }')\nif [[ \"${RELEASE}\" != \"$(cat /opt/${APP}_version.txt)\" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then\n  msg_info \"Updating Homepage to v${RELEASE} (Patience)\"\n  systemctl stop homepage\n  wget -q https://github.com/gethomepage/homepage/archive/refs/tags/v${RELEASE}.tar.gz\n  tar -xzf v${RELEASE}.tar.gz\n  rm -rf v${RELEASE}.tar.gz\n  cp -r homepage-${RELEASE}/* /opt/homepage/\n  rm -rf homepage-${RELEASE}\n  cd /opt/homepage\n  npx update-browserslist-db@latest\n  pnpm install\n  pnpm build\n  systemctl start homepage\n  echo \"${RELEASE}\" >/opt/${APP}_version.txt\n  msg_ok \"Updated Homepage to v${RELEASE}\"\nelse\n  msg_ok \"No update required. ${APP} is already at ${RELEASE}\"\nfi\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} Setup should be reachable by going to the following URL.\n         ${BL}http://${IP}:3000${CL} \\n\"\n"
  },
  {
    "path": "ct/homer.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    __  __                         \n   / / / /___  ____ ___  ___  _____\n  / /_/ / __ \\/ __ `__ \\/ _ \\/ ___/\n / __  / /_/ / / / / / /  __/ /    \n/_/ /_/\\____/_/ /_/ /_/\\___/_/     \n                                   \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Homer\"\nvar_disk=\"2\"\nvar_cpu=\"1\"\nvar_ram=\"512\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/homer ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Stopping ${APP}\"\nsystemctl stop homer\nmsg_ok \"Stopped ${APP}\"\n\nmsg_info \"Backing up assets directory\"\ncd ~\nmkdir -p assets-backup\ncp -R /opt/homer/assets/. assets-backup\nmsg_ok \"Backed up assets directory\"\n\nmsg_info \"Updating ${APP}\"\nrm -rf /opt/homer/*\ncd /opt/homer\nwget -q https://github.com/bastienwirtz/homer/releases/latest/download/homer.zip\nunzip homer.zip &>/dev/null\nmsg_ok \"Updated ${APP}\"\n\nmsg_info \"Restoring assets directory\"\ncd ~\ncp -Rf assets-backup/. /opt/homer/assets/\nmsg_ok \"Restored assets directory\"\n\nmsg_info \"Cleaning\"\nrm -rf assets-backup /opt/homer/homer.zip\nmsg_ok \"Cleaned\"\n\nmsg_info \"Starting ${APP}\"\nsystemctl start homer\nmsg_ok \"Started ${APP}\"\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:8010${CL} \\n\"\n"
  },
  {
    "path": "ct/hyperhdr.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    __  __                      __  ______  ____\n   / / / /_  ______  ___  _____/ / / / __ \\/ __ \\\n  / /_/ / / / / __ \\/ _ \\/ ___/ /_/ / / / / /_/ /\n / __  / /_/ / /_/ /  __/ /  / __  / /_/ / _, _/\n/_/ /_/\\__, / .___/\\___/_/  /_/ /_/_____/_/ |_|\n      /____/_/\n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"HyperHDR\"\nvar_disk=\"4\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"0\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /var ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating $APP LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated $APP LXC\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:8090${CL} \\n\"\n"
  },
  {
    "path": "ct/hyperion.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    __  __                      _           \n   / / / /_  ______  ___  _____(_)___  ____ \n  / /_/ / / / / __ \\/ _ \\/ ___/ / __ \\/ __ \\\n / __  / /_/ / /_/ /  __/ /  / / /_/ / / / /\n/_/ /_/\\__, / .___/\\___/_/  /_/\\____/_/ /_/ \n      /____/_/                              \n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Hyperion\"\nvar_disk=\"2\"\nvar_cpu=\"1\"\nvar_ram=\"512\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -f /etc/apt/sources.list.d/hyperion.list ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating ${APP} LXC\"\napt-get update &>/dev/null\napt-get install -y hyperion &>/dev/null\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:8090${CL} \\n\"\n"
  },
  {
    "path": "ct/influxdb.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ____      ______           ____  ____ \n   /  _/___  / __/ /_  ___  __/ __ \\/ __ )\n   / // __ \\/ /_/ / / / / |/_/ / / / __  |\n _/ // / / / __/ / /_/ />  </ /_/ / /_/ / \n/___/_/ /_/_/ /_/\\__,_/_/|_/_____/_____/  \n \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"InfluxDB\"\nvar_disk=\"8\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -f /etc/apt/sources.list.d/influxdata.list ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating ${APP}\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\n"
  },
  {
    "path": "ct/iobroker.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    _       ____             __            \n   (_)___  / __ )_________  / /_____  _____\n  / / __ \\/ __  / ___/ __ \\/ //_/ _ \\/ ___/\n / / /_/ / /_/ / /  / /_/ / ,< /  __/ /    \n/_/\\____/_____/_/   \\____/_/|_|\\___/_/     \n \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"ioBroker\"\nvar_disk=\"8\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/iobroker ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating ${APP} LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:8081${CL} \\n\"\n"
  },
  {
    "path": "ct/iventoy.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    _ _    __           __             \n   (_) |  / /__  ____  / /_____  __  __\n  / /| | / / _ \\/ __ \\/ __/ __ \\/ / / /\n / / | |/ /  __/ / / / /_/ /_/ / /_/ / \n/_/  |___/\\___/_/ /_/\\__/\\____/\\__, /  \n                              /____/\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"iVentoy\"\nvar_disk=\"2\"\nvar_cpu=\"1\"\nvar_ram=\"512\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"0\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nif [[ ! -d /opt/iventoy ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_error \"There is currently no update path available.\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:26000/ ${CL} \\n\""
  },
  {
    "path": "ct/jackett.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n       __           __        __  __ \n      / /___ ______/ /_____  / /_/ /_\n __  / / __ `/ ___/ //_/ _ \\/ __/ __/\n/ /_/ / /_/ / /__/ ,< /  __/ /_/ /_  \n\\____/\\__,_/\\___/_/|_|\\___/\\__/\\__/  \n                                     \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Jackett\"\nvar_disk=\"2\"\nvar_cpu=\"1\"\nvar_ram=\"512\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -f /etc/systemd/system/jackett.service ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nRELEASE=$(wget -q https://github.com/Jackett/Jackett/releases/latest -O - | grep \"title>Release\" | cut -d \" \" -f 4)\nif [[ ! -f /opt/${APP}_version.txt ]] || [[ \"${RELEASE}\" != \"$(cat /opt/${APP}_version.txt)\" ]]; then\n  msg_info \"Updating ${APP}\"\n  wget -q https://github.com/Jackett/Jackett/releases/download/$RELEASE/Jackett.Binaries.LinuxAMDx64.tar.gz\n  systemctl stop jackett\n  rm -rf /opt/Jackett\n  tar -xzf Jackett.Binaries.LinuxAMDx64.tar.gz -C /opt\n  rm -rf Jackett.Binaries.LinuxAMDx64.tar.gz\n  systemctl start jackett\n  echo \"${RELEASE}\" >/opt/${APP}_version.txt\n  msg_ok \"Updated ${APP} to ${RELEASE}\"\nelse\n  msg_ok \"No update required. ${APP} is already at ${RELEASE}\"\nfi\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:9117${CL}\\n\"\n"
  },
  {
    "path": "ct/jellyfin.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n       __     ____      _____     \n      / /__  / / /_  __/ __(_)___ \n __  / / _ \\/ / / / / / /_/ / __ \\\n/ /_/ /  __/ / / /_/ / __/ / / / /\n\\____/\\___/_/_/\\__, /_/ /_/_/ /_/ \n              /____/              \n \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Jellyfin\"\nvar_disk=\"8\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"ubuntu\"\nvar_version=\"22.04\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /usr/lib/jellyfin ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating ${APP} LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated ${APP} LXC\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n             ${BL}http://${IP}:8096${CL}\\n\"\n"
  },
  {
    "path": "ct/jellyseerr.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n       __     ____\n      / /__  / / /_  __________  ___  __________\n __  / / _ \\/ / / / / / ___/ _ \\/ _ \\/ ___/ ___/\n/ /_/ /  __/ / / /_/ (__  )  __/  __/ /  / /\n\\____/\\___/_/_/\\__, /____/\\___/\\___/_/  /_/\n              /____/\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Jellyseerr\"\nvar_disk=\"8\"\nvar_cpu=\"4\"\nvar_ram=\"4096\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/jellyseerr ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nif (( $(df /boot | awk 'NR==2{gsub(\"%\",\"\",$5); print $5}') > 80 )); then\n  read -r -p \"Warning: Storage is dangerously low, continue anyway? <y/N> \" prompt\n  [[ ${prompt,,} =~ ^(y|yes)$ ]] || exit\nfi\nwhiptail --backtitle \"Proxmox VE Helper Scripts\" --msgbox --title \"SET RESOURCES\" \"Please set the resources in your Jellyseerr LXC to 4vcpu and 4096RAM for the build process before continuing\" 10 75\nif ! command -v pnpm &> /dev/null; then\n    msg_error \"pnpm not found. Installing...\"\n    npm install -g pnpm &>/dev/null\nelse\n    msg_ok \"pnpm is already installed.\"\nfi\nmsg_info \"Updating $APP\"\ncd /opt/jellyseerr\noutput=$(git pull --no-rebase)\nif echo \"$output\" | grep -q \"Already up to date.\"\nthen\n  msg_ok \"$APP is already up to date.\"\n  exit\nfi\nsystemctl stop jellyseerr\nexport CYPRESS_INSTALL_BINARY=0 \npnpm install --frozen-lockfile &>/dev/null\nexport NODE_OPTIONS=\"--max-old-space-size=3072\"\npnpm build &>/dev/null\ncat <<EOF >/etc/systemd/system/jellyseerr.service\n[Unit]\nDescription=jellyseerr Service\nAfter=network.target\n\n[Service]\nEnvironmentFile=/etc/jellyseerr/jellyseerr.conf\nEnvironment=NODE_ENV=production\nType=exec\nWorkingDirectory=/opt/jellyseerr\nExecStart=/usr/bin/node dist/index.js\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl daemon-reload\nsystemctl start jellyseerr\nmsg_ok \"Updated $APP\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_info \"Setting Container to Normal Resources\"\npct set $CTID -memory 2048\npct set $CTID -cores 2\nmsg_ok \"Set Container to Normal Resources\"\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:5055${CL} \\n\"\n"
  },
  {
    "path": "ct/kavita.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    __ __            _ __       \n   / //_/___ __   __(_) /_____ _\n  / ,< / __ `/ | / / / __/ __ `/\n / /| / /_/ /| |/ / / /_/ /_/ / \n/_/ |_\\__,_/ |___/_/\\__/\\__,_/  \n                                \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Kavita\"\nvar_disk=\"8\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/Kavita ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating $APP LXC\"\nsystemctl stop kavita\nRELEASE=$(curl -s https://api.github.com/repos/Kareadita/Kavita/releases/latest | grep \"tag_name\" | awk '{print substr($2, 2, length($2)-3) }')\ntar -xvzf <(curl -fsSL https://github.com/Kareadita/Kavita/releases/download/$RELEASE/kavita-linux-x64.tar.gz) --no-same-owner &>/dev/null\nrm -rf Kavita/config\ncp -r Kavita/* /opt/Kavita\nrm -rf Kavita\nsystemctl start kavita\nmsg_ok \"Updated $APP LXC\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:5000${CL} \\n\"\n"
  },
  {
    "path": "ct/keycloak.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    __ __                __            __  \n   / //_/__  __  _______/ /___  ____ _/ /__\n  / ,< / _ \\/ / / / ___/ / __ \\/ __  / //_/\n / /| /  __/ /_/ / /__/ / /_/ / /_/ / ,<   \n/_/ |_\\___/\\__, /\\___/_/\\____/\\__,_/_/|_|  \n          /____/                           \n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Keycloak\"\nvar_disk=\"4\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -f /etc/systemd/system/keycloak.service ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating ${APP} LXC\"\n\nmsg_info \"Updating packages\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\n\nRELEASE=$(curl -s https://api.github.com/repos/keycloak/keycloak/releases/latest | grep \"tag_name\" | awk '{print substr($2, 2, length($2)-3) }')\nmsg_info \"Downloading Keycloak v$RELEASE\"\ncd /opt\nwget -q https://github.com/keycloak/keycloak/releases/download/$RELEASE/keycloak-$RELEASE.tar.gz\n$STD tar -xvf keycloak-$RELEASE.tar.gz\n\nmsg_info \"Merging configuration files\"\ncp -r keycloak/conf keycloak-$RELEASE\ncp -r keycloak/providers keycloak-$RELEASE\ncp -r keycloak/themes keycloak-$RELEASE\n\nmsg_info \"Updating Keycloak\"\nmv keycloak keycloak.old\nmv keycloak-$RELEASE keycloak\n\nmsg_info \"Delete temporary installation files\"\nrm keycloak-$RELEASE.tar.gz\nrm -rf keycloak.old\n\nmsg_info \"Restating Keycloak\"\nsystemctl restart keycloak\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:8080/admin${CL} \\n\"\n"
  },
  {
    "path": "ct/kubo.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# Co-Author: ulmentflam\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    __ __      __\n   / //_/_  __/ /_  ____\n  / ,< / / / / __ \\/ __ \\\n / /| / /_/ / /_/ / /_/ /\n/_/ |_\\__,_/_.___/\\____/\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Kubo\"\nvar_disk=\"4\"\nvar_cpu=\"2\"\nvar_ram=\"4096\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -f /usr/local/kubo ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nRELEASE=$(wget -q https://github.com/ipfs/kubo/releases/latest -O - | grep \"title>Release\" | cut -d \" \" -f 4)\nif [[ \"${RELEASE}\" != \"$(cat /opt/${APP}_version.txt)\" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then\n  msg_info \"Updating $APP LXC\"\n  apt-get update &>/dev/null\n  apt-get -y upgrade &>/dev/null\n  wget -q \"https://github.com/ipfs/kubo/releases/download/${RELEASE}/kubo_${RELEASE}_linux-amd64.tar.gz\"\n  tar -xzf \"kubo_${RELEASE}_linux-amd64.tar.gz\" -C /usr/local\n  systemctl restart ipfs.service\n  echo \"${RELEASE}\" >/opt/${APP}_version.txt\n  rm \"kubo_${RELEASE}_linux-amd64.tar.gz\"\n  msg_ok \"Updated $APP LXC\"\nelse\n  msg_ok \"No update required. ${APP} is already at ${RELEASE}\"\nfi\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:5001/webui ${CL} \\n\"\n"
  },
  {
    "path": "ct/lazylibrarian.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck\n# Co-Author: MountyMapleSyrup (MountyMapleSyrup)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    __                      __    _ __                    _           \n   / /   ____ _____  __  __/ /   (_) /_  _________ ______(_)___ _____ \n  / /   / __ `/_  / / / / / /   / / __ \\/ ___/ __ `/ ___/ / __ `/ __ \\\n / /___/ /_/ / / /_/ /_/ / /___/ / /_/ / /  / /_/ / /  / / /_/ / / / /\n/_____/\\__,_/ /___/\\__, /_____/_/_.___/_/   \\__,_/_/  /_/\\__,_/_/ /_/ \n                  /____/                                                                                   \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"LazyLibrarian\"\nvar_disk=\"4\"\nvar_cpu=\"2\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/LazyLibrarian/ ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Stopping LazyLibrarian\"\nsystemctl stop lazylibrarian\nmsg_ok \"LazyLibrarian Stopped\"\n\nmsg_info \"Updating $APP LXC\"\ngit -C /opt/LazyLibrarian pull origin master &>/dev/null\nmsg_ok \"Updated $APP LXC\"\n\nmsg_info \"Starting LazyLibrarian\"\nsystemctl start lazylibrarian\nmsg_ok \"Started LazyLibrarian\"\n\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:5299${CL} \\n\"\n"
  },
  {
    "path": "ct/lidarr.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    __    _     __               \n   / /   (_)___/ /___  __________\n  / /   / / __  / __ `/ ___/ ___/\n / /___/ / /_/ / /_/ / /  / /    \n/_____/_/\\__,_/\\__,_/_/  /_/     \n                                 \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Lidarr\"\nvar_disk=\"4\"\nvar_cpu=\"2\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /var/lib/lidarr/ ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating $APP LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated $APP LXC\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:8686${CL} \\n\"\n"
  },
  {
    "path": "ct/linkwarden.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    __    _       __                           __\n   / /   (_)___  / /___      ______ __________/ /__  ____\n  / /   / / __ \\/ //_/ | /| / / __ `/ ___/ __  / _ \\/ __ \\\n / /___/ / / / / ,<  | |/ |/ / /_/ / /  / /_/ /  __/ / / /\n/_____/_/_/ /_/_/|_| |__/|__/\\__,_/_/   \\__,_/\\___/_/ /_/\n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Linkwarden\"\nvar_disk=\"8\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"ubuntu\"\nvar_version=\"22.04\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/linkwarden ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\n\nRELEASE=$(curl -s https://api.github.com/repos/linkwarden/linkwarden/releases/latest | grep \"tag_name\" | awk '{print substr($2, 2, length($2)-3) }')\nif [[ \"${RELEASE}\" != \"$(cat /opt/${APP}_version.txt)\" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then\n  msg_info \"Stopping ${APP}\"\n  systemctl stop linkwarden\n  msg_ok \"Stopped ${APP}\"\n\n  msg_info \"Updating ${APP} to ${RELEASE}\"\n  cd /opt/linkwarden\n  git pull\n  yarn\n  npx playwright install-deps\n  yarn playwright install\n  yarn prisma generate\n  yarn build\n  yarn prisma migrate deploy\n  echo \"${RELEASE}\" >/opt/${APP}_version.txt\n  msg_ok \"Updated ${APP} to ${RELEASE}\"\n\n  msg_info \"Starting ${APP}\"\n  systemctl start linkwarden\n  msg_ok \"Started ${APP}\"\n  msg_ok \"Updated Successfully\"\nelse\n  msg_ok \"No update required.  ${APP} is already at ${RELEASE}.\"\nfi\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP}${CL} should be reachable by going to the following URL.\n         ${BL}http://${IP}:3000${CL} \\n\"\n"
  },
  {
    "path": "ct/lldap.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# Co-Author: remz1337\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ____    __          \n   / / /___/ /___ _____ \n  / / / __  / __ `/ __ \\\n / / / /_/ / /_/ / /_/ /\n/_/_/\\__,_/\\__,_/ .___/ \n               /_/      \n \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"lldap\"\nvar_disk=\"4\"\nvar_cpu=\"1\"\nvar_ram=\"512\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -f /etc/systemd/system/lldap.service ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating $APP\"\napt update\napt upgrade -y lldap\nmsg_ok \"Updated $APP\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:17170${CL} \\n\"\n"
  },
  {
    "path": "ct/mafl.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\n  clear\n  cat <<\"EOF\"\n    __  ___      ______\n   /  |/  /___ _/ __/ /\n  / /|_/ / __ `/ /_/ /\n / /  / / /_/ / __/ /\n/_/  /_/\\__,_/_/ /_/\n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Mafl\"\nvar_disk=\"6\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\n  header_info\n  if [[ ! -d /opt/mafl ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\n  whiptail --backtitle \"Proxmox VE Helper Scripts\" --msgbox --title \"SET RESOURCES\" \"Please set the resources in your ${APP} LXC to ${var_cpu}vCPU and ${var_ram}RAM for the build process before continuing\" 10 75\n  RELEASE=$(curl -s https://api.github.com/repos/hywax/mafl/releases/latest | grep \"tag_name\" | awk '{print substr($2, 3, length($2)-4) }')\n  msg_info \"Updating Mafl to v${RELEASE} (Patience)\"\n  systemctl stop mafl\n  wget -q https://github.com/hywax/mafl/archive/refs/tags/v${RELEASE}.tar.gz\n  tar -xzf v${RELEASE}.tar.gz\n  cp -r mafl-${RELEASE}/* /opt/mafl/\n  rm -rf mafl-${RELEASE}\n  cd /opt/mafl\n  yarn install\n  yarn build\n  systemctl start mafl\n  msg_ok \"Updated Mafl to v${RELEASE}\"\n  exit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_info \"Setting Container to Normal Resources\"\npct set $CTID -memory 1024\npct set $CTID -cores 1\nmsg_ok \"Set Container to Normal Resources\"\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:3000${CL} \\n\"\n"
  },
  {
    "path": "ct/magicmirror.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    __  ___            _      __  ____                     \n   /  |/  /___ _____ _(_)____/  |/  (_)_____________  _____\n  / /|_/ / __  / __  / / ___/ /|_/ / / ___/ ___/ __ \\/ ___/\n / /  / / /_/ / /_/ / / /__/ /  / / / /  / /  / /_/ / /    \n/_/  /_/\\__,_/\\__, /_/\\___/_/  /_/_/_/  /_/   \\____/_/     \n             /____/                                     \n \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"MagicMirror\"\nvar_disk=\"3\"\nvar_cpu=\"1\"\nvar_ram=\"512\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/magicmirror ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\n  if [[ \"$(node -v | cut -d 'v' -f 2)\" == \"18.\"* ]]; then\n    if ! command -v npm >/dev/null 2>&1; then\n      echo \"Installing NPM...\"\n      apt-get install -y npm >/dev/null 2>&1\n      echo \"Installed NPM...\"\n    fi\n  fi\nmsg_info \"Updating ${APP} LXC\"\ncd /opt/magicmirror\ngit pull &>/dev/null\nnpm install --only=prod --omit=dev &>/dev/null\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:8080${CL} \\n\"\n"
  },
  {
    "path": "ct/mariadb.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    __  ___           _       ____  ____ \n   /  |/  /___ ______(_)___ _/ __ \\/ __ )\n  / /|_/ / __  / ___/ / __  / / / / __  |\n / /  / / /_/ / /  / / /_/ / /_/ / /_/ / \n/_/  /_/\\__,_/_/  /_/\\__,_/_____/_____/  \n \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"MariaDB\"\nvar_disk=\"4\"\nvar_cpu=\"1\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -f /etc/apt/sources.list.d/mariadb.list ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating ${APP} LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\n"
  },
  {
    "path": "ct/matterbridge.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: MickLesk (Canbiz)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    __  ___      __  __            __         _     __         \n   /  |/  /___ _/ /_/ /____  _____/ /_  _____(_)___/ /___ ____ \n  / /|_/ / __ `/ __/ __/ _ \\/ ___/ __ \\/ ___/ / __  / __ `/ _ \\\n / /  / / /_/ / /_/ /_/  __/ /  / /_/ / /  / / /_/ / /_/ /  __/\n/_/  /_/\\__,_/\\__/\\__/\\___/_/  /_.___/_/  /_/\\__,_/\\__, /\\___/ \n                                                  /____/                                      \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Matterbridge\"\nvar_disk=\"4\"\nvar_cpu=\"1\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /root/Matterbridge ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_error \"Update via the Matterbridge UI\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} Setup should be reachable by going to the following URL.\n         ${BL}http://${IP}:8283${CL} \\n\"\n"
  },
  {
    "path": "ct/mediamtx.sh",
    "content": "#!/usr/bin/env bash\n\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    __  ___         ___       __  __________  __\n   /  |/  /__  ____/ (_)___ _/  |/  /_  __/ |/ /\n  / /|_/ / _ \\/ __  / / __ `/ /|_/ / / /  |   /\n / /  / /  __/ /_/ / / /_/ / /  / / / /  /   |\n/_/  /_/\\___/\\__,_/_/\\__,_/_/  /_/ /_/  /_/|_|\n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"MediaMTX\"\nvar_disk=\"4\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/mediamtx/ ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\n\nmsg_error \"There is currently no update path available.\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\n"
  },
  {
    "path": "ct/medusa.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    __  ___         __\n   /  |/  /__  ____/ /_  ___________ _\n  / /|_/ / _ \\/ __  / / / / ___/ __ `/\n / /  / /  __/ /_/ / /_/ (__  ) /_/ / \n/_/  /_/\\___/\\__,_/\\__,_/____/\\__,_/\n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Medusa\"\nvar_disk=\"6\"\nvar_cpu=\"2\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/medusa ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating ${APP}\"\nsystemctl stop medusa.service\n/opt/medusa\ngit pull\nsystemctl start medusa.service\nmsg_ok \"Successfully Updated ${APP}\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:8081${CL} \\n\"\n"
  },
  {
    "path": "ct/memos.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck\n# Co-Author: MickLesk (Canbiz)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    __  ___                         \n   /  |/  /__  ____ ___  ____  _____\n  / /|_/ / _ \\/ __ `__ \\/ __ \\/ ___/\n / /  / /  __/ / / / / / /_/ (__  ) \n/_/  /_/\\___/_/ /_/ /_/\\____/____/  \n                                    \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Memos\"\nvar_disk=\"7\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/memos ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating $APP (Patience)\"\ncd /opt/memos\noutput=$(git pull --no-rebase)\nif echo \"$output\" | grep -q \"Already up to date.\"\nthen\n  msg_ok \"$APP is already up to date.\"\n  exit\nfi\nsystemctl stop memos\ncd /opt/memos/web \npnpm i --frozen-lockfile &>/dev/null\npnpm build &>/dev/null\ncd /opt/memos\nmkdir -p /opt/memos/server/dist\ncp -r web/dist/* /opt/memos/server/dist/\ncp -r web/dist/* /opt/memos/server/router/frontend/dist/ \ngo build -o /opt/memos/memos -tags=embed bin/memos/main.go &>/dev/null\nsystemctl start memos\nmsg_ok \"Updated $APP\"\nexit\n}\n\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:9030${CL} \\n\"\n"
  },
  {
    "path": "ct/meshcentral.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    __  ___          __    ______           __             __\n   /  |/  /__  _____/ /_  / ____/__  ____  / /__________ _/ /\n  / /|_/ / _ \\/ ___/ __ \\/ /   / _ \\/ __ \\/ __/ ___/ __  / / \n / /  / /  __(__  ) / / / /___/  __/ / / / /_/ /  / /_/ / /  \n/_/  /_/\\___/____/_/ /_/\\____/\\___/_/ /_/\\__/_/   \\__,_/_/   \n \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"MeshCentral\"\nvar_disk=\"2\"\nvar_cpu=\"1\"\nvar_ram=\"512\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/meshcentral ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating ${APP} LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}${CL} \\n\"\n"
  },
  {
    "path": "ct/metube.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: MickLesk (Canbiz)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    __  ___   ______      __       \n   /  |/  /__/_  __/_  __/ /_  ___ \n  / /|_/ / _ \\/ / / / / / __ \\/ _ \\\n / /  / /  __/ / / /_/ / /_/ /  __/\n/_/  /_/\\___/_/  \\__,_/_.___/\\___/ \n                                                                \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"MeTube\"\nvar_disk=\"10\"\nvar_cpu=\"1\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/metube ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nif (( $(df /boot | awk 'NR==2{gsub(\"%\",\"\",$5); print $5}') > 80 )); then\n  read -r -p \"Warning: Storage is dangerously low, continue anyway? <y/N> \" prompt\n  [[ ${prompt,,} =~ ^(y|yes)$ ]] || exit\nfi\nmsg_info \"Stopping ${APP} Service\"\nsystemctl stop metube\nmsg_ok \"Stopped ${APP} Service\"\n\nmsg_info \"Updating ${APP} to latest Git\"\ncd /opt\nif [ -d metube_bak ]; then\n  rm -rf metube_bak\nfi\nmv metube metube_bak\ngit clone https://github.com/alexta69/metube /opt/metube  >/dev/null 2>&1\ncd /opt/metube/ui\nnpm install >/dev/null 2>&1\nnode_modules/.bin/ng build >/dev/null 2>&1\ncd /opt/metube\ncp /opt/metube_bak/.env /opt/metube/\npip3 install pipenv >/dev/null 2>&1\npipenv install >/dev/null 2>&1\n\nif [ -d \"/opt/metube_bak\" ]; then\nrm -rf /opt/metube_bak\nfi\nmsg_ok \"Updated ${APP} to latest Git\"\n\nmsg_info \"Starting ${APP} Service\"\nsystemctl start metube\nsleep 1\nmsg_ok \"Started ${APP} Service\"\nmsg_ok \"Updated Successfully!\\n\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} Setup should be reachable by going to the following URL.\n         ${BL}http://${IP}:8081${CL} \\n\""
  },
  {
    "path": "ct/mongodb.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    __  ___                        ____  ____ \n   /  |/  /___  ____  ____ _____  / __ \\/ __ )\n  / /|_/ / __ \\/ __ \\/ __ `/ __ \\/ / / / __  |\n / /  / / /_/ / / / / /_/ / /_/ / /_/ / /_/ / \n/_/  /_/\\____/_/ /_/\\__, /\\____/_____/_____/  \n                   /____/                     \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"MongoDB\"\nvar_disk=\"4\"\nvar_cpu=\"1\"\nvar_ram=\"512\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -f /etc/apt/sources.list.d/mongodb-org-7.0.list ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating ${APP} LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\n"
  },
  {
    "path": "ct/motioneye.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    __  ___      __  _                           \n   /  |/  /___  / /_(_)___  ____  ___  __  _____ \n  / /|_/ / __ \\/ __/ / __ \\/ __ \\/ _ \\/ / / / _ \\\n / /  / / /_/ / /_/ / /_/ / / / /  __/ /_/ /  __/\n/_/  /_/\\____/\\__/_/\\____/_/ /_/\\___/\\__, /\\___/ \n                                    /____/       \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Motioneye\"\nvar_disk=\"8\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -f /etc/systemd/system/motioneye.service ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating ${APP} LXC\"\npip install motioneye --upgrade &>/dev/null\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:8765${CL} \\n\"\n"
  },
  {
    "path": "ct/mqtt.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    __  ___           ____        _ ____________    \n   /  |/  /___  _____/ __ \\__  __(_)_  __/_  __/___ \n  / /|_/ / __ \\/ ___/ / / / / / / / / /   / / / __ \\\n / /  / / /_/ (__  ) /_/ / /_/ / / / /   / / / /_/ /\n/_/  /_/\\____/____/\\___\\_\\__,_/_/ /_/   /_/  \\____/ \n                                                    \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"MQTT\"\nvar_disk=\"2\"\nvar_cpu=\"1\"\nvar_ram=\"512\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -f /etc/mosquitto/conf.d/default.conf ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating ${APP} LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\n"
  },
  {
    "path": "ct/myspeed.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# Co-Author: MickLesk (Canbiz)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    __  ___      _____                     __\n   /  |/  /_  __/ ___/____  ___  ___  ____/ /\n  / /|_/ / / / /\\__ \\/ __ \\/ _ \\/ _ \\/ __  / \n / /  / / /_/ /___/ / /_/ /  __/  __/ /_/ /  \n/_/  /_/\\__, //____/ .___/\\___/\\___/\\__,_/   \n       /____/     /_/                        \n\t   \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"MySpeed\"\nvar_disk=\"4\"\nvar_cpu=\"1\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/myspeed ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nif (( $(df /boot | awk 'NR==2{gsub(\"%\",\"\",$5); print $5}') > 80 )); then\n  read -r -p \"Warning: Storage is dangerously low, continue anyway? <y/N> \" prompt\n  [[ ${prompt,,} =~ ^(y|yes)$ ]] || exit\nfi\nRELEASE=$(wget -q https://github.com/gnmyt/myspeed/releases/latest -O - | grep \"title>Release\" | cut -d \" \" -f 5)\nif [[ ! -f /opt/${APP}_version.txt ]] || [[ \"${RELEASE}\" != \"$(cat /opt/${APP}_version.txt)\" ]]; then\n\n  msg_info \"Stopping ${APP} Service\"\n  systemctl stop myspeed\n  msg_ok \"Stopped ${APP} Service\"\n\n  msg_info \"Updating ${APP} to ${RELEASE}\"\n  cd /opt\n  rm -rf myspeed_bak\n  mv myspeed myspeed_bak\n  wget -q https://github.com/gnmyt/myspeed/releases/download/v$RELEASE/MySpeed-$RELEASE.zip\n  unzip -q MySpeed-$RELEASE.zip -d myspeed\n  cd myspeed\n  npm install >/dev/null 2>&1\n  echo \"${RELEASE}\" >/opt/${APP}_version.txt\n  msg_ok \"Updated ${APP} to ${RELEASE}\"\n\n  msg_info \"Starting ${APP} Service\"\n  systemctl start myspeed\n  msg_ok \"Started ${APP} Service\"\n\n  msg_info \"Cleaning up\"\n  rm -rf MySpeed-$RELEASE.zip\n  msg_ok \"Cleaned\"\n\n  msg_ok \"Updated Successfully!\\n\"\nelse\n  msg_ok \"No update required. ${APP} is already at ${RELEASE}\"\nfi\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} Setup should be reachable by going to the following URL.\n         ${BL}http://${IP}:5216${CL} \\n\"\n"
  },
  {
    "path": "ct/mysql.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck\n# Co-Author: MickLesk (Canbiz)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    __  ___      _____ ____    __ \n   /  |/  /_  __/ ___// __ \\  / / \n  / /|_/ / / / /\\__ \\/ / / / / /  \n / /  / / /_/ /___/ / /_/ / / /___\n/_/  /_/\\__, //____/\\___\\_\\/_____/\n       /____/                     \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"MySQL\"\nvar_disk=\"4\"\nvar_cpu=\"1\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -f /usr/share/keyrings/mysql.gpg ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating ${APP} LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\n"
  },
  {
    "path": "ct/n8n.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n         ___        \n        / _ \\       \n  _ __ | (_) |____  \n |  _ \\ > _ <|  _ \\ \n | | | | (_) | | | |\n |_| |_|\\___/|_| |_|\n \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"n8n\"\nvar_disk=\"6\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -f /etc/systemd/system/n8n.service ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\n  if [[ \"$(node -v | cut -d 'v' -f 2)\" == \"18.\"* ]]; then\n    if ! command -v npm >/dev/null 2>&1; then\n      echo \"Installing NPM...\"\n      apt-get install -y npm >/dev/null 2>&1\n      echo \"Installed NPM...\"\n    fi\n  fi\nmsg_info \"Updating ${APP} LXC\"\nnpm update -g n8n &>/dev/null\nsystemctl restart n8n\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:5678${CL} \\n\"\n"
  },
  {
    "path": "ct/navidrome.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    _   __            _     __                        \n   / | / /___ __   __(_)___/ /________  ____ ___  ___ \n  /  |/ / __  / | / / / __  / ___/ __ \\/ __  __ \\/ _ \\\n / /|  / /_/ /| |/ / / /_/ / /  / /_/ / / / / / /  __/\n/_/ |_/\\__,_/ |___/_/\\__,_/_/   \\____/_/ /_/ /_/\\___/ \n \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Navidrome\"\nvar_disk=\"4\"\nvar_cpu=\"2\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/navidrome ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nRELEASE=$(curl -s https://api.github.com/repos/navidrome/navidrome/releases/latest | grep \"tag_name\" | awk '{print substr($2, 3, length($2)-4) }')\nmsg_info \"Stopping ${APP}\"\nsystemctl stop navidrome.service\nmsg_ok \"Stopped Navidrome\"\n\nmsg_info \"Updating to v${RELEASE}\"\nwget https://github.com/navidrome/navidrome/releases/download/v${RELEASE}/navidrome_${RELEASE}_linux_amd64.tar.gz -O Navidrome.tar.gz &>/dev/null\ntar -xvzf Navidrome.tar.gz -C /opt/navidrome/ &>/dev/null\nmsg_ok \"Updated ${APP}\"\nrm Navidrome.tar.gz\n\nmsg_info \"${GN} Starting ${APP}\"\nsystemctl start navidrome.service\nmsg_ok \"Started ${APP}\"\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:4533${CL} \\n\"\n"
  },
  {
    "path": "ct/neo4j.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck\n# Co-Author: havardthom\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"     \n    _   __           __ __  _ \n   / | / /__  ____  / // / (_)\n  /  |/ / _ \\/ __ \\/ // /_/ /\n / /|  /  __/ /_/ /__  __/ /\n/_/ |_/\\___/\\____/  /_/_/ /\n                     /___/\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Neo4j\"\nvar_disk=\"4\"\nvar_cpu=\"1\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /etc/neo4j ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating ${APP}\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} Browser should be reachable by going to the following URL.\n         ${BL}http://${IP}:7474${CL} \\n\"\n"
  },
  {
    "path": "ct/nextcloudpi.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    _   __          __  ________                ______  _ \n   / | / /__  _  __/ /_/ ____/ /___  __  ______/ / __ \\(_)\n  /  |/ / _ \\| |/_/ __/ /   / / __ \\/ / / / __  / /_/ / / \n / /|  /  __/>  </ /_/ /___/ / /_/ / /_/ / /_/ / ____/ /  \n/_/ |_/\\___/_/|_|\\__/\\____/_/\\____/\\__,_/\\__,_/_/   /_/   \n                                                          \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"NextCloudPi\"\nvar_disk=\"8\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -f /lib/systemd/system/nextcloud-domain.service ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating ${APP} LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} Setup should be reachable by going to the following URL.\n         ${BL}https://${IP}/${CL} \\n\"\n"
  },
  {
    "path": "ct/nginxproxymanager.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\n  clear\n  cat <<\"EOF\"\n    _   __      _               ____                           __  ___                                 \n   / | / /___ _(_)___  _  __   / __ \\_________ __  ____  __   /  |/  /___ _____  ____ _____ ____  _____\n  /  |/ / __  / / __ \\| |/_/  / /_/ / ___/ __ \\| |/_/ / / /  / /|_/ / __  / __ \\/ __  / __  / _ \\/ ___/\n / /|  / /_/ / / / / />  <   / ____/ /  / /_/ />  </ /_/ /  / /  / / /_/ / / / / /_/ / /_/ /  __/ /    \n/_/ |_/\\__, /_/_/ /_/_/|_|  /_/   /_/   \\____/_/|_|\\__, /  /_/  /_/\\__,_/_/ /_/\\__,_/\\__, /\\___/_/     \n      /____/                                      /____/                            /____/             \n \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Nginx Proxy Manager\"\nvar_disk=\"4\"\nvar_cpu=\"2\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\n  header_info\n  if [[ ! -f /lib/systemd/system/npm.service ]]; then\n    msg_error \"No ${APP} Installation Found!\"\n    exit\n  fi\n  whiptail --backtitle \"Proxmox VE Helper Scripts\" --msgbox --title \"SET RESOURCES\" \"Please set the resources in your ${APP} LXC to ${var_cpu}vCPU and ${var_ram}RAM for the build process before continuing\" 10 75\n  if ! command -v pnpm &> /dev/null; then  \n    msg_info \"Installing pnpm\"\n    #export NODE_OPTIONS=--openssl-legacy-provider\n    npm install -g pnpm@8.15 &>/dev/null\n    msg_ok \"Installed pnpm\"\n  fi\n  RELEASE=$(curl -s https://api.github.com/repos/NginxProxyManager/nginx-proxy-manager/releases/latest |\n    grep \"tag_name\" |\n    awk '{print substr($2, 3, length($2)-4) }')\n  msg_info \"Stopping Services\"\n  systemctl stop openresty\n  systemctl stop npm\n  msg_ok \"Stopped Services\"\n\n  msg_info \"Cleaning Old Files\"\n  rm -rf /app \\\n    /var/www/html \\\n    /etc/nginx \\\n    /var/log/nginx \\\n    /var/lib/nginx \\\n    /var/cache/nginx &>/dev/null\n  msg_ok \"Cleaned Old Files\"\n\n  msg_info \"Downloading NPM v${RELEASE}\"\n  wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v${RELEASE} -O - | tar -xz &>/dev/null\n  cd nginx-proxy-manager-${RELEASE}\n  msg_ok \"Downloaded NPM v${RELEASE}\"\n\n  msg_info \"Setting up Enviroment\"\n  ln -sf /usr/bin/python3 /usr/bin/python\n  ln -sf /usr/bin/certbot /opt/certbot/bin/certbot\n  ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx\n  ln -sf /usr/local/openresty/nginx/ /etc/nginx\n  sed -i \"s|\\\"version\\\": \\\"0.0.0\\\"|\\\"version\\\": \\\"$RELEASE\\\"|\" backend/package.json\n  sed -i \"s|\\\"version\\\": \\\"0.0.0\\\"|\\\"version\\\": \\\"$RELEASE\\\"|\" frontend/package.json\n  sed -i 's|\"fork-me\": \".*\"|\"fork-me\": \"Proxmox VE Helper-Scripts\"|' frontend/js/i18n/messages.json\n  sed -i \"s|https://github.com.*source=nginx-proxy-manager|https://helper-scripts.com|g\" frontend/js/app/ui/footer/main.ejs\n  sed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf\n  NGINX_CONFS=$(find \"$(pwd)\" -type f -name \"*.conf\")\n  for NGINX_CONF in $NGINX_CONFS; do\n    sed -i 's+include conf.d+include /etc/nginx/conf.d+g' \"$NGINX_CONF\"\n  done\n  mkdir -p /var/www/html /etc/nginx/logs\n  cp -r docker/rootfs/var/www/html/* /var/www/html/\n  cp -r docker/rootfs/etc/nginx/* /etc/nginx/\n  cp docker/rootfs/etc/letsencrypt.ini /etc/letsencrypt.ini\n  cp docker/rootfs/etc/logrotate.d/nginx-proxy-manager /etc/logrotate.d/nginx-proxy-manager\n  ln -sf /etc/nginx/nginx.conf /etc/nginx/conf/nginx.conf\n  rm -f /etc/nginx/conf.d/dev.conf\n  mkdir -p /tmp/nginx/body \\\n    /run/nginx \\\n    /data/nginx \\\n    /data/custom_ssl \\\n    /data/logs \\\n    /data/access \\\n    /data/nginx/default_host \\\n    /data/nginx/default_www \\\n    /data/nginx/proxy_host \\\n    /data/nginx/redirection_host \\\n    /data/nginx/stream \\\n    /data/nginx/dead_host \\\n    /data/nginx/temp \\\n    /var/lib/nginx/cache/public \\\n    /var/lib/nginx/cache/private \\\n    /var/cache/nginx/proxy_temp\n  chmod -R 777 /var/cache/nginx\n  chown root /tmp/nginx\n  echo resolver \"$(awk 'BEGIN{ORS=\" \"} $1==\"nameserver\" {print ($2 ~ \":\")? \"[\"$2\"]\": $2}' /etc/resolv.conf);\" >/etc/nginx/conf.d/include/resolvers.conf\n  if [ ! -f /data/nginx/dummycert.pem ] || [ ! -f /data/nginx/dummykey.pem ]; then\n    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 &>/dev/null\n  fi\n  mkdir -p /app/global /app/frontend/images\n  cp -r backend/* /app\n  cp -r global/* /app/global\n  python3 -m pip install --no-cache-dir certbot-dns-cloudflare &>/dev/null\n  msg_ok \"Setup Enviroment\"\n\n  msg_info \"Building Frontend\"\n  cd ./frontend\n  pnpm install &>/dev/null\n  pnpm upgrade &>/dev/null\n  pnpm run build &>/dev/null\n  cp -r dist/* /app/frontend\n  cp -r app-images/* /app/frontend/images\n  msg_ok \"Built Frontend\"\n\n  msg_info \"Initializing Backend\"\n  rm -rf /app/config/default.json &>/dev/null\n  if [ ! -f /app/config/production.json ]; then\n    cat <<'EOF' >/app/config/production.json\n{\n  \"database\": {\n    \"engine\": \"knex-native\",\n    \"knex\": {\n      \"client\": \"sqlite3\",\n      \"connection\": {\n        \"filename\": \"/data/database.sqlite\"\n      }\n    }\n  }\n}\nEOF\n  fi\n  cd /app\n  pnpm install &>/dev/null\n  msg_ok \"Initialized Backend\"\n\n  msg_info \"Starting Services\"\n  sed -i 's/user npm/user root/g; s/^pid/#pid/g' /usr/local/openresty/nginx/conf/nginx.conf\n  sed -i 's/su npm npm/su root root/g' /etc/logrotate.d/nginx-proxy-manager\n  sed -i 's/include-system-site-packages = false/include-system-site-packages = true/g' /opt/certbot/pyvenv.cfg\n  systemctl enable -q --now openresty\n  systemctl enable -q --now npm\n  msg_ok \"Started Services\"\n\n  msg_info \"Cleaning up\"\n  rm -rf ~/nginx-proxy-manager-*\n  msg_ok \"Cleaned\"\n\n  msg_ok \"Updated Successfully\"\n  exit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_info \"Setting Container to Normal Resources\"\npct set $CTID -cores 1\nmsg_ok \"Set Container to Normal Resources\"\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:81${CL}\\n\"\n"
  },
  {
    "path": "ct/nocodb.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    _   __                 ____  ____ \n   / | / /___  ____  ___  / __ \\/ __ )\n  /  |/ / __ \\/ ___/ __ \\/ / / / __  |\n / /|  / /_/ / /__/ /_/ / /_/ / /_/ / \n/_/ |_/\\____/\\___/\\____/_____/_____/  \n \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"NocoDB\"\nvar_disk=\"4\"\nvar_cpu=\"1\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -f /etc/systemd/system/nocodb.service ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating ${APP}\"\nsystemctl stop nocodb.service\ncd /opt/nocodb\nrm -rf nocodb\ncurl -s http://get.nocodb.com/linux-x64 -o nocodb -L\nchmod +x nocodb\nsystemctl start nocodb.service\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:8080/dashboard${CL} \\n\"\n"
  },
  {
    "path": "ct/node-red.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    _   __          __        ____           __\n   / | / /___  ____/ /__     / __ \\___  ____/ /\n  /  |/ / __ \\/ __  / _ \\   / /_/ / _ \\/ __  / \n / /|  / /_/ / /_/ /  __/  / _, _/  __/ /_/ /  \n/_/ |_/\\____/\\__,_/\\___/  /_/ |_|\\___/\\__,_/   \n \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Node-Red\"\nvar_disk=\"4\"\nvar_cpu=\"1\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nif [[ ! -d /root/.node-red ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nUPD=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"SUPPORT\" --radiolist --cancel-button Exit-Script \"Spacebar = Select\" 11 58 2 \\\n  \"1\" \"Update ${APP}\" ON \\\n  \"2\" \"Install Themes\" OFF \\\n  3>&1 1>&2 2>&3)\nheader_info\nif [ \"$UPD\" == \"1\" ]; then\n  if [[ \"$(node -v | cut -d 'v' -f 2)\" == \"18.\"* ]]; then\n    if ! command -v npm >/dev/null 2>&1; then\n      msg_info \"Installing NPM\"\n      apt-get install -y npm >/dev/null 2>&1\n      msg_ok \"Installed NPM\"\n    fi\n  fi\nmsg_info \"Stopping ${APP}\"\nsystemctl stop nodered\nmsg_ok \"Stopped ${APP}\"\n\nmsg_info \"Updating ${APP}\"\nnpm install -g --unsafe-perm node-red &>/dev/null\nmsg_ok \"Updated ${APP}\"\n\nmsg_info \"Starting ${APP}\"\nsystemctl start nodered\nmsg_ok \"Started ${APP}\"\nmsg_ok \"Update Successful\"\nexit\nfi\nif [ \"$UPD\" == \"2\" ]; then\nTHEME=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"NODE-RED THEMES\" --radiolist --cancel-button Exit-Script \"Choose Theme\" 15 58 6 \\\n    \"aurora\" \"\" OFF \\\n    \"cobalt2\" \"\" OFF \\\n    \"dark\" \"\" OFF \\\n    \"dracula\" \"\" OFF \\\n    \"espresso-libre\" \"\" OFF \\\n    \"github-dark\" \"\" OFF \\\n    \"github-dark-default\" \"\" OFF \\\n    \"github-dark-dimmed\" \"\" OFF \\\n    \"midnight-red\" \"\" ON \\\n    \"monoindustrial\" \"\" OFF \\\n    \"monokai\" \"\" OFF \\\n    \"monokai-dimmed\" \"\" OFF \\\n    \"noctis\" \"\" OFF \\\n    \"oceanic-next\" \"\" OFF \\\n    \"oled\" \"\" OFF \\\n    \"one-dark-pro\" \"\" OFF \\\n    \"one-dark-pro-darker\" \"\" OFF \\\n    \"solarized-dark\" \"\" OFF \\\n    \"solarized-light\" \"\" OFF \\\n    \"tokyo-night\" \"\" OFF \\\n    \"tokyo-night-light\" \"\" OFF \\\n    \"tokyo-night-storm\" \"\" OFF \\\n    \"totallyinformation\" \"\" OFF \\\n    \"zenburn\" \"\" OFF \\\n    3>&1 1>&2 2>&3)\nheader_info\nmsg_info \"Installing ${THEME} Theme\"    \ncd /root/.node-red\nsed -i 's|// theme: \".*\",|theme: \"\",|g' /root/.node-red/settings.js\nnpm install @node-red-contrib-themes/theme-collection &>/dev/null\nsed -i \"{s/theme: \".*\"/theme: '${THEME}',/g}\" /root/.node-red/settings.js\nsystemctl restart nodered\nmsg_ok \"Installed ${THEME} Theme\"\nexit\nfi\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:1880${CL} \\n\"\n"
  },
  {
    "path": "ct/notifiarr.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    _   __      __  _ _____\n   / | / /___  / /_(_) __(_)___ ___________\n  /  |/ / __ \\/ __/ / /_/ / __ `/ ___/ ___/\n / /|  / /_/ / /_/ / __/ / /_/ / /  / /\n/_/ |_/\\____/\\__/_/_/ /_/\\__,_/_/  /_/\n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Notifiarr\"\nvar_disk=\"2\"\nvar_cpu=\"1\"\nvar_ram=\"512\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -f /etc/apt/sources.list.d/golift.list ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating $APP\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated $APP\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:5454${CL} \\n\"\n"
  },
  {
    "path": "ct/ntfy.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n          __  ____\n   ____  / /_/ __/_  __\n  / __ \\/ __/ /_/ / / /\n / / / / /_/ __/ /_/ /\n/_/ /_/\\__/_/  \\__, /\n              /____/\n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"ntfy\"\nvar_disk=\"2\"\nvar_cpu=\"1\"\nvar_ram=\"512\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /var ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating $APP LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated $APP LXC\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}${CL} \\n\"\n"
  },
  {
    "path": "ct/nzbget.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck\n# Co-Author: havardthom\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"     \n    _   _______   ____  ______     __\n   / | / /__  /  / __ )/ ____/__  / /_\n  /  |/ /  / /  / __  / / __/ _ \\/ __/\n / /|  /  / /__/ /_/ / /_/ /  __/ /_\n/_/ |_/  /____/_____/\\____/\\___/\\__/\n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"NZBGet\"\nvar_disk=\"4\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -f /lib/systemd/system/nzbget.service ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating $APP LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated $APP LXC\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:6789${CL} \\n\"\n"
  },
  {
    "path": "ct/octoprint.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n   ____       __        ____       _       __ \n  / __ \\_____/ /_____  / __ \\_____(_)___  / /_\n / / / / ___/ __/ __ \\/ /_/ / ___/ / __ \\/ __/\n/ /_/ / /__/ /_/ /_/ / ____/ /  / / / / / /_ \n\\____/\\___/\\__/\\____/_/   /_/  /_/_/ /_/\\__/\n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"OctoPrint\"\nvar_disk=\"4\"\nvar_cpu=\"1\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"0\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/octoprint ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Stopping OctoPrint\"\nsystemctl stop octoprint\nmsg_ok \"Stopped OctoPrint\"\n\nmsg_info \"Updating OctoPrint\"\nsource /opt/octoprint/bin/activate\npip3 install octoprint --upgrade &>/dev/null\nmsg_ok \"Updated OctoPrint\"\n\nmsg_info \"Starting OctoPrint\"\nsystemctl start octoprint\nmsg_ok \"Started OctoPrint\"\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:5000${CL} \\n\"\n"
  },
  {
    "path": "ct/ollama.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck\n# Co-Author: havardthom\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"     \n   ____  ____\n  / __ \\/ / /___ _____ ___  ____ _\n / / / / / / __ `/ __ `__ \\/ __ `/\n/ /_/ / / / /_/ / / / / / / /_/ /\n\\____/_/_/\\__,_/_/ /_/ /_/\\__,_/\n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Ollama\"\nvar_disk=\"24\"\nvar_cpu=\"4\"\nvar_ram=\"4096\"\nvar_os=\"ubuntu\"\nvar_version=\"22.04\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/ollama ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating ${APP}\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:11434${CL} \\n\"\n"
  },
  {
    "path": "ct/omada.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n   ____                      __     \n  / __ \\____ ___  ____ _____/ /___ _\n / / / / __  __ \\/ __  / __  / __  /\n/ /_/ / / / / / / /_/ / /_/ / /_/ / \n\\____/_/ /_/ /_/\\__,_/\\__,_/\\__,_/  \n \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Omada\"\nvar_disk=\"8\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/tplink ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nlatest_url=$(curl -fsSL \"https://www.tp-link.com/en/support/download/omada-software-controller/\" | grep -o 'https://.*x64.deb' | head -n1)\nlatest_version=$(basename \"${latest_url}\")\nif [ -z \"${latest_version}\" ]; then\n  msg_error \"It seems that the server (tp-link.com) might be down. Please try again at a later time.\"\n  exit\nfi\necho -e \"Updating Omada Controller\"\nwget -qL ${latest_url}\ndpkg -i ${latest_version}\nrm -rf ${latest_version}\necho -e \"Updated Omada Controller\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}https://${IP}:8043${CL} \\n\"\n"
  },
  {
    "path": "ct/ombi.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n   ____            __    _ \n  / __ \\____ ___  / /_  (_)\n / / / / __ `__ \\/ __ \\/ /\n/ /_/ / / / / / / /_/ / /\n\\____/_/ /_/ /_/_.___/_/\n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Ombi\"\nvar_disk=\"4\"\nvar_cpu=\"1\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/ombi ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nRELEASE=$(curl -sL https://api.github.com/repos/Ombi-app/Ombi/releases/latest | grep '\"tag_name\":' | cut -d'\"' -f4)\nif [[ \"${RELEASE}\" != \"$(cat /opt/${APP}_version.txt)\" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then\n  msg_info \"Stopping ${APP}\"\n  systemctl stop ombi\n  msg_ok \"Stopped ${APP}\"\n\n  msg_info \"Updating ${APP} to ${RELEASE}\"\n  wget -q https://github.com/Ombi-app/Ombi/releases/download/${RELEASE}/linux-x64.tar.gz\n  tar -xzf linux-x64.tar.gz -C /opt/ombi\n  rm -rf linux-x64.tar.gz\n  echo \"${RELEASE}\" >/opt/${APP}_version.txt\n  msg_ok \"Updated ${APP} to ${RELEASE}\"\n\n  msg_info \"Starting ${APP}\"\n  systemctl start ombi\n  msg_ok \"Started ${APP}\"\n  msg_ok \"Updated Successfully\"\nelse\n  msg_ok \"No update required.  ${APP} ia already at ${RELEASE}.\"\nfi\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:5000${CL} \\n\"\n"
  },
  {
    "path": "ct/omv.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n   ____                   __  ___         ___      _    __            ____ \n  / __ \\____  ___  ____  /  |/  /__  ____/ (_)___ | |  / /___ ___  __/ / /_\n / / / / __ \\/ _ \\/ __ \\/ /|_/ / _ \\/ __  / / __ `/ | / / __ `/ / / / / __/\n/ /_/ / /_/ /  __/ / / / /  / /  __/ /_/ / / /_/ /| |/ / /_/ / /_/ / / /_  \n\\____/ .___/\\___/_/ /_/_/  /_/\\___/\\__,_/_/\\__,_/ |___/\\__,_/\\__,_/_/\\__/  \n    /_/                                                                    \n \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"OMV\"\nvar_disk=\"4\"\nvar_cpu=\"2\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -f /etc/apt/sources.list.d/openmediavault.list ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating ${APP} LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}${CL} \\n\"\n"
  },
  {
    "path": "ct/openhab.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n                          __  _____    ____ \n  ____  ____  ___  ____  / / / /   |  / __ )\n / __ \\/ __ \\/ _ \\/ __ \\/ /_/ / /| | / __  |\n/ /_/ / /_/ /  __/ / / / __  / ___ |/ /_/ / \n\\____/ .___/\\___/_/ /_/_/ /_/_/  |_/_____/  \n    /_/                                     \n \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"openHAB\"\nvar_disk=\"8\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -f /etc/apt/sources.list.d/openhab.list ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating ${APP} LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:8080${CL} \\n\"\n"
  },
  {
    "path": "ct/openobserve.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n\n   ____                   ____  __\n  / __ \\____  ___  ____  / __ \\/ /_  ________  ______   _____\n / / / / __ \\/ _ \\/ __ \\/ / / / __ \\/ ___/ _ \\/ ___/ | / / _ \\\n/ /_/ / /_/ /  __/ / / / /_/ / /_/ (__  )  __/ /   | |/ /  __/\n\\____/ .___/\\___/_/ /_/\\____/_.___/____/\\___/_/    |___/\\___/\n    /_/\n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"OpenObserve\"\nvar_disk=\"3\"\nvar_cpu=\"1\"\nvar_ram=\"512\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/openobserve/ ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating $APP\"\nsystemctl stop openobserve\nLATEST=$(curl -sL https://api.github.com/repos/openobserve/openobserve/releases/latest | grep '\"tag_name\":' | cut -d'\"' -f4)\ntar zxvf <(curl -fsSL https://github.com/openobserve/openobserve/releases/download/$LATEST/openobserve-${LATEST}-linux-amd64.tar.gz) -C /opt/openobserve\nsystemctl start openobserve\nmsg_ok \"Updated $APP\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:5080${CL} \\n\"\n"
  },
  {
    "path": "ct/openwebui.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck\n# Co-Author: havardthom\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"     \n   ____                      _       __     __    __  ______\n  / __ \\____  ___  ____     | |     / /__  / /_  / / / /  _/\n / / / / __ \\/ _ \\/ __ \\    | | /| / / _ \\/ __ \\/ / / // /\n/ /_/ / /_/ /  __/ / / /    | |/ |/ /  __/ /_/ / /_/ // /\n\\____/ .___/\\___/_/ /_/     |__/|__/\\___/_.___/\\____/___/\n    /_/\n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Open WebUI\"\nvar_disk=\"16\"\nvar_cpu=\"4\"\nvar_ram=\"4096\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/open-webui ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating ${APP} (Patience)\"\ncd /opt/open-webui\noutput=$(git pull --no-rebase)\nif echo \"$output\" | grep -q \"Already up to date.\"\nthen\n  msg_ok \"$APP is already up to date.\"\n  exit\nfi\nsystemctl stop open-webui.service\nnpm install &>/dev/null\nexport NODE_OPTIONS=\"--max-old-space-size=3584\"\nnpm run build &>/dev/null\ncd ./backend\npip install -r requirements.txt -U &>/dev/null\nsystemctl start open-webui.service\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:8080${CL} \\n\"\n"
  },
  {
    "path": "ct/overseerr.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n   ____\n  / __ \\_   _____  _____________  ___  __________\n / / / / | / / _ \\/ ___/ ___/ _ \\/ _ \\/ ___/ ___/\n/ /_/ /| |/ /  __/ /  (__  )  __/  __/ /  / /\n\\____/ |___/\\___/_/  /____/\\___/\\___/_/  /_/\n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Overseerr\"\nvar_disk=\"8\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/overseerr ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating $APP\"\nsystemctl stop overseerr\ncd /opt/overseerr\noutput=$(git pull)\ngit pull &>/dev/null\nif echo \"$output\" | grep -q \"Already up to date.\"\nthen\n  msg_ok \" $APP is already up to date.\"\n  systemctl start overseerr\n  exit\nfi\nyarn install &>/dev/null\nyarn build &>/dev/null\nsystemctl start overseerr\nmsg_ok \"Updated $APP\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:5055${CL} \\n\"\n"
  },
  {
    "path": "ct/owncast.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n   ____                                 __\n  / __ \\_      ______  _________ ______/ /_\n / / / / | /| / / __ \\/ ___/ __ `/ ___/ __/\n/ /_/ /| |/ |/ / / / / /__/ /_/ (__  ) /_\n\\____/ |__/|__/_/ /_/\\___/\\__,_/____/\\__/\n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Owncast\"\nvar_disk=\"2\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/owncast ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating $APP LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated $APP LXC\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n             ${BL}http://${IP}:8080${CL}\n             ${BL}http://${IP}:8080/admin${CL} admin|abc123\\n\"\n"
  },
  {
    "path": "ct/pairdrop.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ____        _      ____\n   / __ \\____ _(_)____/ __ \\_________  ____\n  / /_/ / __ `/ / ___/ / / / ___/ __ \\/ __ \\\n / ____/ /_/ / / /  / /_/ / /  / /_/ / /_/ /\n/_/    \\__,_/_/_/  /_____/_/   \\____/ .___/\n                                   /_/\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"PairDrop\"\nvar_disk=\"4\"\nvar_cpu=\"1\"\nvar_ram=\"512\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/pairdrop ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating $APP\"\nsystemctl stop pairdrop\ncd /opt/pairdrop\ngit pull\nnpm install\nsystemctl start pairdrop\nmsg_ok \"Updated $APP\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:3000${CL} \\n\"\n"
  },
  {
    "path": "ct/paperless-ngx.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\n  clear\n  cat <<\"EOF\"\n    ____                        __                                     \n   / __ \\____ _____  ___  _____/ /__  __________    ____  ____ __  __\n  / /_/ / __ `/ __ \\/ _ \\/ ___/ / _ \\/ ___/ ___/___/ __ \\/ __ `/ |/_/\n / ____/ /_/ / /_/ /  __/ /  / /  __(__  |__  )___/ / / / /_/ />  <  \n/_/    \\__,_/ .___/\\___/_/  /_/\\___/____/____/   /_/ /_/\\__, /_/|_|  \n           /_/                                         /____/        \n \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Paperless-ngx\"\nvar_disk=\"10\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\n  if [[ ! -d /opt/paperless ]]; then\n    msg_error \"No ${APP} Installation Found!\"\n    exit\n  fi\n  RELEASE=$(curl -s https://api.github.com/repos/paperless-ngx/paperless-ngx/releases/latest | grep \"tag_name\" | awk '{print substr($2, 2, length($2)-3) }')\n\n  UPD=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"SUPPORT\" --radiolist --cancel-button Exit-Script \"Spacebar = Select\" 11 58 2 \\\n    \"1\" \"Update Paperless-ngx to $RELEASE\" ON \\\n    \"2\" \"Paperless-ngx Credentials\" OFF \\\n    3>&1 1>&2 2>&3)\n  header_info\n  if [ \"$UPD\" == \"1\" ]; then\n    if [[ \"${RELEASE}\" != \"$(cat /opt/${APP}_version.txt)\" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then\n\t  if [[ \"$(gs --version 2>/dev/null)\" != \"10.04.0\" ]]; then\n        msg_info \"Updating Ghostscript\"\n        cd /tmp\n        wget -q https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/gs10040/ghostscript-10.04.0.tar.gz\n        tar -xzf ghostscript-10.04.0.tar.gz\n        cd ghostscript-10.04.0\n        ./configure &>/dev/null\n        make &>/dev/null\n        sudo make install &>/dev/null\n        rm -rf /tmp/ghostscript*\n        msg_ok \"Ghostscript updated to 10.04.0\"\n      fi\n      msg_info \"Stopping all Paperless-ngx Services\"\n      systemctl stop paperless-consumer paperless-webserver paperless-scheduler paperless-task-queue.service\n      msg_ok \"Stopped all Paperless-ngx Services\"\n\n      msg_info \"Updating to ${RELEASE}\"\n      cd ~\n      wget -q https://github.com/paperless-ngx/paperless-ngx/releases/download/$RELEASE/paperless-ngx-$RELEASE.tar.xz\n      tar -xf paperless-ngx-$RELEASE.tar.xz\n      cp -r /opt/paperless/paperless.conf paperless-ngx/\n      cp -r paperless-ngx/* /opt/paperless/\n      cd /opt/paperless\n      pip install -r requirements.txt &>/dev/null\n      cd /opt/paperless/src\n      /usr/bin/python3 manage.py migrate &>/dev/null\n      echo \"${RELEASE}\" >/opt/${APP}_version.txt\n      msg_ok \"Updated to ${RELEASE}\"\n\n      msg_info \"Cleaning up\"\n      cd ~\n      rm paperless-ngx-$RELEASE.tar.xz\n      rm -rf paperless-ngx\n      msg_ok \"Cleaned\"\n\n      msg_info \"Starting all Paperless-ngx Services\"\n      systemctl start paperless-consumer paperless-webserver paperless-scheduler paperless-task-queue.service\n      sleep 1\n      msg_ok \"Started all Paperless-ngx Services\"\n      msg_ok \"Updated Successfully!\\n\"\n    else\n      msg_ok \"No update required. ${APP} is already at ${RELEASE}\"\n    fi\n    exit\n  fi\n  if [ \"$UPD\" == \"2\" ]; then\n    cat paperless.creds\n    exit\n  fi\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:8000${CL} \\n\"\n"
  },
  {
    "path": "ct/pbs.sh",
    "content": "#!/usr/bin/env bash\n\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ____                                          ____             __                  _____\n   / __ \\_________  _  ______ ___  ____  _  __   / __ )____ ______/ /____  ______     / ___/___  ______   _____  _____\n  / /_/ / ___/ __ \\| |/_/ __ `__ \\/ __ \\| |/_/  / __  / __ `/ ___/ //_/ / / / __ \\    \\__ \\/ _ \\/ ___/ | / / _ \\/ ___/\n / ____/ /  / /_/ />  </ / / / / / /_/ />  <   / /_/ / /_/ / /__/ ,< / /_/ / /_/ /   ___/ /  __/ /   | |/ /  __/ /\n/_/   /_/   \\____/_/|_/_/ /_/ /_/\\____/_/|_|  /_____/\\__,_/\\___/_/|_|\\__,_/ .___/   /____/\\___/_/    |___/\\___/_/\n                                                                         /_/\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"PBS\"\nvar_disk=\"10\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /var ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating $APP LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated $APP LXC\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:8007${CL} \\n\"\n"
  },
  {
    "path": "ct/peanut.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# Co-Author: remz1337\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ____             _   ____  ________\n   / __ \\___  ____ _/ | / / / / /_  __/\n  / /_/ / _ \\/ __ `/  |/ / / / / / /\n / ____/  __/ /_/ / /|  / /_/ / / /\n/_/    \\___/\\__,_/_/ |_/\\____/ /_/\n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"PeaNUT\"\nvar_disk=\"4\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\n  header_info\n  if [[ ! -f /etc/systemd/system/peanut.service ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\n  whiptail --backtitle \"Proxmox VE Helper Scripts\" --msgbox --title \"SET RESOURCES\" \"Please set the resources in your ${APP} LXC to ${var_cpu}vCPU and ${var_ram}RAM for the build process before continuing\" 10 75\n  RELEASE=$(curl -sL https://api.github.com/repos/Brandawg93/PeaNUT/releases/latest | grep '\"tag_name\":' | cut -d'\"' -f4)\n  if [[ ! -f /opt/${APP}_version.txt ]] || [[ \"${RELEASE}\" != \"$(cat /opt/${APP}_version.txt)\" ]]; then\n    msg_info \"Updating $APP to ${RELEASE}\"\n    systemctl stop peanut\n    wget -qO peanut.tar.gz https://api.github.com/repos/Brandawg93/PeaNUT/tarball/${RELEASE}\n    tar -xzf peanut.tar.gz -C /opt/peanut --strip-components 1\n    rm peanut.tar.gz\n    cd /opt/peanut\n    pnpm i &>/dev/null\n    pnpm run build &>/dev/null\n    cp -r .next/static .next/standalone/.next/\n    mkdir -p /opt/peanut/.next/standalone/config\n    ln -sf /etc/peanut/settings.yml /opt/peanut/.next/standalone/config/settings.yml\n    systemctl start peanut\n    echo \"${RELEASE}\" >/opt/${APP}_version.txt\n    msg_ok \"Updated $APP to ${RELEASE}\"\n  else\n    msg_ok \"No update required. ${APP} is already at ${RELEASE}\"\n  fi\n  exit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_info \"Setting Container to Normal Resources\"\npct set $CTID -memory 1024\npct set $CTID -cores 1\nmsg_ok \"Set Container to Normal Resources\"\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:3000${CL} \\n\"\n"
  },
  {
    "path": "ct/petio.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ____       __  _     \n   / __ \\___  / /_(_)___ \n  / /_/ / _ \\/ __/ / __ \\\n / ____/  __/ /_/ / /_/ /\n/_/    \\___/\\__/_/\\____/ \n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Petio\"\nvar_disk=\"4\"\nvar_cpu=\"2\"\nvar_ram=\"1024\"\nvar_os=\"ubuntu\"\nvar_version=\"20.04\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/Petio ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating $APP\"\nsystemctl stop petio.service\nwget https://petio.tv/releases/latest -O petio-latest.zip\nunzip petio-latest.zip -d /opt/Petio\nsystemctl start petio.service\nmsg_ok \"Updated $APP\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:7777${CL} \\n\"\n"
  },
  {
    "path": "ct/photoprism.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\n  clear\n  cat <<\"EOF\"\n    ____  __  ______  __________  ____  ____  _________ __  ___\n   / __ \\/ / / / __ \\/_  __/ __ \\/ __ \\/ __ \\/  _/ ___//  |/  /\n  / /_/ / /_/ / / / / / / / / / / /_/ / /_/ // / \\__ \\/ /|_/ / \n / ____/ __  / /_/ / / / / /_/ / ____/ _, _// / ___/ / /  / /  \n/_/   /_/ /_/\\____/ /_/  \\____/_/   /_/ |_/___//____/_/  /_/   \n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"PhotoPrism\"\nvar_disk=\"8\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\n  header_info\n  if [[ ! -d /opt/photoprism ]]; then\n    msg_error \"No ${APP} Installation Found!\"\n    exit\n  fi\n  echo -e \"\\n ⚠️  Ensure you set 2vCPU & 3072MiB RAM MIMIMUM!!! \\n\"\n  msg_info \"Stopping PhotoPrism\"\n  sudo systemctl stop photoprism\n  msg_ok \"Stopped PhotoPrism\"\n\n  msg_info \"Updating PhotoPrism\"\n  apt-get install -y libvips42 &>/dev/null\n  wget -q -cO - https://dl.photoprism.app/pkg/linux/amd64.tar.gz | tar -xzf - -C /opt/photoprism --strip-components=1\n  msg_ok \"Updated PhotoPrism\"\n\n  msg_info \"Starting PhotoPrism\"\n  sudo systemctl start photoprism\n  msg_ok \"Started PhotoPrism\"\n  msg_ok \"Update Successful\"\n  exit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:2342${CL} \\n\"\n"
  },
  {
    "path": "ct/pialert.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ____  _   ___    __          __\n   / __ \\(_) /   |  / /__  _____/ /_\n  / /_/ / / / /| | / / _ \\/ ___/ __/\n / ____/ / / ___ |/ /  __/ /  / /_\n/_/   /_(_)_/  |_/_/\\___/_/   \\__/\n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"PiAlert\"\nvar_disk=\"3\"\nvar_cpu=\"1\"\nvar_ram=\"512\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/pialert ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nbash -c \"$(wget -qLO - https://github.com/leiweibau/Pi.Alert/raw/main/install/pialert_update.sh)\" -s --lxc\nmsg_ok \"Updated $APP\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}/pialert/${CL} \\n\"\n"
  },
  {
    "path": "ct/pihole.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ____  ____   __  ______  __    ______\n   / __ \\/  _/  / / / / __ \\/ /   / ____/\n  / /_/ // /___/ /_/ / / / / /   / __/   \n / ____// /___/ __  / /_/ / /___/ /___   \n/_/   /___/  /_/ /_/\\____/_____/_____/   \n \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Pihole\"\nvar_disk=\"2\"\nvar_cpu=\"1\"\nvar_ram=\"512\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /etc/pihole ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating ${APP}\"\nset +e\npihole -up\nmsg_ok \"Updated ${APP}\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}/admin${CL} \\n\"\n"
  },
  {
    "path": "ct/pingvin.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ____  _                   _          _____ __                  \n   / __ \\(_)___  ____ __   __(_)___     / ___// /_  ____ _________\n  / /_/ / / __ \\/ __ `/ | / / / __ \\    \\__ \\/ __ \\/ __ `/ ___/ _ \\\n / ____/ / / / / /_/ /| |/ / / / / /   ___/ / / / / /_/ / /  /  __/\n/_/   /_/_/ /_/\\__, / |___/_/_/ /_/   /____/_/ /_/\\__,_/_/   \\___/\n              /____/\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Pingvin\"\nvar_disk=\"8\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/pingvin-share ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Stopping Pingvin Share\"\nsystemctl stop pm2-root.service\nmsg_ok \"Stopped Pingvin Share\"\n\nmsg_info \"Updating Pingvin Share\"\ncd /opt/pingvin-share\ngit fetch --tags\ngit checkout $(git describe --tags `git rev-list --tags --max-count=1`) &>/dev/null\ncd backend\nnpm install &>/dev/null\nnpm run build &>/dev/null\ncd ../frontend\nnpm install &>/dev/null\nnpm run build &>/dev/null\nmsg_ok \"Updated Pingvin Share\"\n\nmsg_info \"Starting Pingvin Share\"\nsystemctl start pm2-root.service\nmsg_ok \"Started Pingvin Share\"\n\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:3000 ${CL} \\n\"\n"
  },
  {
    "path": "ct/plex.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ____  __             __  ___         ___          _____                          \n   / __ \\/ /__  _  __   /  |/  /__  ____/ (_)___ _   / ___/___  ______   _____  _____\n  / /_/ / / _ \\| |/_/  / /|_/ / _ \\/ __  / / __ `/   \\__ \\/ _ \\/ ___/ | / / _ \\/ ___/\n / ____/ /  __/>  <   / /  / /  __/ /_/ / / /_/ /   ___/ /  __/ /   | |/ /  __/ /    \n/_/   /_/\\___/_/|_|  /_/  /_/\\___/\\__,_/_/\\__,_/   /____/\\___/_/    |___/\\___/_/     \n                                                                                      \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Plex\"\nvar_disk=\"8\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"ubuntu\"\nvar_version=\"22.04\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nif [[ ! -f /etc/apt/sources.list.d/plexmediaserver.list ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nUPD=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"SUPPORT\" --radiolist --cancel-button Exit-Script \"Spacebar = Select \\nplexupdate info >> https://github.com/mrworf/plexupdate\" 10 59 2 \\\n  \"1\" \"Update LXC\" ON \\\n  \"2\" \"Install plexupdate\" OFF \\\n  3>&1 1>&2 2>&3)\n\nheader_info\nif [ \"$UPD\" == \"1\" ]; then\nmsg_info \"Updating ${APP} LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated ${APP} LXC\"\nexit\nfi\nif [ \"$UPD\" == \"2\" ]; then\nset +e\nbash -c \"$(wget -qO - https://raw.githubusercontent.com/mrworf/plexupdate/master/extras/installer.sh)\"\nexit\nfi\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n             ${BL}http://${IP}:32400/web${CL}\\n\"\n"
  },
  {
    "path": "ct/pocketbase.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ____             __        __  __\n   / __ \\____  _____/ /_____  / /_/ /_  ____ _________\n  / /_/ / __ \\/ ___/ //_/ _ \\/ __/ __ \\/ __ `/ ___/ _ \\\n / ____/ /_/ / /__/ ,< /  __/ /_/ /_/ / /_/ (__  )  __/\n/_/    \\____/\\___/_/|_|\\___/\\__/_.___/\\__,_/____/\\___/\n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Pocketbase\"\nvar_disk=\"8\"\nvar_cpu=\"1\"\nvar_ram=\"512\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n             ${BL}http://${IP}:8080/_${CL}\"\n"
  },
  {
    "path": "ct/podman-homeassistant.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n                     ____            __                                      \n                    / __ \\____  ____/ /___ ___  ____ _____                   \n                   / /_/ / __ \\/ __  / __  __ \\/ __  / __ \\                  \n                  / ____/ /_/ / /_/ / / / / / / /_/ / / / /                  \n    __  __       /_/    \\____/\\__,_/_/ /_/ /_/\\__,_/_/ /_/__              __ \n   / / / /___  ____ ___  ___     /   |  __________(_)____/ /_____ _____  / /_\n  / /_/ / __ \\/ __  __ \\/ _ \\   / /| | / ___/ ___/ / ___/ __/ __  / __ \\/ __/\n / __  / /_/ / / / / / /  __/  / ___ |(__  |__  ) (__  ) /_/ /_/ / / / / /_  \n/_/ /_/\\____/_/ /_/ /_/\\___/  /_/  |_/____/____/_/____/\\__/\\__,_/_/ /_/\\__/  \n \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Podman-Home Assistant\"\nvar_disk=\"16\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\n  if [[ ! -f /etc/systemd/system/homeassistant.service ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\n  UPD=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"UPDATE\" --radiolist --cancel-button Exit-Script \"Spacebar = Select\" 11 58 4 \\\n  \"1\" \"Update system and containers\" ON \\\n  \"2\" \"Install HACS\" OFF \\\n  \"3\" \"Install FileBrowser\" OFF \\\n  \"4\" \"Remove ALL Unused Images\" OFF \\\n  3>&1 1>&2 2>&3)\nheader_info\nif [ \"$UPD\" == \"1\" ]; then\n  msg_info \"Updating ${APP} LXC\"\n  apt-get update &>/dev/null\n  apt-get -y upgrade &>/dev/null\n  msg_ok \"Updated Successfully\"\n\n  msg_info \"Updating All Containers\\n\"\n  CONTAINER_LIST=\"${1:-$(podman ps -q)}\"\n  for container in ${CONTAINER_LIST}; do\n    CONTAINER_IMAGE=\"$(podman inspect --format \"{{.Config.Image}}\" --type container ${container})\"\n    RUNNING_IMAGE=\"$(podman inspect --format \"{{.Image}}\" --type container \"${container}\")\"\n    podman pull \"${CONTAINER_IMAGE}\"\n    LATEST_IMAGE=\"$(podman inspect --format \"{{.Id}}\" --type image \"${CONTAINER_IMAGE}\")\"\n    if [[ \"${RUNNING_IMAGE}\" != \"${LATEST_IMAGE}\" ]]; then\n      echo \"Updating ${container} image ${CONTAINER_IMAGE}\"\n      systemctl restart homeassistant\n    fi\n  done\n  msg_ok \"All containers updated.\"\n  exit\nfi\nif [ \"$UPD\" == \"2\" ]; then\n  msg_info \"Installing Home Assistant Community Store (HACS)\"\n  apt update &>/dev/null\n  apt install unzip &>/dev/null\n  cd /var/lib/containers/storage/volumes/hass_config/_data\n  bash <(curl -fsSL https://get.hacs.xyz) &>/dev/null\n  msg_ok \"Installed Home Assistant Community Store (HACS)\"\n  echo -e \"\\n Reboot Home Assistant and clear browser cache then Add HACS integration.\\n\"\n  exit\nfi\nif [ \"$UPD\" == \"3\" ]; then\n  IP=$(hostname -I | awk '{print $1}') \n  msg_info \"Installing FileBrowser\"\n  curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bash &>/dev/null\n  filebrowser config init -a '0.0.0.0' &>/dev/null\n  filebrowser config set -a '0.0.0.0' &>/dev/null\n  filebrowser users add admin helper-scripts.com --perm.admin &>/dev/null\n  msg_ok \"Installed FileBrowser\"\n\n  msg_info \"Creating Service\"\n  service_path=\"/etc/systemd/system/filebrowser.service\"\n  echo \"[Unit]\n  Description=Filebrowser\n  After=network-online.target\n  [Service]\n    User=root\n    WorkingDirectory=/root/\n    ExecStart=/usr/local/bin/filebrowser -r /\n  [Install]\n    WantedBy=default.target\" >$service_path\n\n    systemctl enable --now filebrowser.service &>/dev/null\n    msg_ok \"Created Service\"\n\n    msg_ok \"Completed Successfully!\\n\"\n    echo -e \"FileBrowser should be reachable by going to the following URL.\n         ${BL}http://$IP:8080${CL}   admin|helper-scripts.com\\n\"\n  exit\nfi\nif [ \"$UPD\" == \"4\" ]; then\n  msg_info \"Removing ALL Unused Images\"\n  podman image prune -a -f\n  msg_ok \"Removed ALL Unused Images\"\n  exit\nfi\n\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:8123${CL} \\n\"\n"
  },
  {
    "path": "ct/podman.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ____            __                    \n   / __ \\____  ____/ /___ ___  ____ _____ \n  / /_/ / __ \\/ __  / __ `__ \\/ __ `/ __ \\\n / ____/ /_/ / /_/ / / / / / / /_/ / / / /\n/_/    \\____/\\__,_/_/ /_/ /_/\\__,_/_/ /_/ \n                                          \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Podman\"\nvar_disk=\"4\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -f /etc/containers/registries.conf ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating ${APP} LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\n"
  },
  {
    "path": "ct/postgresql.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ____             __                 _____ ____    __ \n   / __ \\____  _____/ /_____ _________ / ___// __ \\  / / \n  / /_/ / __ \\/ ___/ __/ __  / ___/ _ \\\\__ \\/ / / / / /  \n / ____/ /_/ (__  ) /_/ /_/ / /  /  __/__/ / /_/ / / /___\n/_/    \\____/____/\\__/\\__, /_/   \\___/____/\\___\\_\\/_____/\n                     /____/                              \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"PostgreSQL\"\nvar_disk=\"4\"\nvar_cpu=\"1\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -f /etc/apt/sources.list.d/pgdg.list ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating ${APP} LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\n"
  },
  {
    "path": "ct/prometheus.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ____                            __  __                   \n   / __ \\_________  ____ ___  ___  / /_/ /_  ___  __  _______\n  / /_/ / ___/ __ \\/ __  __ \\/ _ \\/ __/ __ \\/ _ \\/ / / / ___/\n / ____/ /  / /_/ / / / / / /  __/ /_/ / / /  __/ /_/ (__  ) \n/_/   /_/   \\____/_/ /_/ /_/\\___/\\__/_/ /_/\\___/\\__,_/____/  \n \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Prometheus\"\nvar_disk=\"4\"\nvar_cpu=\"1\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -f /etc/systemd/system/prometheus.service ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nRELEASE=$(curl -s https://api.github.com/repos/prometheus/prometheus/releases/latest | grep \"tag_name\" | awk '{print substr($2, 3, length($2)-4) }')\nif [[ ! -f /opt/${APP}_version.txt ]] || [[ \"${RELEASE}\" != \"$(cat /opt/${APP}_version.txt)\" ]]; then\n  msg_info \"Stopping ${APP}\"\n  systemctl stop prometheus\n  msg_ok \"Stopped ${APP}\"\n  \n  msg_info \"Updating ${APP} to ${RELEASE}\"\n  wget -q https://github.com/prometheus/prometheus/releases/download/v${RELEASE}/prometheus-${RELEASE}.linux-amd64.tar.gz\n  tar -xf prometheus-${RELEASE}.linux-amd64.tar.gz\n  cd prometheus-${RELEASE}.linux-amd64\n  cp -rf prometheus promtool /usr/local/bin/\n  cp -rf consoles/ console_libraries/ /etc/prometheus/\n  cd ~\n  rm -rf prometheus-${RELEASE}.linux-amd64 prometheus-${RELEASE}.linux-amd64.tar.gz\n  echo \"${RELEASE}\" >/opt/${APP}_version.txt\n  msg_ok \"Updated ${APP} to ${RELEASE}\"\n\n  msg_info \"Starting ${APP}\"\n  systemctl start prometheus\n  msg_ok \"Started ${APP}\"\n  msg_ok \"Updated Successfully\"\nelse\n  msg_ok \"No update required. ${APP} is already at ${RELEASE}\"\nfi\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:9090${CL} \\n\"\n"
  },
  {
    "path": "ct/prowlarr.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ____                     __               \n   / __ \\_________ _      __/ /___  __________\n  / /_/ / ___/ __ \\ | /| / / / __ `/ ___/ ___/\n / ____/ /  / /_/ / |/ |/ / / /_/ / /  / /    \n/_/   /_/   \\____/|__/|__/_/\\__,_/_/  /_/     \n                                              \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Prowlarr\"\nvar_disk=\"4\"\nvar_cpu=\"2\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /var/lib/prowlarr/ ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_error \"There is currently no update path available.\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:9696${CL} \\n\"\n"
  },
  {
    "path": "ct/qbittorrent.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n         ____  _ __  __                             __ \n  ____ _/ __ )(_) /_/ /_____  _____________  ____  / /_\n / __ `/ __  / / __/ __/ __ \\/ ___/ ___/ _ \\/ __ \\/ __/\n/ /_/ / /_/ / / /_/ /_/ /_/ / /  / /  /  __/ / / / /_  \n\\__, /_____/_/\\__/\\__/\\____/_/  /_/   \\___/_/ /_/\\__/  \n  /_/                                                  \n \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"qBittorrent\"\nvar_disk=\"8\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -f /etc/systemd/system/qbittorrent-nox.service ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating ${APP} LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated ${APP} LXC\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:8090${CL}\\n\"\n"
  },
  {
    "path": "ct/rabbitmq.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck\n# Co-Author: MickLesk (Canbiz)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ____        __    __    _ __  __  _______ \n   / __ \\____ _/ /_  / /_  (_) /_/  |/  / __ \\\n  / /_/ / __ `/ __ \\/ __ \\/ / __/ /|_/ / / / /\n / _, _/ /_/ / /_/ / /_/ / / /_/ /  / / /_/ / \n/_/ |_|\\__,_/_.___/_.___/_/\\__/_/  /_/\\___\\_\\ \n                                              \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"RabbitMQ\"\nvar_disk=\"4\"\nvar_cpu=\"1\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\n\nfunction update_script() {\nheader_info\nif [[ ! -d /etc/rabbitmq ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nif (( $(df /boot | awk 'NR==2{gsub(\"%\",\"\",$5); print $5}') > 80 )); then\n  read -r -p \"Warning: Storage is dangerously low, continue anyway? <y/N> \" prompt\n  [[ ${prompt,,} =~ ^(y|yes)$ ]] || exit\nfi\nmsg_info \"Stopping ${APP} Service\"\nsystemctl stop rabbitmq-server\nmsg_ok \"Stopped ${APP} Service\"\n\nmsg_info \"Updating...\"\napt install --only-upgrade rabbitmq-server &>/dev/null\nmsg_ok \"Update Successfully\"\n\nmsg_info \"Starting ${APP}\"\nsystemctl start rabbitmq-server\nmsg_ok \"Started ${APP}\"\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} Setup should be reachable by going to the following URL.\n         ${BL}http://${IP}:15672${CL} \\n\"\n"
  },
  {
    "path": "ct/radarr.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ____            __               \n   / __ \\____ _____/ /___  __________\n  / /_/ / __ `/ __  / __ `/ ___/ ___/\n / _, _/ /_/ / /_/ / /_/ / /  / /    \n/_/ |_|\\__,_/\\__,_/\\__,_/_/  /_/     \n                                     \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Radarr\"\nvar_disk=\"4\"\nvar_cpu=\"2\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /var/lib/radarr/ ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_error \"There is currently no update path available.\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:7878${CL} \\n\"\n"
  },
  {
    "path": "ct/rdtclient.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ____             __    ____       __         _     __   ______                           __     _________            __\n   / __ \\___  ____  / /   / __ \\___  / /_  _____(_)___/ /  /_  __/___  _____________  ____  / /_   / ____/ (_)__  ____  / /_\n  / /_/ / _ \\/ __ `/ /___/ / / / _ \\/ __ \\/ ___/ / __  /    / / / __ \\/ ___/ ___/ _ \\/ __ \\/ __/  / /   / / / _ \\/ __ \\/ __/\n / _, _/  __/ /_/ / /___/ /_/ /  __/ /_/ / /  / / /_/ /    / / / /_/ / /  / /  /  __/ / / / /_   / /___/ / /  __/ / / / /_\n/_/ |_|\\___/\\__,_/_/   /_____/\\___/_.___/_/  /_/\\__,_/    /_/  \\____/_/  /_/   \\___/_/ /_/\\__/   \\____/_/_/\\___/_/ /_/\\__/\n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"RDTClient\"\nvar_disk=\"4\"\nvar_cpu=\"1\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/rdtc/ ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating $APP\"\nsystemctl stop rdtc\nmkdir -p rdtc-backup\ncp -R /opt/rdtc/appsettings.json rdtc-backup/\nwget -q https://github.com/rogerfar/rdt-client/releases/latest/download/RealDebridClient.zip\nunzip -oqq RealDebridClient.zip -d /opt/rdtc\ncp -R rdtc-backup/appsettings.json /opt/rdtc/\nrm -rf rdtc-backup RealDebridClient.zip\nsystemctl start rdtc\nmsg_ok \"Updated $APP\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:6500${CL} \\n\"\n"
  },
  {
    "path": "ct/readarr.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ____                 __               \n   / __ \\___  ____ _____/ /___  __________\n  / /_/ / _ \\/ __ `/ __  / __ `/ ___/ ___/\n / _, _/  __/ /_/ / /_/ / /_/ / /  / /    \n/_/ |_|\\___/\\__,_/\\__,_/\\__,_/_/  /_/     \n                                          \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Readarr\"\nvar_disk=\"4\"\nvar_cpu=\"2\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /var/lib/readarr/ ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating $APP LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated $APP LXC\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:8787${CL} \\n\"\n"
  },
  {
    "path": "ct/readeck.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ____                 __          __\n   / __ \\___  ____ _____/ /__  _____/ /__\n  / /_/ / _ \\/ __ `/ __  / _ \\/ ___/ //_/\n / _, _/  __/ /_/ / /_/ /  __/ /__/ ,<\n/_/ |_|\\___/\\__,_/\\__,_/\\___/\\___/_/|_|\n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Readeck\"\nvar_disk=\"2\"\nvar_cpu=\"1\"\nvar_ram=\"512\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/readeck ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating ${APP}\"\nLATEST=$(curl -s https://codeberg.org/readeck/readeck/releases/ | grep -oP '(?<=Version )\\d+\\.\\d+\\.\\d+' | head -1)\nsystemctl stop readeck.service\nrm -rf /opt/readeck/readeck\ncd /opt/readeck\nwget -q -O readeck https://codeberg.org/readeck/readeck/releases/download/${LATEST}/readeck-${LATEST}-linux-amd64\nchmod a+x readeck\nsystemctl start readeck.service\nmsg_ok \"Updated ${APP}\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n             ${BL}http://${IP}:8000${CL}\\n\"\n"
  },
  {
    "path": "ct/redis.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ____           ___     \n   / __ \\___  ____/ (_)____\n  / /_/ / _ \\/ __  / / ___/\n / _, _/  __/ /_/ / (__  ) \n/_/ |_|\\___/\\__,_/_/____/  \n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Redis\"\nvar_disk=\"4\"\nvar_cpu=\"1\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nVERBOSE=\"yes\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -f /lib/systemd/system/redis-server.service ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_error \"There is currently no update path available.\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\n"
  },
  {
    "path": "ct/rockylinux.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ____             __            __    _                 \n   / __ \\____  _____/ /____  __   / /   (_)___  __  ___  __\n  / /_/ / __ \\/ ___/ //_/ / / /  / /   / / __ \\/ / / / |/_/\n / _, _/ /_/ / /__/ ,< / /_/ /  / /___/ / / / / /_/ />  <  \n/_/ |_|\\____/\\___/_/|_|\\__, /  /_____/_/_/ /_/\\__,_/_/|_|  \n                      /____/                               \n \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Rocky Linux\"\nvar_disk=\"1\"\nvar_cpu=\"1\"\nvar_ram=\"512\"\nvar_os=\"rockylinux\"\nvar_version=\"9\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"-password rockylinux\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /etc/pacman.d ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating ${APP} LXC\"\ndnf -y update\ndnf -y upgrade\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\n"
  },
  {
    "path": "ct/rtsptoweb.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ____  ___________ ____  __      _       __     __ \n   / __ \\/_  __/ ___// __ \\/ /_____| |     / /__  / /_ \n  / /_/ / / /  \\__ \\/ /_/ / __/ __ \\ | /| / / _ \\/ __ \\\n / _, _/ / /  ___/ / ____/ /_/ /_/ / |/ |/ /  __/ /_/ /\n/_/ |_| /_/  /____/_/    \\__/\\____/|__/|__/\\___/_.___/ \n                                                     \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"RTSPtoWeb\"\nvar_disk=\"4\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /var ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating $APP LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated $APP LXC\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} Setup should be reachable by going to the following URL.\n         ${BL}http://${IP}:8083 ${CL} \\n\"\n"
  },
  {
    "path": "ct/runtipi.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    ____              __  _       _\n   / __ \\__  ______  / /_(_)___  (_)\n  / /_/ / / / / __ \\/ __/ / __ \\/ /\n / _, _/ /_/ / / / / /_/ / /_/ / /\n/_/ |_|\\__,_/_/ /_/\\__/_/ .___/_/\n                       /_/\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Runtipi\"\nvar_disk=\"8\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/runtipi ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\ncd /opt/runtipi && ./runtipi-cli update latest\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP} ${CL} \\n\"\n"
  },
  {
    "path": "ct/sabnzbd.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n   _____ ___    ____              __        __\n  / ___//   |  / __ )____  ____  / /_  ____/ /\n  \\__ \\/ /| | / __  / __ \\/_  / / __ \\/ __  / \n ___/ / ___ |/ /_/ / / / / / /_/ /_/ / /_/ /  \n/____/_/  |_/_____/_/ /_/ /___/_.___/\\__,_/   \n                                              \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"SABnzbd\"\nvar_disk=\"8\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/sabnzbd ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nRELEASE=$(curl -s https://api.github.com/repos/sabnzbd/sabnzbd/releases/latest | grep \"tag_name\" | awk '{print substr($2, 2, length($2)-3) }')\nif [[ ! -f /opt/${APP}_version.txt ]] || [[ \"${RELEASE}\" != \"$(cat /opt/${APP}_version.txt)\" ]]; then\n   msg_info \"Updating $APP to ${RELEASE}\"\n   systemctl stop sabnzbd.service\n   tar zxvf <(curl -fsSL https://github.com/sabnzbd/sabnzbd/releases/download/$RELEASE/SABnzbd-${RELEASE}-src.tar.gz) &>/dev/null\n   \\cp -r SABnzbd-${RELEASE}/* /opt/sabnzbd &>/dev/null\n   rm -rf SABnzbd-${RELEASE}\n   cd /opt/sabnzbd\n   python3 -m pip install -r requirements.txt &>/dev/null\n   echo \"${RELEASE}\" >/opt/${APP}_version.txt\n   systemctl start sabnzbd.service\n   msg_ok \"Updated ${APP} to ${RELEASE}\"\nelse\n   msg_info \"No update required. ${APP} is already at ${RELEASE}\"\nfi\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:7777${CL} \\n\"\n"
  },
  {
    "path": "ct/scrypted.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n   _____                       __           __\n  / ___/____________  ______  / /____  ____/ /\n  \\__ \\/ ___/ ___/ / / / __ \\/ __/ _ \\/ __  / \n ___/ / /__/ /  / /_/ / /_/ / /_/  __/ /_/ /  \n/____/\\___/_/   \\__, / .___/\\__/\\___/\\__,_/   \n               /____/_/                       \n \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Scrypted\"\nvar_disk=\"8\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -f /etc/systemd/system/scrypted.service ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating ${APP} LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}https://${IP}:10443${CL} \\n\"\n"
  },
  {
    "path": "ct/sftpgo.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n   _____ ________________  ______\n  / ___// ____/_  __/ __ \\/ ____/___\n  \\__ \\/ /_    / / / /_/ / / __/ __ \\\n ___/ / __/   / / / ____/ /_/ / /_/ /\n/____/_/     /_/ /_/    \\____/\\____/\n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"SFTPGo\"\nvar_disk=\"4\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /var ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating $APP LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated $APP LXC\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:8080/web/admin ${CL} \\n\"\n"
  },
  {
    "path": "ct/shinobi.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n   _____ __    _             __    _ \n  / ___// /_  (_)___  ____  / /_  (_)\n  \\__ \\/ __ \\/ / __ \\/ __ \\/ __ \\/ / \n ___/ / / / / / / / / /_/ / /_/ / /  \n/____/_/ /_/_/_/ /_/\\____/_.___/_/   \n                                     \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Shinobi\"\nvar_disk=\"8\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"ubuntu\"\nvar_version=\"22.04\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"0\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/Shinobi ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating Shinobi LXC\"\ncd /opt/Shinobi\nsh UPDATE.sh\npm2 flush\npm2 restart camera\npm2 restart cron\nmsg_ok \"Updated Shinobi LXC\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} Setup should be reachable by going to the following URL.\n         ${BL}http://${IP}:8080/super${CL} \\n\"\n"
  },
  {
    "path": "ct/smokeping.sh",
    "content": "#!/usr/bin/env bash\n\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n   _____                 __        ____  _\n  / ___/____ ___  ____  / /_____  / __ \\(_)___  ____ _\n  \\__ \\/ __ `__ \\/ __ \\/ //_/ _ \\/ /_/ / / __ \\/ __ `/\n ___/ / / / / / / /_/ / ,< /  __/ ____/ / / / / /_/ /\n/____/_/ /_/ /_/\\____/_/|_|\\___/_/   /_/_/ /_/\\__, /\n                                             /____/\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"SmokePing\"\nvar_disk=\"2\"\nvar_cpu=\"1\"\nvar_ram=\"512\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif ! command -v smokeping &> /dev/null; then msg_error \"No ${APP} Installation Found!\"; exit; fi\n\nmsg_info \"Updating ${APP}\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}/smokeping${CL} \\n\"\n"
  },
  {
    "path": "ct/sonarr.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n   _____\n  / ___/____  ____  ____  __________\n  \\__ \\/ __ \\/ __ \\/ __ `/ ___/ ___/\n ___/ / /_/ / / / / /_/ / /  / /\n/____/\\____/_/ /_/\\__,_/_/  /_/\n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Sonarr\"\nvar_disk=\"4\"\nvar_cpu=\"2\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/Sonarr ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating $APP v4\"\nsystemctl stop sonarr.service\nwget -q -O SonarrV4.tar.gz 'https://services.sonarr.tv/v1/download/main/latest?version=4&os=linux&arch=x64'\ntar -xzf SonarrV4.tar.gz\nrm -rf /opt/Sonarr\nmv Sonarr /opt\nrm -rf SonarrV4.tar.gz\nsystemctl start sonarr.service\nmsg_ok \"Updated $APP v4\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:8989${CL} \\n\"\n"
  },
  {
    "path": "ct/spoolman.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck\n# Co-Author: MickLesk (Canbiz)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n   _____                   __                    \n  / ___/____  ____  ____  / /___ ___  ____ _____ \n  \\__ \\/ __ \\/ __ \\/ __ \\/ / __ `__ \\/ __ `/ __ \\\n ___/ / /_/ / /_/ / /_/ / / / / / / / /_/ / / / /\n/____/ .___/\\____/\\____/_/_/ /_/ /_/\\__,_/_/ /_/ \n    /_/                                                         \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Spoolman\"\nvar_disk=\"4\"\nvar_cpu=\"1\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/spoolman ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nif (( $(df /boot | awk 'NR==2{gsub(\"%\",\"\",$5); print $5}') > 80 )); then\n  read -r -p \"Warning: Storage is dangerously low, continue anyway? <y/N> \" prompt\n  [[ ${prompt,,} =~ ^(y|yes)$ ]] || exit\nfi\nRELEASE=$(wget -q https://github.com/Donkie/Spoolman/releases/latest -O - | grep \"title>Release\" | cut -d \" \" -f 4)\nif [[ ! -f /opt/${APP}_version.txt ]] || [[ \"${RELEASE}\" != \"$(cat /opt/${APP}_version.txt)\" ]]; then\n\n  msg_info \"Stopping ${APP} Service\"\n  systemctl stop spoolman\n  msg_ok \"Stopped ${APP} Service\"\n\n  msg_info \"Updating ${APP} to ${RELEASE}\"\n  cd /opt\n  rm -rf spoolman_bak\n  mv spoolman spoolman_bak\n  wget -q https://github.com/Donkie/Spoolman/releases/download/${RELEASE}/spoolman.zip \n  unzip -q spoolman.zip -d spoolman\n  cd spoolman\n  pip3 install -r requirements.txt >/dev/null 2>&1\n  wget -q https://raw.githubusercontent.com/Donkie/Spoolman/master/.env.example -O .env\n  echo \"${RELEASE}\" >/opt/${APP}_version.txt\n  msg_ok \"Updated ${APP} to ${RELEASE}\"\n\n  msg_info \"Starting ${APP} Service\"\n  systemctl start spoolman\n  msg_ok \"Started ${APP} Service\"\n\n  msg_info \"Cleaning up\"\n  rm -rf /opt/spoolman.zip\n  msg_ok \"Cleaned\"\n\n  msg_ok \"Updated Successfully!\\n\"\nelse\n  msg_ok \"No update required. ${APP} is already at ${RELEASE}\"\nfi\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} Setup should be reachable by going to the following URL.\n         ${BL}http://${IP}:7912${CL} \\n\"\n"
  },
  {
    "path": "ct/stirling-pdf.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n   _____ __  _      ___                 ____  ____  ______\n  / ___// /_(_)____/ (_)___  ____ _    / __ \\/ __ \\/ ____/\n  \\__ \\/ __/ / ___/ / / __ \\/ __ `/___/ /_/ / / / / /_\n ___/ / /_/ / /  / / / / / / /_/ /___/ ____/ /_/ / __/\n/____/\\__/_/_/  /_/_/_/ /_/\\__, /   /_/   /_____/_/\n                          /____/\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Stirling-PDF\"\nvar_disk=\"8\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/Stirling-PDF ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating ${APP}\"\nsystemctl stop stirlingpdf\nRELEASE=$(curl -s https://api.github.com/repos/Stirling-Tools/Stirling-PDF/releases/latest | grep \"tag_name\" | awk '{print substr($2, 3, length($2)-4) }')\nwget -q https://github.com/Stirling-Tools/Stirling-PDF/archive/refs/tags/v$RELEASE.tar.gz\ntar -xzf v$RELEASE.tar.gz\ncd Stirling-PDF-$RELEASE\nchmod +x ./gradlew\n./gradlew build &>/dev/null\ncp -r ./build/libs/Stirling-PDF-*.jar /opt/Stirling-PDF/\ncp -r scripts /opt/Stirling-PDF/\ncd ~\nrm -rf Stirling-PDF-$RELEASE v$RELEASE.tar.gz\nln -sf /opt/Stirling-PDF/Stirling-PDF-$RELEASE.jar /opt/Stirling-PDF/Stirling-PDF.jar\nsystemctl start stirlingpdf\nmsg_ok \"Updated ${APP} to v$RELEASE\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:8080 ${CL} \\n\"\n"
  },
  {
    "path": "ct/syncthing.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n   _____                  __  __    _            \n  / ___/__  ______  _____/ /_/ /_  (_)___  ____ _\n  \\__ \\/ / / / __ \\/ ___/ __/ __ \\/ / __ \\/ __ `/\n ___/ / /_/ / / / / /__/ /_/ / / / / / / / /_/ / \n/____/\\__, /_/ /_/\\___/\\__/_/ /_/_/_/ /_/\\__, /  \n     /____/                             /____/   \n                                     \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Syncthing\"\nvar_disk=\"8\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -f /etc/apt/sources.list.d/syncthing.list ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating ${APP} LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:8384 ${CL} \\n\"\n"
  },
  {
    "path": "ct/tandoor.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck\n# Co-Author: MickLesk (Canbiz)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n  ______                __                    ____            _\n /_  __/___ _____  ____/ /___  ____  _____   / __ \\___  _____(_)___  ___  _____\n  / / / __ `/ __ \\/ __  / __ \\/ __ \\/ ___/  / /_/ / _ \\/ ___/ / __ \\/ _ \\/ ___/\n / / / /_/ / / / / /_/ / /_/ / /_/ / /     / _, _/  __/ /__/ / /_/ /  __(__  )\n/_/  \\__,_/_/ /_/\\__,_/\\____/\\____/_/     /_/ |_|\\___/\\___/_/ .___/\\___/____/\n                                                           /_/\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Tandoor\"\nvar_disk=\"10\"\nvar_cpu=\"4\"\nvar_ram=\"4096\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\n  header_info\n  if [[ ! -d /opt/tandoor ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi \n  if cd /opt/tandoor && git pull | grep -q 'Already up to date'; then\n    msg_ok \"There is currently no update available.\"\n  else\n    msg_info \"Updating ${APP} (Patience)\"\n    export $(cat /opt/tandoor/.env | grep \"^[^#]\" | xargs)\n    cd /opt/tandoor/\n    pip3 install -r requirements.txt >/dev/null 2>&1\n    /usr/bin/python3 /opt/tandoor/manage.py migrate >/dev/null 2>&1\n    /usr/bin/python3 /opt/tandoor/manage.py collectstatic --no-input >/dev/null 2>&1\n    /usr/bin/python3 /opt/tandoor/manage.py collectstatic_js_reverse >/dev/null 2>&1\n    cd /opt/tandoor/vue\n    yarn install >/dev/null 2>&1\n    yarn build >/dev/null 2>&1\n    systemctl restart gunicorn_tandoor\n    msg_ok \"Updated ${APP}\"\n  fi\n  exit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_info \"Setting Container to Normal Resources\"\npct set $CTID -memory 2048\npct set $CTID -cores 2\nmsg_ok \"Set Container to Normal Resources\"\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} Setup should be reachable by going to the following URL.\n         ${BL}http://${IP}:8002${CL} \\n\"\n"
  },
  {
    "path": "ct/tasmoadmin.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n  ______                           ___       __          _ \n /_  __/___ __________ ___  ____  /   | ____/ /___ ___  (_)___\n  / / / __ `/ ___/ __ `__ \\/ __ \\/ /| |/ __  / __ `__ \\/ / __ \\\n / / / /_/ (__  ) / / / / / /_/ / ___ / /_/ / / / / / / / / / /\n/_/  \\__,_/____/_/ /_/ /_/\\____/_/  |_\\__,_/_/ /_/ /_/_/_/ /_/\n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"TasmoAdmin\"\nvar_disk=\"2\"\nvar_cpu=\"1\"\nvar_ram=\"512\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /var ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating $APP LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated $APP LXC\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:9999${CL} \\n\"\n"
  },
  {
    "path": "ct/tautulli.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n  ______            __        _____\n /_  __/___ ___  __/ /___  __/ / (_)\n  / / / __ `/ / / / __/ / / / / / / \n / / / /_/ / /_/ / /_/ /_/ / / / / \n/_/  \\__,_/\\__,_/\\__/\\__,_/_/_/_/ \n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Tautulli\"\nvar_disk=\"4\"\nvar_cpu=\"2\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/Tautulli/ ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating $APP LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated $APP LXC\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:8181${CL} \\n\"\n"
  },
  {
    "path": "ct/tdarr.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n  ______    __               \n /_  __/___/ /___  __________\n  / / / __  / __ `/ ___/ ___/\n / / / /_/ / /_/ / /  / /    \n/_/  \\__,_/\\__,_/_/  /_/     \n                             \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Tdarr\"\nvar_disk=\"4\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/tdarr ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating $APP LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated $APP LXC\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:8265${CL} \\n\"\n"
  },
  {
    "path": "ct/technitiumdns.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n  ______          __          _ __  _                    ____  _   _______\n /_  __/__  _____/ /_  ____  (_) /_(_)_  ______ ___     / __ \\/ | / / ___/\n  / / / _ \\/ ___/ __ \\/ __ \\/ / __/ / / / / __  __ \\   / / / /  |/ /\\__ \\ \n / / /  __/ /__/ / / / / / / / /_/ / /_/ / / / / / /  / /_/ / /|  /___/ / \n/_/  \\___/\\___/_/ /_/_/ /_/_/\\__/_/\\__,_/_/ /_/ /_/  /_____/_/ |_//____/  \n \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Technitium DNS\"\nvar_disk=\"2\"\nvar_cpu=\"1\"\nvar_ram=\"512\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /etc/dns ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating ${APP}\"\n\nif ! dpkg -s aspnetcore-runtime-8.0 > /dev/null 2>&1; then\n    wget -q https://packages.microsoft.com/config/debian/12/packages-microsoft-prod.deb\n    dpkg -i packages-microsoft-prod.deb &>/dev/null\n    apt-get update &>/dev/null\n    apt-get install -y aspnetcore-runtime-8.0 &>/dev/null\n    rm packages-microsoft-prod.deb\nfi\nbash <(curl -fsSL https://download.technitium.com/dns/install.sh) &>/dev/null\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:5380${CL} \\n\"\n"
  },
  {
    "path": "ct/threadfin.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n  ________                        _______     \n /_  __/ /_  ________  ____ _____/ / __(_)___ \n  / / / __ \\/ ___/ _ \\/ __ `/ __  / /_/ / __ \\\n / / / / / / /  /  __/ /_/ / /_/ / __/ / / / /\n/_/ /_/ /_/_/   \\___/\\__,_/\\__,_/_/ /_/_/ /_/ \n                                              \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Threadfin\"\nvar_disk=\"4\"\nvar_cpu=\"1\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/threadfin ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating $APP\"\nsystemctl stop threadfin.service\nwget -q -O /opt/threadfin/threadfin 'https://github.com/Threadfin/Threadfin/releases/latest/download/Threadfin_linux_amd64'\nchmod +x /opt/threadfin/threadfin\nsystemctl start threadfin.service\nmsg_ok \"Updated $APP\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:34400/web${CL} \\n\"\n"
  },
  {
    "path": "ct/tianji.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck\n# Co-Author: MickLesk (Canbiz)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n  _______               _ _ \n /_  __(_)___ _____    (_|_)\n  / / / / __ `/ __ \\  / / / \n / / / / /_/ / / / / / / /  \n/_/ /_/\\__,_/_/ /_/_/ /_/   \n                 /___/      \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Tianji\"\nvar_disk=\"12\"\nvar_cpu=\"4\"\nvar_ram=\"4096\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/tianji ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nif (( $(df /boot | awk 'NR==2{gsub(\"%\",\"\",$5); print $5}') > 80 )); then\n  read -r -p \"Warning: Storage is dangerously low, continue anyway? <y/N> \" prompt\n  [[ ${prompt,,} =~ ^(y|yes)$ ]] || exit\nfi\nRELEASE=$(curl -s https://api.github.com/repos/msgbyte/tianji/releases/latest | grep \"tag_name\" | awk '{print substr($2, 3, length($2)-4) }')\nif [[ ! -f /opt/${APP}_version.txt ]] || [[ \"${RELEASE}\" != \"$(cat /opt/${APP}_version.txt)\" ]]; then\n  whiptail --backtitle \"Proxmox VE Helper Scripts\" --msgbox --title \"SET RESOURCES\" \"Please set the resources in your ${APP} LXC to ${var_cpu}vCPU and ${var_ram}RAM for the build process before continuing\" 10 75\n  msg_info \"Stopping ${APP} Service\"\n  systemctl stop tianji\n  msg_ok \"Stopped ${APP} Service\"\n  msg_info \"Updating ${APP} to ${RELEASE}\"\n  cd /opt\n  cp /opt/tianji/src/server/.env /opt/.env\n  mv /opt/tianji /opt/tianji_bak\n  wget -q \"https://github.com/msgbyte/tianji/archive/refs/tags/v${RELEASE}.zip\"\n  unzip -q v${RELEASE}.zip\n  mv tianji-${RELEASE} /opt/tianji\n  cd tianji\n  pnpm install --filter @tianji/client... --config.dedupe-peer-dependents=false --frozen-lockfile >/dev/null 2>&1\n  pnpm build:static >/dev/null 2>&1\n  pnpm install --filter @tianji/server... --config.dedupe-peer-dependents=false >/dev/null 2>&1\n  mkdir -p ./src/server/public >/dev/null 2>&1\n  cp -r ./geo ./src/server/public >/dev/null 2>&1\n  pnpm build:server >/dev/null 2>&1\n  mv /opt/.env /opt/tianji/src/server/.env \n  cd src/server\n  pnpm db:migrate:apply >/dev/null 2>&1\n  echo \"${RELEASE}\" >/opt/${APP}_version.txt\n  msg_ok \"Updated ${APP} to ${RELEASE}\"\n  msg_info \"Starting ${APP}\"\n  systemctl start tianji\n  msg_ok \"Started ${APP}\"\n  msg_info \"Cleaning up\"\n  rm -R /opt/v${RELEASE}.zip\n  rm -rf /opt/tianji_bak\n  rm -rf /opt/tianji/src/client\n  rm -rf /opt/tianji/website\n  rm -rf /opt/tianji/reporter\n  msg_ok \"Cleaned\"\n  msg_ok \"Updated Successfully\"\nelse\n  msg_ok \"No update required.  ${APP} is already at ${RELEASE}.\"\nfi\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_info \"Setting Container to Normal Resources\"\npct set $CTID -memory 1024\npct set $CTID -cores 1\nmsg_ok \"Set Container to Normal Resources\"\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} Setup should be reachable by going to the following URL.\n         ${BL}http://${IP}:12345${CL} \\n\"\n"
  },
  {
    "path": "ct/traccar.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n  ______\n /_  __/________ _______________ ______\n  / / / ___/ __ `/ ___/ ___/ __ `/ ___/\n / / / /  / /_/ / /__/ /__/ /_/ / /\n/_/ /_/   \\__,_/\\___/\\___/\\__,_/_/\n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Traccar\"\nvar_disk=\"2\"\nvar_cpu=\"1\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/traccar ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_error \"There is currently no update path available.\"\nexit\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:8082${CL} \\n\"\n"
  },
  {
    "path": "ct/traefik.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n  ______                _____ __  \n /_  __/________ ____  / __(_) /__\n  / / / ___/ __ `/ _ \\/ /_/ / //_/\n / / / /  / /_/ /  __/ __/ / ,<   \n/_/ /_/   \\__,_/\\___/_/ /_/_/|_|  \n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Traefik\"\nvar_disk=\"2\"\nvar_cpu=\"1\"\nvar_ram=\"512\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -f /etc/systemd/system/traefik.service ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nRELEASE=$(curl -s https://api.github.com/repos/traefik/traefik/releases | grep -oP '\"tag_name\":\\s*\"v\\K[\\d.]+?(?=\")' | sort -V | tail -n 1)\nmsg_info \"Updating $APP LXC\"\nif [[ \"${RELEASE}\" != \"$(cat /opt/${APP}_version.txt)\" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then\n  wget -q https://github.com/traefik/traefik/releases/download/v${RELEASE}/traefik_v${RELEASE}_linux_amd64.tar.gz\n  tar -C /tmp -xzf traefik*.tar.gz\n  mv /tmp/traefik /usr/bin/\n  rm -rf traefik*.tar.gz\n  systemctl restart traefik.service\n  msg_ok \"Updated $APP LXC\"\nelse\n  msg_ok \"No update required. ${APP} is already at ${RELEASE}\"\nfi\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:8080${CL} \\n\"\n"
  },
  {
    "path": "ct/transmission.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n  ______                                _           _           \n /_  __/________ _____  _________ ___  (_)_________(_)___  ____ \n  / / / ___/ __ `/ __ \\/ ___/ __ `__ \\/ / ___/ ___/ / __ \\/ __ \\\n / / / /  / /_/ / / / (__  ) / / / / / (__  |__  ) / /_/ / / / /\n/_/ /_/   \\__,_/_/ /_/____/_/ /_/ /_/_/____/____/_/\\____/_/ /_/ \n                                                                \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Transmission\"\nvar_disk=\"8\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -f /etc/transmission-daemon/settings.json ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating ${APP} LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated ${APP} LXC\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:9091/transmission${CL} \\n\"\n"
  },
  {
    "path": "ct/trilium.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n  ______     _ ___               \n /_  __/____(_) (_)_  ______ ___ \n  / / / ___/ / / / / / / __ `__ \\\n / / / /  / / / / /_/ / / / / / /\n/_/ /_/  /_/_/_/\\__,_/_/ /_/ /_/ \n                                                                      \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Trilium\"\nvar_disk=\"2\"\nvar_cpu=\"1\"\nvar_ram=\"512\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/trilium ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nRELEASE=$(curl -s https://api.github.com/repos/TriliumNext/Notes/releases/latest | grep \"tag_name\" | awk '{print substr($2, 2, length($2)-3) }')\n    \nmsg_info \"Stopping ${APP}\"\nsystemctl stop trilium.service\nsleep 1\nmsg_ok \"Stopped ${APP}\"\n\nmsg_info \"Updating to ${RELEASE}\"\nwget -q https://github.com/TriliumNext/Notes/releases/download/${RELEASE}/TriliumNextNotes-${RELEASE}-server-linux-x64.tar.xz\ntar -xf TriliumNextNotes-${RELEASE}-server-linux-x64.tar.xz\ncp -r trilium-linux-x64-server/* /opt/trilium/\nmsg_ok \"Updated to ${RELEASE}\"\n\nmsg_info \"Cleaning up\"\nrm -rf TriliumNextNotes-${RELEASE}-server-linux-x64.tar.xz trilium-linux-x64-server\nmsg_ok \"Cleaned\"\n\nmsg_info \"Starting ${APP}\"\nsystemctl start trilium.service\nsleep 1\nmsg_ok \"Started ${APP}\"\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:8080${CL} \\n\"\n"
  },
  {
    "path": "ct/ubuntu.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n   __  ____                __       \n  / / / / /_  __  ______  / /___  __\n / / / / __ \\/ / / / __ \\/ __/ / / /\n/ /_/ / /_/ / /_/ / / / / /_/ /_/ / \n\\____/_.___/\\__,_/_/ /_/\\__/\\__,_/  \n \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Ubuntu\"\nvar_disk=\"2\"\nvar_cpu=\"1\"\nvar_ram=\"512\"\nvar_os=\"ubuntu\"\nvar_version=\"22.04\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /var ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating ${APP} LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated ${APP} LXC\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\n"
  },
  {
    "path": "ct/umami.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n                                   _ \n  __  ______ ___  ____ _____ ___  (_)\n / / / / __ `__ \\/ __ `/ __ `__ \\/ / \n/ /_/ / / / / / / /_/ / / / / / / /  \n\\__,_/_/ /_/ /_/\\__,_/_/ /_/ /_/_/   \n                                     \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Umami\"\nvar_disk=\"12\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/umami ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nwhiptail --backtitle \"Proxmox VE Helper Scripts\" --msgbox --title \"SET RESOURCES\" \"Please set the resources in your ${APP} LXC to ${var_cpu}vCPU and ${var_ram}RAM for the build process before continuing\" 10 75\nif (( $(df /boot | awk 'NR==2{gsub(\"%\",\"\",$5); print $5}') > 80 )); then\n  read -r -p \"Warning: Storage is dangerously low, continue anyway? <y/N> \" prompt\n  [[ ${prompt,,} =~ ^(y|yes)$ ]] || exit\nfi\n\nmsg_info \"Stopping ${APP}\"\nsystemctl stop umami\nmsg_ok \"Stopped $APP\"\n\nmsg_info \"Updating ${APP}\"\ncd /opt/umami\ngit pull\nyarn install\nyarn build\nmsg_ok \"Updated ${APP}\"\n\nmsg_info \"Starting ${APP}\"\nsystemctl start umami\nmsg_ok \"Started ${APP}\"\n\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_info \"Setting Container to Normal Resources\"\npct set $CTID -memory 1024\npct set $CTID -cores 1\nmsg_ok \"Set Container to Normal Resources\"\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:3000${CL} \\n\"\n"
  },
  {
    "path": "ct/umbrel.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n   __  __          __              __\n  / / / /___ ___  / /_  ________  / /\n / / / / __ `__ \\/ __ \\/ ___/ _ \\/ / \n/ /_/ / / / / / / /_/ / /  /  __/ /  \n\\____/_/ /_/ /_/_.___/_/   \\___/_/   \n                                     \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Umbrel\"\nvar_disk=\"8\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nmsg_info \"Updating ${APP} LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated ${APP} LXC\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL (reboot is required before apps install).\n    ${BL}http://${IP} ${CL} \\n\"\n"
  },
  {
    "path": "ct/unifi.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n   __  __      _ _____ \n  / / / /__   (_) __(_)\n / / / / __ \\/ / /_/ / \n/ /_/ / / / / / __/ /  \n\\____/_/ /_/_/_/ /_/   \n \nEOF\n}\nheader_info\nif ! grep -q -m1 'avx[^ ]*' /proc/cpuinfo; then\n  echo \"AVX instruction set is not supported on this CPU.\"\n  exit\nfi\necho -e \"Loading...\"\nAPP=\"Unifi\"\nvar_disk=\"8\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /usr/lib/unifi ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating ${APP}\"\napt-get update --allow-releaseinfo-change\napt-get install -y unifi\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP}${CL} should be reachable by going to the following URL.\n         ${BL}https://${IP}:8443${CL} \\n\"\n"
  },
  {
    "path": "ct/unmanic.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n   __  __                            _\n  / / / /___  ____ ___  ____ _____  (_)____\n / / / / __ \\/ __ `__ \\/ __ `/ __ \\/ / ___/\n/ /_/ / / / / / / / / / /_/ / / / / / /__\n\\____/_/ /_/_/ /_/ /_/\\__,_/_/ /_/_/\\___/\n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Unmanic\"\nvar_disk=\"4\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"0\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -f /etc/systemd/system/unmanic.service ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating $APP LXC\"\npip3 install -U unmanic &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated $APP LXC\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:8888${CL} \\n\"\n"
  },
  {
    "path": "ct/uptimekuma.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n   __  __      __  _                   __ __                     \n  / / / /___  / /_(_)___ ___  ___     / //_/_  ______ ___  ____ _\n / / / / __ \\/ __/ / __  __ \\/ _ \\   / ,< / / / / __  __ \\/ __  /\n/ /_/ / /_/ / /_/ / / / / / /  __/  / /| / /_/ / / / / / / /_/ / \n\\____/ .___/\\__/_/_/ /_/ /_/\\___/  /_/ |_\\__,_/_/ /_/ /_/\\__,_/  \n    /_/                                                          \n \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Uptime Kuma\"\nvar_disk=\"4\"\nvar_cpu=\"1\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/uptime-kuma ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\n  if [[ \"$(node -v | cut -d 'v' -f 2)\" == \"18.\"* ]]; then\n    if ! command -v npm >/dev/null 2>&1; then\n      echo \"Installing NPM...\"\n      apt-get install -y npm >/dev/null 2>&1\n      echo \"Installed NPM...\"\n    fi\n  fi\nLATEST=$(curl -sL https://api.github.com/repos/louislam/uptime-kuma/releases/latest | grep '\"tag_name\":' | cut -d'\"' -f4)\nmsg_info \"Stopping ${APP}\"\nsudo systemctl stop uptime-kuma &>/dev/null\nmsg_ok \"Stopped ${APP}\"\n\ncd /opt/uptime-kuma\n\nmsg_info \"Pulling ${APP} ${LATEST}\"\ngit fetch --all &>/dev/null\ngit checkout $LATEST --force &>/dev/null\nmsg_ok \"Pulled ${APP} ${LATEST}\"\n\nmsg_info \"Updating ${APP} to ${LATEST}\"\nnpm install --production &>/dev/null\nnpm run download-dist &>/dev/null\nmsg_ok \"Updated ${APP}\"\n\nmsg_info \"Starting ${APP}\"\nsudo systemctl start uptime-kuma &>/dev/null\nmsg_ok \"Started ${APP}\"\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:3001${CL} \\n\"\n"
  },
  {
    "path": "ct/vaultwarden.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\n  clear\n  cat <<\"EOF\"\n _    __            ____ _       __               __         \n| |  / /___ ___  __/ / /| |     / /___ __________/ /__  ____ \n| | / / __ `/ / / / / __/ | /| / / __ `/ ___/ __  / _ \\/ __ \\\n| |/ / /_/ / /_/ / / /_ | |/ |/ / /_/ / /  / /_/ /  __/ / / /\n|___/\\__,_/\\__,_/_/\\__/ |__/|__/\\__,_/_/   \\__,_/\\___/_/ /_/ \n                                                             \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Vaultwarden\"\nvar_disk=\"6\"\nvar_cpu=\"4\"\nvar_ram=\"5120\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\n  if [[ ! -f /etc/systemd/system/vaultwarden.service ]]; then\n    msg_error \"No ${APP} Installation Found!\"\n    exit\n  fi\n \n  VAULT=$(curl -s https://api.github.com/repos/dani-garcia/vaultwarden/releases/latest |\n    grep \"tag_name\" |\n    awk '{print substr($2, 2, length($2)-3) }')\n  WVRELEASE=$(curl -s https://api.github.com/repos/dani-garcia/bw_web_builds/releases/latest |\n    grep \"tag_name\" |\n    awk '{print substr($2, 2, length($2)-3) }')\n\n  UPD=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"SUPPORT\" --radiolist --cancel-button Exit-Script \"Spacebar = Select\" 11 58 3 \\\n    \"1\" \"VaultWarden $VAULT\" ON \\\n    \"2\" \"Web-Vault $WVRELEASE\" OFF \\\n    \"3\" \"Set Admin Token\" OFF \\\n    3>&1 1>&2 2>&3)\n\n  header_info\n  if [ \"$UPD\" == \"1\" ]; then\n    whiptail --backtitle \"Proxmox VE Helper Scripts\" --msgbox --title \"SET RESOURCES\" \"Please set the resources in your ${APP} LXC to ${var_cpu}vCPU and ${var_ram}RAM for the build process before continuing\" 10 75\n    msg_info \"Stopping Vaultwarden\"\n    systemctl stop vaultwarden.service\n    msg_ok \"Stopped Vaultwarden\"\n\n    msg_info \"Updating VaultWarden to $VAULT (Patience)\"\n    cd ~ && rm -rf vaultwarden\n    git clone https://github.com/dani-garcia/vaultwarden &>/dev/null\n    cd vaultwarden\n    cargo build --features \"sqlite,mysql,postgresql\" --release &>/dev/null\n    DIR=/usr/bin/vaultwarden\n    if [ -d \"$DIR\" ]; then\n      cp target/release/vaultwarden /usr/bin/\n    else\n      cp target/release/vaultwarden /opt/vaultwarden/bin/\n    fi\n    msg_ok \"Updated VaultWarden\"\n\n    msg_info \"Cleaning up\"\n    cd ~ && rm -rf vaultwarden\n    msg_ok \"Cleaned\"\n\n    msg_info \"Starting Vaultwarden\"\n    systemctl start vaultwarden.service\n    msg_ok \"Started Vaultwarden\"\n\n    msg_ok \"$VAULT Update Successful\"\n    echo -e \"\\n ⚠️  Ensure you set resources back to normal settings \\n\"\n    exit\n  fi\n  if [ \"$UPD\" == \"2\" ]; then\n    msg_info \"Stopping Vaultwarden\"\n    systemctl stop vaultwarden.service\n    msg_ok \"Stopped Vaultwarden\"\n\n    msg_info \"Updating Web-Vault to $WVRELEASE\"\n    curl -fsSLO https://github.com/dani-garcia/bw_web_builds/releases/download/$WVRELEASE/bw_web_$WVRELEASE.tar.gz &>/dev/null\n    tar -zxf bw_web_$WVRELEASE.tar.gz -C /opt/vaultwarden/ &>/dev/null\n    msg_ok \"Updated Web-Vault\"\n\n    msg_info \"Cleaning up\"\n    rm bw_web_$WVRELEASE.tar.gz\n    msg_ok \"Cleaned\"\n\n    msg_info \"Starting Vaultwarden\"\n    systemctl start vaultwarden.service\n    msg_ok \"Started Vaultwarden\"\n    msg_ok \"$WVRELEASE Update Successful\"\n    exit\n  fi\n  if [ \"$UPD\" == \"3\" ]; then\n    if NEWTOKEN=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --passwordbox \"Set the ADMIN_TOKEN\" 10 58 3>&1 1>&2 2>&3); then\n      if [[ -z \"$NEWTOKEN\" ]]; then exit; fi\n      if ! command -v argon2 >/dev/null 2>&1; then apt-get install -y argon2 &>/dev/null; fi\n      TOKEN=$(echo -n ${NEWTOKEN} | argon2 \"$(openssl rand -base64 32)\" -t 2 -m 16 -p 4 -l 64 -e)\n      sed -i \"s|ADMIN_TOKEN=.*|ADMIN_TOKEN='${TOKEN}'|\" /opt/vaultwarden/.env\n      if [[ -f /opt/vaultwarden/data/config.json ]]; then\n        sed -i \"s|\\\"admin_token\\\":.*|\\\"admin_token\\\": \\\"${TOKEN}\\\"|\" /opt/vaultwarden/data/config.json\n      fi\n      systemctl restart vaultwarden\n    fi\n    exit\n  fi\n}\n\nstart\nbuild_container\ndescription\n\nmsg_info \"Setting Container to Normal Resources\"\npct set $CTID -memory 512\npct set $CTID -cores 1\nmsg_ok \"Set Container to Normal Resources\"\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:8000${CL} \\n\"\n"
  },
  {
    "path": "ct/wallos.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck\n# Co-Author: MickLesk (Canbiz)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n _       __      ____          \n| |     / /___ _/ / /___  _____\n| | /| / / __ `/ / / __ \\/ ___/\n| |/ |/ / /_/ / / / /_/ (__  ) \n|__/|__/\\__,_/_/_/\\____/____/  \n                               \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Wallos\"\nvar_disk=\"5\"\nvar_cpu=\"1\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/wallos ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nif (( $(df /boot | awk 'NR==2{gsub(\"%\",\"\",$5); print $5}') > 80 )); then\n  read -r -p \"Warning: Storage is dangerously low, continue anyway? <y/N> \" prompt\n  [[ ${prompt,,} =~ ^(y|yes)$ ]] || exit\nfi\nRELEASE=$(curl -s https://api.github.com/repos/ellite/Wallos/releases/latest | grep \"tag_name\" | awk '{print substr($2, 3, length($2)-4) }')\nif [[ ! -f /opt/${APP}_version.txt ]] || [[ \"${RELEASE}\" != \"$(cat /opt/${APP}_version.txt)\" ]]; then\n  msg_info \"Updating ${APP} to ${RELEASE}\"\n  cd /opt\n  wget -q \"https://github.com/ellite/Wallos/archive/refs/tags/v${RELEASE}.zip\"\n  mv /opt/wallos/db/wallos.db /opt/wallos.db\n  unzip -q v${RELEASE}.zip\n  mv Wallos-${RELEASE} /opt/wallos\n  rm -rf /opt/wallos/db/wallos.empty.db\n  mv /opt/wallos.db /opt/wallos/db/wallos.db\n  chown -R www-data:www-data /opt/wallos\n  chmod -R 755 /opt/wallos\n  curl http://localhost/endpoints/db/migrate.php &>/dev/null\n  echo \"${RELEASE}\" >/opt/${APP}_version.txt\n  msg_ok \"Updated ${APP}\"\n\n  msg_info \"Reload Apache2\"\n  systemctl reload apache2\n  msg_ok \"Apache2 Reloaded\"\n\n  msg_info \"Cleaning Up\"\n  rm -R /opt/v${RELEASE}.zip \n  msg_ok \"Cleaned\"\n  msg_ok \"Updated Successfully\"\nelse\n  msg_ok \"No update required. ${APP} is already at ${RELEASE}\"\nfi\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP} ${CL} \\n\"\n"
  },
  {
    "path": "ct/wastebin.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck\n# Co-Author: MickLesk (Canbiz)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n# Source: https://github.com/matze/wastebin\n\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n _       __           __       __    _     \n| |     / /___ ______/ /____  / /_  (_)___ \n| | /| / / __ `/ ___/ __/ _ \\/ __ \\/ / __ \\\n| |/ |/ / /_/ (__  ) /_/  __/ /_/ / / / / /\n|__/|__/\\__,_/____/\\__/\\___/_.___/_/_/ /_/ \n                                            \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Wastebin\"\nvar_disk=\"4\"\nvar_cpu=\"1\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/wastebin ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nRELEASE=$(curl -s https://api.github.com/repos/matze/wastebin/releases/latest | grep \"tag_name\" | awk '{print substr($2, 2, length($2)-3) }')\nif [[ ! -f /opt/${APP}_version.txt ]] || [[ \"${RELEASE}\" != \"$(cat /opt/${APP}_version.txt)\" ]]; then\n  msg_info \"Stopping Wastebin\"\n  systemctl stop wastebin\n  msg_ok \"Wastebin Stopped\"\n\n  msg_info \"Updating Wastebin\"\n  wget -q https://github.com/matze/wastebin/releases/download/${RELEASE}/wastebin_${RELEASE}_x86_64-unknown-linux-musl.tar.zst\n  tar -xf wastebin_${RELEASE}_x86_64-unknown-linux-musl.tar.zst\n  cp -f wastebin /opt/wastebin/\n  chmod +x /opt/wastebin/wastebin\n  echo \"${RELEASE}\" >/opt/${APP}_version.txt\n  msg_ok \"Updated Wastebin\"\n\n  msg_info \"Starting Wastebin\"\n  systemctl start wastebin\n  msg_ok \"Started Wastebin\"\n\n  msg_info \"Cleaning Up\"\n  rm -rf wastebin_${RELEASE}_x86_64-unknown-linux-musl.tar.zst\n  msg_ok \"Cleaned\"\n  msg_ok \"Updated Successfully\"\nelse\n  msg_ok \"No update required. ${APP} is already at ${RELEASE}\"\nfi\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} Setup should be reachable by going to the following URL.\n         ${BL}http://${IP}:8088${CL} \\n\"\n"
  },
  {
    "path": "ct/watchyourlan.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n _       __      __       ____  __                 __    ___    _   __\n| |     / /___ _/ /______/ /\\ \\/ /___  __  _______/ /   /   |  / | / /\n| | /| / / __ `/ __/ ___/ __ \\  / __ \\/ / / / ___/ /   / /| | /  |/ /\n| |/ |/ / /_/ / /_/ /__/ / / / / /_/ / /_/ / /  / /___/ ___ |/ /|  /\n|__/|__/\\__,_/\\__/\\___/_/ /_/_/\\____/\\__,_/_/  /_____/_/  |_/_/ |_/\n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"WatchYourLAN\"\nvar_disk=\"2\"\nvar_cpu=\"1\"\nvar_ram=\"512\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -f /lib/systemd/system/watchyourlan.service ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating $APP\"\nsystemctl stop watchyourlan.service\ncp -R /data/config.yaml config.yaml\nRELEASE=$(curl -s https://api.github.com/repos/aceberg/WatchYourLAN/releases/latest | grep -o '\"tag_name\": *\"[^\"]*\"' | cut -d '\"' -f 4)\nwget -q https://github.com/aceberg/WatchYourLAN/releases/download/$RELEASE/watchyourlan_${RELEASE}_linux_amd64.deb\ndpkg -i watchyourlan_${RELEASE}_linux_amd64.deb\ncp -R config.yaml /data/config.yaml\nsed -i 's|/etc/watchyourlan/config.yaml|/data/config.yaml|' /lib/systemd/system/watchyourlan.service\nrm watchyourlan_${RELEASE}_linux_amd64.deb config.yaml\nsystemctl enable -q --now watchyourlan.service\nmsg_ok \"Updated $APP\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:8840${CL} \\n\"\n"
  },
  {
    "path": "ct/whisparr.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n _       ____    _                           \n| |     / / /_  (_)________  ____  __________\n| | /| / / __ \\/ / ___/ __ \\/ __ `/ ___/ ___/\n| |/ |/ / / / / (__  ) /_/ / /_/ / /  / /    \n|__/|__/_/ /_/_/____/ .___/\\__,_/_/  /_/     \n                   /_/                       \n \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Whisparr\"\nvar_disk=\"4\"\nvar_cpu=\"2\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /var/lib/whisparr ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating $APP LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated $APP LXC\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:6969${CL} \\n\"\n"
  },
  {
    "path": "ct/whoogle.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n _       ____  ______  ____  ________    ______\n| |     / / / / / __ \\/ __ \\/ ____/ /   / ____/\n| | /| / / /_/ / / / / / / / / __/ /   / __/   \n| |/ |/ / __  / /_/ / /_/ / /_/ / /___/ /___   \n|__/|__/_/ /_/\\____/\\____/\\____/_____/_____/   \n \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Whoogle\"\nvar_disk=\"2\"\nvar_cpu=\"1\"\nvar_ram=\"512\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -f /usr/local/bin/whoogle-search ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating ${APP} LXC\"\npip3 install whoogle-search --upgrade &>/dev/null\nsystemctl restart whoogle.service\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:5000${CL} \\n\"\n"
  },
  {
    "path": "ct/wikijs.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n _       ___ __   _     _     \n| |     / (_) /__(_)   (_)____\n| | /| / / / //_/ /   / / ___/\n| |/ |/ / / ,< / /   / (__  ) \n|__/|__/_/_/|_/_(_)_/ /____/  \n                 /___/      \n \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Wikijs\"\nvar_disk=\"3\"\nvar_cpu=\"1\"\nvar_ram=\"512\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/wikijs ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Stopping ${APP}\"\nsystemctl stop wikijs\nmsg_ok \"Stopped ${APP}\"\n\nmsg_info \"Backing up Data\"\nmkdir -p ~/data-backup\ncp -R /opt/wikijs/{db.sqlite,config.yml,/data} ~/data-backup\nmsg_ok \"Backed up Data\"\n\nmsg_info \"Updating ${APP}\"\nrm -rf /opt/wikijs/*\ncd /opt/wikijs\nwget -q https://github.com/Requarks/wiki/releases/latest/download/wiki-js.tar.gz\ntar xzf wiki-js.tar.gz \nmsg_ok \"Updated ${APP}\"\n\nmsg_info \"Restoring Data\"\ncp -R ~/data-backup/* /opt/wikijs\nrm -rf ~/data-backup\nnpm rebuild sqlite3 &>/dev/null\nmsg_ok \"Restored Data\"\n\nmsg_info \"Starting ${APP}\"\nsystemctl start wikijs\nmsg_ok \"Started ${APP}\"\nmsg_ok \"Updated Successfully\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:3000${CL} \\n\"\n"
  },
  {
    "path": "ct/wireguard.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n _       ___           ______                     __\n| |     / (_)_______  / ____/_  ______ __________/ /\n| | /| / / / ___/ _ \\/ / __/ / / / __ `/ ___/ __  / \n| |/ |/ / / /  /  __/ /_/ / /_/ / /_/ / /  / /_/ /  \n|__/|__/_/_/   \\___/\\____/\\__,_/\\__,_/_/   \\__,_/   \n                                                    \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Wireguard\"\nvar_disk=\"4\"\nvar_cpu=\"1\"\nvar_ram=\"512\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nif [[ ! -d /etc/wireguard ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\napt-get update\napt-get -y upgrade\nsleep 2\ncd /etc/wgdashboard/src\n./wgd.sh update\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"WGDashboard should be reachable by going to the following URL.\n         ${BL}http://${IP}:10086${CL} admin|admin \\n\"\n"
  },
  {
    "path": "ct/yunohost.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n__  __                  __  __           __ \n\\ \\/ /_  ______  ____  / / / /___  _____/ /_\n \\  / / / / __ \\/ __ \\/ /_/ / __ \\/ ___/ __/\n / / /_/ / / / / /_/ / __  / /_/ (__  ) /_  \n/_/\\__,_/_/ /_/\\____/_/ /_/\\____/____/\\__/  \n                                            \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"YunoHost\"\nvar_disk=\"20\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"11\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -f /etc/apt/trusted.gpg.d/php.gpg ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating $APP LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nmsg_ok \"Updated $APP LXC\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}/ ${CL}\"\n"
  },
  {
    "path": "ct/zabbix.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n _____         __    __    _\n/__  /  ____ _/ /_  / /_  (_)  __\n  / /  / __ `/ __ \\/ __ \\/ / |/_/\n / /__/ /_/ / /_/ / /_/ / />  <\n/____/\\__,_/_.___/_.___/_/_/|_|\n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Zabbix\"\nvar_disk=\"6\"\nvar_cpu=\"2\"\nvar_ram=\"4096\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -f /etc/zabbix/zabbix_server.conf ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nmsg_info \"Updating $APP LXC\"\napt-get update &>/dev/null\napt-get -y upgrade &>/dev/null\nsystemctl restart zabbix-server\nmsg_ok \"Updated $APP LXC\"\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}/zabbix${CL} \\n\"\n"
  },
  {
    "path": "ct/zigbee2mqtt.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\n  clear\n  cat <<\"EOF\"\n _____   _       __             ___   __  _______  ____________\n/__  /  (_)___ _/ /_  ___  ___ |__ \\ /  |/  / __ \\/_  __/_  __/\n  / /  / / __  / __ \\/ _ \\/ _ \\__/ // /|_/ / / / / / /   / /   \n / /__/ / /_/ / /_/ /  __/  __/ __// /  / / /_/ / / /   / /    \n/____/_/\\__, /_.___/\\___/\\___/____/_/  /_/\\___\\_\\/_/   /_/     \n       /____/ 🐝\n \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Zigbee2MQTT\"\nvar_disk=\"4\"\nvar_cpu=\"2\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"0\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\n  header_info\n  if [[ ! -d /opt/zigbee2mqtt ]]; then\n    msg_error \"No ${APP} Installation Found!\"\n    exit\n  fi\n  if [[ \"$(node -v | cut -d 'v' -f 2)\" == \"18.\"* ]]; then\n    if ! command -v npm >/dev/null 2>&1; then\n      echo \"Installing NPM...\"\n      apt-get install -y npm >/dev/null 2>&1\n      echo \"Installed NPM...\"\n    fi\n  fi\n  cd /opt/zigbee2mqtt\n\n  stop_zigbee2mqtt() {\n    if which systemctl 2>/dev/null >/dev/null; then\n      echo \"Shutting down Zigbee2MQTT...\"\n      sudo systemctl stop zigbee2mqtt\n    else\n      echo \"Skipped stopping Zigbee2MQTT, no systemctl found\"\n    fi\n  }\n\n  start_zigbee2mqtt() {\n    if which systemctl 2>/dev/null >/dev/null; then\n      echo \"Starting Zigbee2MQTT...\"\n      sudo systemctl start zigbee2mqtt\n    else\n      echo \"Skipped starting Zigbee2MQTT, no systemctl found\"\n    fi\n  }\n\n  set -e\n\n  if [ -d data-backup ]; then\n    echo \"ERROR: Backup directory exists. May be previous restoring was failed?\"\n    echo \"1. Save 'data-backup' and 'data' dirs to safe location to make possibility to restore config later.\"\n    echo \"2. Manually delete 'data-backup' dir and try again.\"\n    exit 1\n  fi\n\n  stop_zigbee2mqtt\n\n  echo \"Generating a backup of the configuration...\"\n  cp -R data data-backup || {\n    echo \"Failed to create backup.\"\n    exit 1\n  }\n\n  echo \"Checking if any changes were made to package-lock.json...\"\n  git checkout package-lock.json || {\n    echo \"Failed to check package-lock.json.\"\n    exit 1\n  }\n\n  echo \"Initiating update...\"\n  if ! git pull; then\n    echo \"Update failed, temporarily storing changes and trying again.\"\n    git stash && git pull || (\n      echo \"Update failed even after storing changes. Aborting.\"\n      exit 1\n    )\n  fi\n\n  echo \"Acquiring necessary components...\"\n  npm ci || {\n    echo \"Failed to install necessary components.\"\n    exit 1\n  }\n\n  echo \"Building...\"\n  npm run build || {\n    echo \"Failed to build new version.\"\n    exit 1\n  }\n\n  echo \"Restoring configuration...\"\n  cp -R data-backup/* data || {\n    echo \"Failed to restore configuration.\"\n    exit 1\n  }\n\n  rm -rf data-backup || {\n    echo \"Failed to remove backup directory.\"\n    exit 1\n  }\n\n  start_zigbee2mqtt\n\n  echo \"Done!\"\n  exit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\n"
  },
  {
    "path": "ct/zipline.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck\n# Co-Author: MickLesk (Canbiz)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n _____   _       ___          \n/__  /  (_)___  / (_)___  ___ \n  / /  / / __ \\/ / / __ \\/ _ \\\n / /__/ / /_/ / / / / / /  __/\n/____/_/ .___/_/_/_/ /_/\\___/ \n      /_/                                                  \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Zipline\"\nvar_disk=\"5\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/zipline ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nif (( $(df /boot | awk 'NR==2{gsub(\"%\",\"\",$5); print $5}') > 80 )); then\n  read -r -p \"Warning: Storage is dangerously low, continue anyway? <y/N> \" prompt\n  [[ ${prompt,,} =~ ^(y|yes)$ ]] || exit\nfi\nRELEASE=$(curl -s https://api.github.com/repos/diced/zipline/releases/latest | grep \"tag_name\" | awk '{print substr($2, 3, length($2)-4) }')\nif [[ ! -f /opt/${APP}_version.txt ]] || [[ \"${RELEASE}\" != \"$(cat /opt/${APP}_version.txt)\" ]]; then\n  msg_info \"Stopping ${APP}\"\n  systemctl stop zipline\n  msg_ok \"${APP} Stopped\"\n\n  msg_info \"Updating ${APP} to ${RELEASE}\"\n  cp /opt/zipline/.env /opt/\n  rm -R /opt/zipline\n  wget -q \"https://github.com/diced/zipline/archive/refs/tags/v${RELEASE}.zip\"\n  unzip -q v${RELEASE}.zip\n  mv zipline-${RELEASE} /opt/zipline\n  cd /opt/zipline\n  mv /opt/.env /opt/zipline/.env\n  yarn install &>/dev/null\n  yarn build &>/dev/null\n  echo \"${RELEASE}\" >/opt/${APP}_version.txt\n  msg_ok \"Updated ${APP}\"\n\n  msg_info \"Starting ${APP}\"\n  systemctl start zipline\n  msg_ok \"Started ${APP}\"\n\n  msg_info \"Cleaning Up\"\n  rm -rf v${RELEASE}.zip\n  msg_ok \"Cleaned\"\n  msg_ok \"Updated Successfully\"\nelse\n  msg_ok \"No update required. ${APP} is already at ${RELEASE}\"\nfi\nexit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} Setup should be reachable by going to the following URL.\n         ${BL}http://${IP}:3000${CL} \\n\""
  },
  {
    "path": "ct/zoraxy.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n _____\n/__  /  ____  _________ __  ____  __\n  / /  / __ \\/ ___/ __ `/ |/_/ / / /\n / /__/ /_/ / /  / /_/ />  </ /_/ /\n/____/\\____/_/   \\__,_/_/|_|\\__, /\n                           /____/\nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Zoraxy\"\nvar_disk=\"6\"\nvar_cpu=\"2\"\nvar_ram=\"2048\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"1\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\nheader_info\nif [[ ! -d /opt/zoraxy/ ]]; then msg_error \"No ${APP} Installation Found!\"; exit; fi\nRELEASE=$(curl -s https://api.github.com/repos/tobychui/zoraxy/releases/latest  | grep \"tag_name\" | awk '{print substr($2, 2, length($2)-3) }')\nif [[ ! -f /opt/${APP}_version.txt ]] || [[ \"${RELEASE}\" != \"$(cat /opt/${APP}_version.txt)\" ]]; then\n  msg_info \"Updating $APP to ${RELEASE}\"\n  systemctl stop zoraxy\n  wget -q \"https://github.com/tobychui/zoraxy/releases/download/${RELEASE}/zoraxy_linux_amd64\"\n  rm /opt/zoraxy/zoraxy\n  mv zoraxy_linux_amd64 /opt/zoraxy/zoraxy\n  chmod +x /opt/zoraxy/zoraxy\n  systemctl start zoraxy\n  echo \"${RELEASE}\" >/opt/${APP}_version.txt\n  msg_ok \"Updated $APP\"\nelse\n  msg_ok \"No update required. ${APP} is already at ${RELEASE}\"\n fi\n exit\n}\n\nstart\nbuild_container\ndescription\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:8000${CL} \\n\"\n"
  },
  {
    "path": "ct/zwave-js-ui.sh",
    "content": "#!/usr/bin/env bash\nsource <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\n  clear\n  cat <<\"EOF\"\n _____                                  _______    __  ______\n/__  /_      ______ __   _____         / / ___/   / / / /  _/\n  / /| | /| / / __ `/ | / / _ \\   __  / /\\__ \\   / / / // /  \n / /_| |/ |/ / /_/ /| |/ /  __/  / /_/ /___/ /  / /_/ // /   \n/____/__/|__/\\__,_/ |___/\\___/   \\____//____/   \\____/___/   \n                                                             \nEOF\n}\nheader_info\necho -e \"Loading...\"\nAPP=\"Zwave-JS-UI\"\nvar_disk=\"4\"\nvar_cpu=\"2\"\nvar_ram=\"1024\"\nvar_os=\"debian\"\nvar_version=\"12\"\nvariables\ncolor\ncatch_errors\n\nfunction default_settings() {\n  CT_TYPE=\"0\"\n  PW=\"\"\n  CT_ID=$NEXTID\n  HN=$NSAPP\n  DISK_SIZE=\"$var_disk\"\n  CORE_COUNT=\"$var_cpu\"\n  RAM_SIZE=\"$var_ram\"\n  BRG=\"vmbr0\"\n  NET=\"dhcp\"\n  GATE=\"\"\n  APT_CACHER=\"\"\n  APT_CACHER_IP=\"\"\n  DISABLEIP6=\"no\"\n  MTU=\"\"\n  SD=\"\"\n  NS=\"\"\n  MAC=\"\"\n  VLAN=\"\"\n  SSH=\"no\"\n  VERB=\"no\"\n  echo_default\n}\n\nfunction update_script() {\n  header_info\n  if [[ ! -d /opt/zwave-js-ui ]]; then\n    msg_error \"No ${APP} Installation Found!\"\n    exit\n  fi\n  RELEASE=$(curl -s https://api.github.com/repos/zwave-js/zwave-js-ui/releases/latest | grep \"tag_name\" | awk '{print substr($2, 2, length($2)-3) }')\n  msg_info \"Stopping Z-wave JS UI\"\n  systemctl stop zwave-js-ui.service\n  msg_ok \"Stopped Z-wave JS UI\"\n\n  msg_info \"Updating Z-wave JS UI\"\n  wget https://github.com/zwave-js/zwave-js-ui/releases/download/${RELEASE}/zwave-js-ui-${RELEASE}-linux.zip &>/dev/null\n  unzip zwave-js-ui-${RELEASE}-linux.zip &>/dev/null\n  \\cp -R zwave-js-ui-linux /opt/zwave-js-ui\n  service_path=\"/etc/systemd/system/zwave-js-ui.service\"\n  echo \"[Unit]\n  Description=zwave-js-ui\n  Wants=network-online.target\n  After=network-online.target\n  [Service]\n  User=root\n  WorkingDirectory=/opt/zwave-js-ui\n  ExecStart=/opt/zwave-js-ui/zwave-js-ui-linux\n  [Install]\n  WantedBy=multi-user.target\" >$service_path\n  msg_ok \"Updated Z-wave JS UI\"\n\n  msg_info \"Starting Z-wave JS UI\"\n  systemctl enable --now zwave-js-ui.service\n  msg_ok \"Started Z-wave JS UI\"\n\n  msg_info \"Cleanup\"\n  rm -rf zwave-js-ui-${RELEASE}-linux.zip zwave-js-ui-linux store\n  msg_ok \"Cleaned\"\n  msg_ok \"Updated Successfully!\\n\"\n  exit\n}\n\nstart\nbuild_container\ndescription\n\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://${IP}:8091${CL} \\n\"\n"
  },
  {
    "path": "install/actualbudget-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y gpg\n$STD apt-get install -y git\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Setting up Node.js Repository\"\nmkdir -p /etc/apt/keyrings\ncurl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg\necho \"deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main\" >/etc/apt/sources.list.d/nodesource.list\nmsg_ok \"Set up Node.js Repository\"\n\nmsg_info \"Installing Node.js\"\n$STD apt-get update\n$STD apt-get install -y nodejs\n$STD npm install --global yarn\nmsg_ok \"Installed Node.js\"\n\nmsg_info \"Installing Actual Budget\"\n$STD git clone https://github.com/actualbudget/actual-server.git /opt/actualbudget\nmkdir -p /opt/actualbudget/server-files\nchown -R root:root /opt/actualbudget/server-files\nchmod 755 /opt/actualbudget/server-files\ncat <<EOF > /opt/actualbudget/.env\nACTUAL_UPLOAD_DIR=/opt/actualbudget/server-files\nPORT=5006\nEOF\ncd /opt/actualbudget\n$STD yarn install\nmsg_ok \"Installed Actual Budget\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/actualbudget.service\n[Unit]\nDescription=Actual Budget Service\nAfter=network.target\n\n[Service]\nType=simple\nUser=root\nGroup=root\nWorkingDirectory=/opt/actualbudget\nEnvironmentFile=/opt/actualbudget/.env\nExecStart=/usr/bin/yarn start\nRestart=always\nRestartSec=10\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now actualbudget.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/adguard-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing AdGuard Home\"\n$STD tar zxvf <(curl -fsSL https://static.adtidy.org/adguardhome/release/AdGuardHome_linux_amd64.tar.gz) -C /opt\nmsg_ok \"Installed AdGuard Home\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/AdGuardHome.service\n[Unit]\nDescription=AdGuard Home: Network-level blocker\nConditionFileIsExecutable=/opt/AdGuardHome/AdGuardHome\nAfter=syslog.target network-online.target\n\n[Service]\nStartLimitInterval=5\nStartLimitBurst=10\nExecStart=/opt/AdGuardHome/AdGuardHome \"-s\" \"run\"\nWorkingDirectory=/opt/AdGuardHome\nStandardOutput=file:/var/log/AdGuardHome.out\nStandardError=file:/var/log/AdGuardHome.err\nRestart=always\nRestartSec=10\nEnvironmentFile=-/etc/sysconfig/AdGuardHome\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now AdGuardHome.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/adventurelog-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck\n# Co-Author: MickLesk (Canbiz)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n# Source: https://github.com/seanmorley15/AdventureLog\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y \\\n  gpg \\\n  curl \\\n  sudo \\\n  mc \\\n  gdal-bin \\\n  libgdal-dev \\\n  git \\\n  python3-venv \\\n  python3-pip\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Setting up Node.js Repository\"\nmkdir -p /etc/apt/keyrings\ncurl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg\necho \"deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main\" >/etc/apt/sources.list.d/nodesource.list\nmsg_ok \"Set up Node.js Repository\"\n\nmsg_info \"Setting up PostgreSQL Repository\"\ncurl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor -o /etc/apt/trusted.gpg.d/postgresql.gpg\necho \"deb https://apt.postgresql.org/pub/repos/apt bookworm-pgdg main\" >/etc/apt/sources.list.d/pgdg.list\nmsg_ok \"Set up PostgreSQL Repository\"\n\nmsg_info \"Installing Node.js\"\n$STD apt-get update\n$STD apt-get install -y nodejs\n$STD npm install -g pnpm\nmsg_ok \"Installed Node.js\"\n\nmsg_info \"Install/Set up PostgreSQL Database\"\n$STD apt-get install -y postgresql-16 postgresql-16-postgis\nDB_NAME=\"adventurelog_db\"\nDB_USER=\"adventurelog_user\"\nDB_PASS=\"$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13)\"\nSECRET_KEY=\"$(openssl rand -base64 32 | tr -dc 'a-zA-Z0-9' | cut -c1-32)\"\n$STD sudo -u postgres psql -c \"CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';\"\n$STD sudo -u postgres psql -c \"CREATE DATABASE $DB_NAME WITH OWNER $DB_USER ENCODING 'UTF8' TEMPLATE template0;\"\n$STD sudo -u postgres psql -c \"CREATE EXTENSION IF NOT EXISTS postgis;\" $DB_NAME\n$STD sudo -u postgres psql -c \"ALTER ROLE $DB_USER SET client_encoding TO 'utf8';\"\n$STD sudo -u postgres psql -c \"ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';\"\n$STD sudo -u postgres psql -c \"ALTER ROLE $DB_USER SET timezone TO 'UTC';\"\n{\n    echo \"AdventureLog-Credentials\"\n    echo \"AdventureLog Database User: $DB_USER\"\n    echo \"AdventureLog Database Password: $DB_PASS\"\n    echo \"AdventureLog Database Name: $DB_NAME\"\n    echo \"AdventureLog Secret: $SECRET_KEY\"\n} >> ~/adventurelog.creds\nmsg_ok \"Set up PostgreSQL\"\n\nmsg_info \"Installing AdventureLog (Patience)\"\nDJANGO_ADMIN_USER=\"djangoadmin\"\nDJANGO_ADMIN_PASS=\"$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13)\"\nLOCAL_IP=\"$(hostname -I | awk '{print $1}')\"\ncd /opt\nRELEASE=$(curl -s https://api.github.com/repos/seanmorley15/AdventureLog/releases/latest | grep \"tag_name\" | awk '{print substr($2, 3, length($2)-4) }')\nwget -q \"https://github.com/seanmorley15/AdventureLog/archive/refs/tags/v${RELEASE}.zip\"\nunzip -q v${RELEASE}.zip\nmv AdventureLog-${RELEASE} /opt/adventurelog\ncat <<EOF > /opt/adventurelog/backend/server/.env\nPGHOST='localhost'\nPGDATABASE='${DB_NAME}'\nPGUSER='${DB_USER}'\nPGPASSWORD='${DB_PASS}'\nSECRET_KEY='${SECRET_KEY}'\nPUBLIC_URL='http://$LOCAL_IP:8000'\nDEBUG=True\nFRONTEND_URL='http://$LOCAL_IP:3000'\nCSRF_TRUSTED_ORIGINS='http://127.0.0.1:3000,http://localhost:3000,http://$LOCAL_IP:3000'\nDJANGO_ADMIN_USERNAME='${DJANGO_ADMIN_USER}'\nDJANGO_ADMIN_PASSWORD='${DJANGO_ADMIN_PASS}'\nDISABLE_REGISTRATION=False\n# EMAIL_BACKEND='email'\n# EMAIL_HOST='smtp.gmail.com'\n# EMAIL_USE_TLS=False\n# EMAIL_PORT=587\n# EMAIL_USE_SSL=True\n# EMAIL_HOST_USER='user'\n# EMAIL_HOST_PASSWORD='password'\n# DEFAULT_FROM_EMAIL='user@example.com'\nEOF\ncd /opt/adventurelog/backend/server\nmkdir -p /opt/adventurelog/backend/server/media\n$STD pip install --upgrade pip\n$STD pip install -r requirements.txt\n$STD python3 manage.py collectstatic --noinput\n$STD python3 manage.py migrate\n$STD python3 manage.py download-countries\ncat <<EOF > /opt/adventurelog/frontend/.env\nPUBLIC_SERVER_URL=http://$LOCAL_IP:8000\nBODY_SIZE_LIMIT=Infinity\nORIGIN='http://$LOCAL_IP:3000'\nEOF\ncd /opt/adventurelog/frontend\n$STD pnpm i\n$STD pnpm build\necho \"${RELEASE}\" >\"/opt/${APPLICATION}_version.txt\"\nmsg_ok \"Installed AdventureLog\"\n\nmsg_info \"Setting up Django Admin\"\n$STD python3 /opt/adventurelog/backend/server/manage.py shell << EOF\nfrom django.contrib.auth import get_user_model\nUserModel = get_user_model()\nuser = UserModel.objects.create_user('$DJANGO_ADMIN_USER', password='$DJANGO_ADMIN_PASS')\nuser.is_superuser = True\nuser.is_staff = True\nuser.save()\nEOF\n{\n    echo \"\"\n    echo \"Django-Credentials\"\n    echo \"Django Admin User: $DJANGO_ADMIN_USER\"\n    echo \"Django Admin Password: $DJANGO_ADMIN_PASS\"\n} >> ~/adventurelog.creds\nmsg_ok \"Setup Django Admin\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/adventurelog-backend.service\n[Unit]\nDescription=AdventureLog Backend Service\nAfter=network.target postgresql.service\n\n[Service]\nWorkingDirectory=/opt/adventurelog/backend/server\nExecStart=python3 manage.py runserver 0.0.0.0:8000\nRestart=always\nEnvironmentFile=/opt/adventurelog/backend/server/.env\n\n[Install]\nWantedBy=multi-user.target\nEOF\ncat <<EOF >/etc/systemd/system/adventurelog-frontend.service\n[Unit]\nDescription=AdventureLog SvelteKit Frontend Service\nAfter=network.target\n\n[Service]\nWorkingDirectory=/opt/adventurelog/frontend\nExecStart=/usr/bin/node build 127.0.0.1:3000\nRestart=always\nEnvironmentFile=/opt/adventurelog/frontend/.env\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now adventurelog-backend.service\nsystemctl enable -q --now adventurelog-frontend.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\nrm -rf /opt/v${RELEASE}.zip\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\""
  },
  {
    "path": "install/agentdvr-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y unzip\n$STD apt-get install -y apt-transport-https\n$STD apt-get install -y alsa-utils\n$STD apt-get install -y libxext-dev\n$STD apt-get install -y fontconfig\n$STD apt-get install -y libva-drm2\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing AgentDVR\"\nmkdir -p /opt/agentdvr/agent\nRELEASE=$(curl -s \"https://www.ispyconnect.com/api/Agent/DownloadLocation4?platform=Linux64&fromVersion=0\" | grep -o 'https://.*\\.zip')\ncd /opt/agentdvr/agent\nwget -q $RELEASE\n$STD unzip Agent_Linux64*.zip\nrm -rf Agent_Linux64*.zip\nchmod +x ./Agent\nmsg_ok \"Installed AgentDVR\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/AgentDVR.service\n[Unit]\nDescription=AgentDVR\n\n[Service]\nWorkingDirectory=/opt/agentdvr/agent\nExecStart=/opt/agentdvr/agent/./Agent\nEnvironment=\"MALLOC_TRIM_THRESHOLD_=100000\"\nSyslogIdentifier=AgentDVR\nRestart=always\nRestartSec=5\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now AgentDVR.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/alpine-docker-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\n\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apk add newt\n$STD apk add curl\n$STD apk add openssh\n$STD apk add tzdata\n$STD apk add nano\n$STD apk add mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Docker\"\n$STD apk add docker\n$STD rc-service docker start\n$STD rc-update add docker default\nmsg_ok \"Installed Docker\"\n\nget_latest_release() {\n  curl -sL https://api.github.com/repos/$1/releases/latest | grep '\"tag_name\":' | cut -d'\"' -f4\n}\nPORTAINER_LATEST_VERSION=$(get_latest_release \"portainer/portainer\")\nDOCKER_COMPOSE_LATEST_VERSION=$(get_latest_release \"docker/compose\")\nPORTAINER_AGENT_LATEST_VERSION=$(get_latest_release \"portainer/agent\")\n\nread -r -p \"Would you like to add Portainer? <y/N> \" prompt\nif [[ \"${prompt,,}\" =~ ^(y|yes)$ ]]; then\n  msg_info \"Installing Portainer $PORTAINER_LATEST_VERSION\"\n  docker volume create portainer_data >/dev/null\n  $STD docker run -d \\\n    -p 8000:8000 \\\n    -p 9443:9443 \\\n    --name=portainer \\\n    --restart=always \\\n    -v /var/run/docker.sock:/var/run/docker.sock \\\n    -v portainer_data:/data \\\n    portainer/portainer-ce:latest\n  msg_ok \"Installed Portainer $PORTAINER_LATEST_VERSION\"\nelse\n  read -r -p \"Would you like to add the Portainer Agent? <y/N> \" prompt\n  if [[ \"${prompt,,}\" =~ ^(y|yes)$ ]]; then\n    msg_info \"Installing Portainer agent $PORTAINER_AGENT_LATEST_VERSION\"\n    $STD docker run -d \\\n      -p 9001:9001 \\\n      --name portainer_agent \\\n      --restart=always \\\n      -v /var/run/docker.sock:/var/run/docker.sock \\\n      -v /var/lib/docker/volumes:/var/lib/docker/volumes \\\n      portainer/agent\n    msg_ok \"Installed Portainer Agent $PORTAINER_AGENT_LATEST_VERSION\"\n  fi\nfi\nread -r -p \"Would you like to add Docker Compose? <y/N> \" prompt\nif [[ \"${prompt,,}\" =~ ^(y|yes)$ ]]; then\n  msg_info \"Installing Docker Compose $DOCKER_COMPOSE_LATEST_VERSION\"\n  DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker}\n  mkdir -p $DOCKER_CONFIG/cli-plugins\n  curl -sSL https://github.com/docker/compose/releases/download/$DOCKER_COMPOSE_LATEST_VERSION/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose\n  chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose\n  msg_ok \"Installed Docker Compose $DOCKER_COMPOSE_LATEST_VERSION\"\nfi\n\nmotd_ssh\ncustomize\n"
  },
  {
    "path": "install/alpine-grafana-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\n\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apk add newt\n$STD apk add curl\n$STD apk add openssh\n$STD apk add nano\n$STD apk add mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Grafana\"\n$STD apk add grafana\n$STD sed -i '/http_addr/s/127.0.0.1/0.0.0.0/g' /etc/conf.d/grafana\n$STD rc-service grafana start\n$STD rc-update add grafana default\nmsg_ok \"Installed Grafana\"\n\nmotd_ssh\ncustomize"
  },
  {
    "path": "install/alpine-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\n\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apk add newt\n$STD apk add curl\n$STD apk add openssh\n$STD apk add nano\n$STD apk add mc\nmsg_ok \"Installed Dependencies\"\n\nmotd_ssh\ncustomize\n"
  },
  {
    "path": "install/alpine-nextcloud-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\n\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apk add newt\n$STD apk add curl\n$STD apk add openssl\n$STD apk add openssh\n$STD apk add nano\n$STD apk add mc\n$STD apk add nginx\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing PHP/Redis\"\n$STD apk add php82-opcache\n$STD apk add php82-redis\n$STD apk add php82-apcu\n$STD apk add php82-fpm\n$STD apk add php82-sysvsem\n$STD apk add php82-ftp\n$STD apk add php82-pecl-smbclient\n$STD apk add php82-pecl-imagick\n$STD apk add php82-pecl-vips\n$STD apk add php82-exif\n$STD apk add php82-sodium\n$STD apk add php82-bz2\n$STD apk add redis\nmsg_ok \"Installed PHP/Redis\"\n\nmsg_info \"Installing MySQL Database\"\nDB_NAME=nextcloud\nDB_USER=nextcloud\nDB_PASS=\"$(openssl rand -base64 18 | cut -c1-13)\"\nADMIN_PASS=\"$(openssl rand -base64 18 | cut -c1-13)\"\necho \"\" >>~/nextcloud.creds\necho -e \"MySQL Admin Password: \\e[32m$ADMIN_PASS\\e[0m\" >>~/nextcloud.creds\necho -e \"Nextcloud Database Username: \\e[32m$DB_USER\\e[0m\" >>~/nextcloud.creds\necho -e \"Nextcloud Database Password: \\e[32m$DB_PASS\\e[0m\" >>~/nextcloud.creds\necho -e \"Nextcloud Database Name: \\e[32m$DB_NAME\\e[0m\" >>~/nextcloud.creds\n$STD apk add nextcloud-mysql mariadb mariadb-client\n$STD mysql_install_db --user=mysql --datadir=/var/lib/mysql\n$STD service mariadb start\n$STD rc-update add mariadb\nmysql -uroot -p\"$ADMIN_PASS\" -e \"GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY '$ADMIN_PASS' WITH GRANT OPTION; DELETE FROM mysql.user WHERE User=''; DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1'); DROP DATABASE test; DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%'; CREATE DATABASE $DB_NAME; GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASS'; GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost.localdomain' IDENTIFIED BY '$DB_PASS'; FLUSH PRIVILEGES;\"\n$STD apk del mariadb-client\nmsg_ok \"Installed MySQL Database\"\n\nmsg_info \"Installing Nextcloud\"\nADMIN_USER=ncAdmin\necho \"\" >>~/nextcloud.creds\necho -e \"Nextcloud Admin Username: \\e[32m$ADMIN_USER\\e[0m\" >>~/nextcloud.creds\necho -e \"Nextcloud Admin Password: \\e[32m$ADMIN_PASS\\e[0m (Initially enter twice)\" >>~/nextcloud.creds\n$STD apk add nextcloud-initscript\n$STD openssl req -x509 -nodes -days 365 -newkey rsa:4096 -keyout /etc/ssl/private/nextcloud-selfsigned.key -out /etc/ssl/certs/nextcloud-selfsigned.crt -subj \"/C=US/O=Nextcloud/OU=Domain Control Validated/CN=nextcloud.local\"\ncat <<'EOF' >/usr/share/webapps/nextcloud/config/config.php\n<?php\n$CONFIG = array (\n  'datadirectory' => '/var/lib/nextcloud/data',\n  'logfile' => '/var/log/nextcloud/nextcloud.log',\n  'logdateformat' => 'F d, Y H:i:s',\n  'log_rotate_size' => 104857600,\n  'apps_paths' => array (\n    0 => array (\n      'path' => '/usr/share/webapps/nextcloud/apps',\n      'url' => '/apps',\n      'writable' => false,\n    ),\n    1 => array (\n      'path' => '/var/lib/nextcloud/apps',\n      'url' => '/apps-appstore',\n      'writable' => true,\n    ),\n  ),\n  'updatechecker' => false,\n  'check_for_working_htaccess' => false,\n  'memcache.local' => '\\\\OC\\\\Memcache\\\\Redis',\n  'memcache.locking' => '\\\\OC\\\\Memcache\\\\Redis',\n  'redis' => array(\n    'host' => 'localhost',\n    'port' => 6379,\n    'dbindex' => 0,\n    'timeout' => 1.5,\n  ),\n  'installed' => false,\n);\nEOF\nrm -rf /etc/nginx/http.d/default.conf\ncat <<'EOF' >/etc/nginx/http.d/nextcloud.conf\nserver {\n        listen       [::]:80;\n        listen       80;\n        return 301 https://$host$request_uri;\n        server_name localhost;\n}\nserver {\n        listen       443 ssl http2;\n        listen       [::]:443 ssl http2;\n        server_name  localhost;\n        root /usr/share/webapps/nextcloud;\n        index  index.php index.html index.htm;\n        disable_symlinks off;\n        ssl_certificate      /etc/ssl/certs/nextcloud-selfsigned.crt;\n        ssl_certificate_key  /etc/ssl/private/nextcloud-selfsigned.key;\n        ssl_session_timeout  5m;\n        ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA;\n        ssl_prefer_server_ciphers  on;\n        location / {\n            try_files $uri $uri/ /index.html;\n        }\n        location ~ [^/]\\.php(/|$) {\n                fastcgi_split_path_info ^(.+?\\.php)(/.*)$;\n                if (!-f $document_root$fastcgi_script_name) {\n                        return 404;\n                }\n                fastcgi_pass unix:/run/nextcloud/fastcgi.sock; # From the nextcloud-initscript package\n                fastcgi_index index.php;\n                include fastcgi.conf;\n        }\n        location ^~ /.well-known/carddav { return 301 /remote.php/dav/; }\n        location ^~ /.well-known/caldav { return 301 /remote.php/dav/; }\n        location ^~ /.well-known/webfinger { return 301 /index.php/.well-known/webfinger; }\n        location ^~ /.well-known/nodeinfo { return 301 /index.php/.well-known/nodeinfo; }\n}\nEOF\nsed -i -e 's|memory_limit = 128M|memory_limit = 512M|; $aapc.enable_cli=1' /etc/php82/php.ini\nsed -i -E '/^php_admin_(flag|value)\\[opcache/s/^/;/' /etc/php82/php-fpm.d/nextcloud.conf\nmsg_ok \"Installed Nextcloud\"\n\nmsg_info \"Adding Additional Nextcloud Packages\"\n$STD apk add nextcloud-default-apps\n$STD apk add nextcloud-activity\n$STD apk add nextcloud-admin_audit\n$STD apk add nextcloud-comments\n$STD apk add nextcloud-dashboard\n$STD apk add nextcloud-doc\n$STD apk add nextcloud-encryption\n$STD apk add nextcloud-federation\n$STD apk add nextcloud-files_external\n$STD apk add nextcloud-files_sharing\n$STD apk add nextcloud-files_trashbin\n$STD apk add nextcloud-files_versions\n$STD apk add nextcloud-notifications\n$STD apk add nextcloud-sharebymail\n$STD apk add nextcloud-suspicious_login\n$STD apk add nextcloud-support\n$STD apk add nextcloud-systemtags\n$STD apk add nextcloud-user_status\n$STD apk add nextcloud-weather_status\nmsg_ok \"Added Additional Nextcloud Packages\"\n\nmsg_info \"Starting Services\"\n$STD rc-service redis start\n$STD rc-update add redis default\n$STD rc-service php-fpm82 start\nchown -R nextcloud:www-data /var/log/nextcloud/\n$STD rc-service php-fpm82 restart\n$STD rc-service nginx start\n$STD rc-service nextcloud start\n$STD rc-update add nginx default\n$STD rc-update add nextcloud default\nmsg_ok \"Started Services\"\n\nmsg_info \"Start Nextcloud Setup-Wizard\"\necho -e \"export VISUAL=nano\\nexport EDITOR=nano\" >>/etc/profile\ncd /usr/share/webapps/nextcloud\n$STD su nextcloud -s /bin/sh -c \"php82 occ maintenance:install \\\n--database='mysql' --database-name $DB_NAME \\\n--database-user '$DB_USER' --database-pass '$DB_PASS' \\\n--admin-user '$ADMIN_USER' --admin-pass '$ADMIN_PASS' \\\n--data-dir '/var/lib/nextcloud/data'\"\n$STD su nextcloud -s /bin/sh -c 'php82 occ background:cron'\nrm -rf /usr/share/webapps/nextcloud/apps/serverinfo\nIP4=$(/sbin/ip -o -4 addr list eth0 | awk '{print $4}' | cut -d/ -f1)\nsed -i \"/0 => \\'localhost\\',/a \\    \\1 => '$IP4',\" /usr/share/webapps/nextcloud/config/config.php\nsu nextcloud -s /bin/sh -c 'php82 -f /usr/share/webapps/nextcloud/cron.php'\nmsg_ok \"Finished Nextcloud Setup-Wizard\"\n\nmotd_ssh\ncustomize\n"
  },
  {
    "path": "install/alpine-vaultwarden-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\n\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apk add newt\n$STD apk add curl\n$STD apk add openssl\n$STD apk add openssh\n$STD apk add nano\n$STD apk add mc\n$STD apk add argon2\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Alpine-Vaultwarden\"\n$STD apk add vaultwarden\nsed -i -e 's/# export ADMIN_TOKEN=.*/export ADMIN_TOKEN='\\'''\\''/' -e '/^# export ROCKET_ADDRESS=0\\.0\\.0\\.0/s/^# //' -e 's|export WEB_VAULT_ENABLED=.*|export WEB_VAULT_ENABLED=true|' /etc/conf.d/vaultwarden\nmsg_ok \"Installed Alpine-Vaultwarden\"\n\nmsg_info \"Installing Web-Vault\"\n$STD apk add vaultwarden-web-vault\nmsg_ok \"Installed Web-Vault\" \n\nmsg_info \"Starting Alpine-Vaultwarden\"\n$STD rc-service vaultwarden start\n$STD rc-update add vaultwarden default\nmsg_ok \"Started Alpine-Vaultwarden\"\n\nmotd_ssh\ncustomize\n"
  },
  {
    "path": "install/alpine-zigbee2mqtt-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\n\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apk add newt\n$STD apk add curl\n$STD apk add openssh\n$STD apk add nano\n$STD apk add mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Alpine-Zigbee2MQTT\"\n$STD apk add zigbee2mqtt\nmkdir -p /root/.z2m\nln -s /etc/zigbee2mqtt/ /root/.z2m\nchown -R root:root /etc/zigbee2mqtt /root/.z2m\nsed -i -e 's/#datadir=\"\\/var\\/lib\\/zigbee2mqtt\"/datadir=\"\\/etc\\/zigbee2mqtt\"/' -e 's/#command_user=\"zigbee2mqtt\"/command_user=\"root\"/' /etc/conf.d/zigbee2mqtt\n$STD rc-update add zigbee2mqtt\n$STD rc-service zigbee2mqtt restart\nmsg_ok \"Installed Alpine-Zigbee2MQTT\"\n\nmotd_ssh\ncustomize\n"
  },
  {
    "path": "install/apache-cassandra-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y apt-transport-https\n$STD apt-get install -y gpg\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Eclipse Temurin (Patience)\"\nwget -qO- https://packages.adoptium.net/artifactory/api/gpg/key/public | gpg --dearmor >/etc/apt/trusted.gpg.d/adoptium.gpg\necho 'deb [arch=amd64 signed-by=/etc/apt/trusted.gpg.d/adoptium.gpg] https://packages.adoptium.net/artifactory/deb bookworm main' >/etc/apt/sources.list.d/adoptium.list\n$STD apt-get update\n$STD apt-get install -y temurin-11-jdk\nmsg_ok \"Installed Eclipse Temurin\"\n\nmsg_info \"Installing Apache Cassandra\"\nwget -qO- https://downloads.apache.org/cassandra/KEYS | gpg --dearmor >/etc/apt/trusted.gpg.d/cassandra.gpg\necho \"deb https://debian.cassandra.apache.org 41x main\" >/etc/apt/sources.list.d/cassandra.sources.list\n$STD apt-get update\n$STD apt-get install -y cassandra cassandra-tools\nsed -i -e 's/^rpc_address: localhost/#rpc_address: localhost/g' -e 's/^# rpc_interface: eth1/rpc_interface: eth0/g' /etc/cassandra/cassandra.yaml\nmsg_ok \"Installed Apache Cassandra\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/apache-couchdb-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y apt-transport-https\n$STD apt-get install -y gnupg\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Apache CouchDB\"\nERLANG_COOKIE=$(openssl rand -base64 32)\nADMIN_PASS=\"$(openssl rand -base64 18 | cut -c1-13)\"\ndebconf-set-selections <<< \"couchdb couchdb/cookie string $ERLANG_COOKIE\"\ndebconf-set-selections <<< \"couchdb couchdb/mode select standalone\"\ndebconf-set-selections <<< \"couchdb couchdb/bindaddress string 0.0.0.0\"\ndebconf-set-selections <<< \"couchdb couchdb/adminpass password $ADMIN_PASS\"\ndebconf-set-selections <<< \"couchdb couchdb/adminpass_again password $ADMIN_PASS\"\ncurl -fsSL https://couchdb.apache.org/repo/keys.asc | gpg --dearmor -o /usr/share/keyrings/couchdb-archive-keyring.gpg\nVERSION_CODENAME=\"$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)\"\necho \"deb [signed-by=/usr/share/keyrings/couchdb-archive-keyring.gpg] https://apache.jfrog.io/artifactory/couchdb-deb/ ${VERSION_CODENAME} main\" >/etc/apt/sources.list.d/couchdb.sources.list\n$STD apt-get update\n$STD apt-get install -y couchdb\necho -e \"CouchDB Erlang Cookie: \\e[32m$ERLANG_COOKIE\\e[0m\" >>~/CouchDB.creds\necho -e \"CouchDB Admin Password: \\e[32m$ADMIN_PASS\\e[0m\" >>~/CouchDB.creds\nmsg_ok \"Installed Apache CouchDB.\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/apt-cacher-ng-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Apt-Cacher NG\"\nDEBIAN_FRONTEND=noninteractive $STD apt-get -o Dpkg::Options::=\"--force-confold\" install -y apt-cacher-ng\nsed -i 's/# PassThroughPattern: .* # this would allow CONNECT to everything/PassThroughPattern: .*/' /etc/apt-cacher-ng/acng.conf\nsystemctl enable -q --now apt-cacher-ng\nmsg_ok \"Installed Apt-Cacher NG\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/archivebox-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y \\\n  curl \\\n  sudo \\\n  mc \\\n  git \\\n  expect \\\n  libssl-dev \\\n  libldap2-dev \\\n  libsasl2-dev \\\n  procps \\\n  dnsutils \\\n  ripgrep\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Python Dependencies\"\n$STD apt-get install -y \\\n  python3-pip \\\n  python3-ldap \\\n  python3-msgpack \\\n  python3-regex\nmsg_ok \"Installed Python Dependencies\"\n\nmsg_info \"Setting up Node.js Repository\"\nmkdir -p /etc/apt/keyrings\ncurl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg\necho \"deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main\" >/etc/apt/sources.list.d/nodesource.list\nmsg_ok \"Set up Node.js Repository\"\n\nmsg_info \"Installing Node.js\"\n$STD apt-get update\n$STD apt-get install -y nodejs\nmsg_ok \"Installed Node.js\"\n\nmsg_info \"Installing Playright/Chromium\"\n$STD pip install playwright\n$STD playwright install --with-deps chromium\nmsg_ok \"Installed Playright/Chromium\"\n\nmsg_info \"Installing ArchiveBox\"\nmkdir -p /opt/archivebox/{data,.npm,.cache,.local}\n$STD adduser --system --shell /bin/bash --gecos 'Archive Box User' --group --disabled-password  archivebox\nchown -R archivebox:archivebox /opt/archivebox/{data,.npm,.cache,.local}\nchmod -R 755 /opt/archivebox/data\n$STD pip install archivebox\ncd /opt/archivebox/data\nexpect <<EOF\nset timeout -1\nlog_user 0\n\nspawn sudo -u archivebox archivebox setup\n\nexpect \"Username\"\nsend \"\\r\"\n\nexpect \"Email address\"\nsend \"\\r\"\n\nexpect \"Password\"\nsend \"helper-scripts.com\\r\"\n\nexpect \"Password (again)\"\nsend \"helper-scripts.com\\r\"\n\nexpect eof\nEOF\nmsg_ok \"Installed ArchiveBox\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/archivebox.service\n[Unit]\nDescription=ArchiveBox Server\nAfter=network.target\n\n[Service]\nUser=archivebox\nWorkingDirectory=/opt/archivebox/data\nExecStart=/usr/local/bin/archivebox server 0.0.0.0:8000\nRestart=always\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now archivebox.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/aria2-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Aria2\"\n$STD apt-get install -y aria2\nmsg_ok \"Installed Aria2\"\n\nread -r -p \"Would you like to add AriaNG? <y/N> \" prompt\nif [[ ${prompt,,} =~ ^(y|yes)$ ]]; then\n  msg_info \"Installing AriaNG\"\n  $STD apt-get install -y nginx\n  systemctl disable -q --now nginx\n  wget -q \"$(curl -s https://api.github.com/repos/mayswind/ariang/releases/latest | grep download | grep AllInOne.zip | cut -d\\\" -f4)\"\n  $STD unzip AriaNg-*-AllInOne.zip -d /var/www\n  rm /etc/nginx/sites-enabled/*\n  cat <<EOF >/etc/nginx/conf.d/ariang.conf\nserver {\n    listen 6880 default_server;\n    listen [::]:6880 default_server;\n\n    server_name _;\n\n    root /var/www;\n    index index.html;\n\n    location / {\n        try_files \\$uri \\$uri/ =404;\n    }\n}\nEOF\n  cp /lib/systemd/system/nginx.service /lib/systemd/system/ariang.service\n  msg_ok \"Installed AriaNG\"\nfi\n\nmsg_info \"Creating Service\"\nmkdir /root/downloads\nrpc_secret=$(openssl rand -base64 8)\necho \"rpc-secret: $rpc_secret\" >>~/rpc.secret\ncat <<EOF >/root/aria2.daemon\ndir=/root/downloads\nfile-allocation=falloc\nmax-connection-per-server=4\nmax-concurrent-downloads=2\nmax-overall-download-limit=0\nmin-split-size=25M\nrpc-allow-origin-all=true\nrpc-secret=${rpc_secret}\ninput-file=/var/tmp/aria2c.session\nsave-session=/var/tmp/aria2c.session\nEOF\n\ncat <<EOF >/etc/systemd/system/aria2.service\n[Unit]\nDescription=Aria2c download manager\nAfter=network.target\n\n[Service]\nType=simple\nUser=root\nGroup=root\nExecStartPre=/usr/bin/env touch /var/tmp/aria2c.session\nExecStart=/usr/bin/aria2c --console-log-level=warn --enable-rpc --rpc-listen-all --conf-path=/root/aria2.daemon\nTimeoutStopSec=20\nRestart=on-failure\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now aria2.service\nsystemctl enable -q --now ariang\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\nrm AriaNg-*-AllInOne.zip\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\""
  },
  {
    "path": "install/audiobookshelf-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y gnupg\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing audiobookshelf\"\ncurl -fsSL https://advplyr.github.io/audiobookshelf-ppa/KEY.gpg >/etc/apt/trusted.gpg.d/audiobookshelf-ppa.asc\necho \"deb [signed-by=/etc/apt/trusted.gpg.d/audiobookshelf-ppa.asc] https://advplyr.github.io/audiobookshelf-ppa ./\" >/etc/apt/sources.list.d/audiobookshelf.list\n$STD apt-get update\n$STD apt install audiobookshelf\nmsg_ok \"Installed audiobookshelf\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/autobrr-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Autobrr\"\nwget -q $(curl -s https://api.github.com/repos/autobrr/autobrr/releases/latest | grep download | grep linux_x86_64 | cut -d\\\" -f4)\ntar -C /usr/local/bin -xzf autobrr*.tar.gz\nrm -rf autobrr*.tar.gz\nmkdir -p /root/.config/autobrr\ncat <<EOF >>/root/.config/autobrr/config.toml\n# https://autobrr.com/configuration/autobrr\nhost = \"0.0.0.0\"\nport = 7474\nlogLevel = \"DEBUG\"\nsessionSecret = \"$(openssl rand -base64 24)\"\nEOF\nmsg_ok \"Installed Autobrr\"\n\nmsg_info \"Creating Service\"\nservice_path=\"/etc/systemd/system/autobrr.service\"\necho \"[Unit]\nDescription=autobrr service\nAfter=syslog.target network-online.target\n[Service]\nType=simple\nUser=root\nGroup=root\nExecStart=/usr/local/bin/autobrr --config=/root/.config/autobrr/\n[Install]\nWantedBy=multi-user.target\" >$service_path\nsystemctl enable --now -q autobrr.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/bazarr-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Updating Python3\"\n$STD apt-get install -y \\\n  python3 \\\n  python3-dev \\\n  python3-pip\nrm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED\nmsg_ok \"Updated Python3\"\n\nmsg_info \"Installing Bazarr\"\nmkdir -p /var/lib/bazarr/\nwget -q https://github.com/morpheus65535/bazarr/releases/latest/download/bazarr.zip\nunzip -qq bazarr -d /opt/bazarr\nchmod 775 /opt/bazarr /var/lib/bazarr/\npython3 -m pip install -q -r /opt/bazarr/requirements.txt\nmsg_ok \"Installed Bazarr\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/bazarr.service\n[Unit]\nDescription=Bazarr Daemon\nAfter=syslog.target network.target\n\n[Service]\nWorkingDirectory=/opt/bazarr/\nUMask=0002\nRestart=on-failure\nRestartSec=5\nType=simple\nExecStart=/usr/bin/python3 /opt/bazarr/bazarr.py\nKillSignal=SIGINT\nTimeoutStopSec=20\nSyslogIdentifier=bazarr\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now bazarr\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\nrm -rf bazarr.zip\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\""
  },
  {
    "path": "install/blocky-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Blocky\"\nif systemctl is-active systemd-resolved > /dev/null 2>&1; then\n  systemctl disable -q --now systemd-resolved\nfi\nmkdir /opt/blocky\nRELEASE=$(curl -s https://api.github.com/repos/0xERR0R/blocky/releases/latest | grep \"tag_name\" | awk '{print substr($2, 3, length($2)-4) }')\nwget -qO- https://github.com/0xERR0R/blocky/releases/download/v${RELEASE}/blocky_v${RELEASE}_Linux_x86_64.tar.gz | tar -xzf - -C /opt/blocky/\n\ncat <<EOF >/opt/blocky/config.yml\nupstream:\n  # these external DNS resolvers will be used. Blocky picks 2 random resolvers from the list for each query\n  # format for resolver: [net:]host:[port][/path]. net could be empty (default, shortcut for tcp+udp), tcp+udp, tcp, udp, tcp-tls or https (DoH). If port is empty, default port will be used (53 for udp and tcp, 853 for tcp-tls, 443 for https (Doh))\n  # this configuration is mandatory, please define at least one external DNS resolver\n  default:\n    # example for tcp+udp IPv4 server (https://digitalcourage.de/)\n    #- 5.9.164.112\n    # Cloudflare\n    - 1.1.1.1\n    # example for DNS-over-TLS server (DoT)\n    #- tcp-tls:fdns1.dismail.de:853\n    # example for DNS-over-HTTPS (DoH)\n    #- https://dns.digitale-gesellschaft.ch/dns-query\n  # optional: use client name (with wildcard support: * - sequence of any characters, [0-9] - range)\n  # or single ip address / client subnet as CIDR notation\n  #laptop*:\n    #- 123.123.123.123\n\n# optional: timeout to query the upstream resolver. Default: 2s\n#upstreamTimeout: 2s\n\n# optional: If true, blocky will fail to start unless at least one upstream server per group is reachable. Default: false\n#startVerifyUpstream: true\n\n# optional: Determines how blocky will create outgoing connections. This impacts both upstreams, and lists.\n# accepted: dual, v4, v6\n# default: dual\n#connectIPVersion: dual\n\n# optional: custom IP address(es) for domain name (with all sub-domains). Multiple addresses must be separated by a comma\n# example: query \"printer.lan\" or \"my.printer.lan\" will return 192.168.178.3\n#customDNS:\n  #customTTL: 1h\n  # optional: if true (default), return empty result for unmapped query types (for example TXT, MX or AAAA if only IPv4 address is defined).\n  # if false, queries with unmapped types will be forwarded to the upstream resolver\n  #filterUnmappedTypes: true\n  # optional: replace domain in the query with other domain before resolver lookup in the mapping\n  #rewrite:\n    #example.com: printer.lan\n  #mapping:\n    #printer.lan: 192.168.178.3,2001:0db8:85a3:08d3:1319:8a2e:0370:7344\n\n# optional: definition, which DNS resolver(s) should be used for queries to the domain (with all sub-domains). Multiple resolvers must be separated by a comma\n# Example: Query client.fritz.box will ask DNS server 192.168.178.1. This is necessary for local network, to resolve clients by host name\n#conditional:\n  # optional: if false (default), return empty result if after rewrite, the mapped resolver returned an empty answer. If true, the original query will be sent to the upstream resolver\n  # Example: The query \"blog.example.com\" will be rewritten to \"blog.fritz.box\" and also redirected to the resolver at 192.168.178.1. If not found and if  was set to , the original query \"blog.example.com\" will be sent upstream.\n  # Usage: One usecase when having split DNS for internal and external (internet facing) users, but not all subdomains are listed in the internal domain.\n  #fallbackUpstream: false\n  # optional: replace domain in the query with other domain before resolver lookup in the mapping\n  #rewrite:\n    #example.com: fritz.box\n  #mapping:\n    #fritz.box: 192.168.178.1\n    #lan.net: 192.168.178.1,192.168.178.2\n\n# optional: use black and white lists to block queries (for example ads, trackers, adult pages etc.)\nblocking:\n  # definition of blacklist groups. Can be external link (http/https) or local file\n  blackLists:\n    ads:\n      - https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt\n      - https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts\n      - http://sysctl.org/cameleon/hosts\n      - https://s3.amazonaws.com/lists.disconnect.me/simple_tracking.txt\n      - |\n        # inline definition with YAML literal block scalar style\n        # hosts format\n        someadsdomain.com\n    special:\n      - https://raw.githubusercontent.com/StevenBlack/hosts/master/alternates/fakenews/hosts\n  # definition of whitelist groups. Attention: if the same group has black and whitelists, whitelists will be used to disable particular blacklist entries. If a group has only whitelist entries -> this means only domains from this list are allowed, all other domains will be blocked\n  whiteLists:\n    ads:\n      - whitelist.txt\n      - |\n        # inline definition with YAML literal block scalar style\n        # hosts format\n        whitelistdomain.com\n        # this is a regex\n        /^banners?[_.-]/\n  # definition: which groups should be applied for which client\n  clientGroupsBlock:\n    # default will be used, if no special definition for a client name exists\n    default:\n      - ads\n      - special\n    # use client name (with wildcard support: * - sequence of any characters, [0-9] - range)\n    # or single ip address / client subnet as CIDR notation\n    #laptop*:\n      #- ads\n    #192.168.178.1/24:\n      #- special\n  # which response will be sent, if query is blocked:\n  # zeroIp: 0.0.0.0 will be returned (default)\n  # nxDomain: return NXDOMAIN as return code\n  # comma separated list of destination IP addresses (for example: 192.100.100.15, 2001:0db8:85a3:08d3:1319:8a2e:0370:7344). Should contain ipv4 and ipv6 to cover all query types. Useful with running web server on this address to display the \"blocked\" page.\n  blockType: zeroIp\n  # optional: TTL for answers to blocked domains\n  # default: 6h\n  blockTTL: 1m\n  # optional: automatically list refresh period (in duration format). Default: 4h.\n  # Negative value -> deactivate automatically refresh.\n  # 0 value -> use default\n  refreshPeriod: 4h\n  # optional: timeout for list download (each url). Default: 60s. Use large values for big lists or slow internet connections\n  downloadTimeout: 4m\n  # optional: Download attempt timeout. Default: 60s\n  downloadAttempts: 5\n  # optional: Time between the download attempts. Default: 1s\n  downloadCooldown: 10s\n  # optional: if failOnError, application startup will fail if at least one list can't be downloaded / opened. Default: blocking\n  #startStrategy: failOnError\n\n# optional: configuration for caching of DNS responses\ncaching:\n  # duration how long a response must be cached (min value).\n  # If <=0, use response's TTL, if >0 use this value, if TTL is smaller\n  # Default: 0\n  minTime: 5m\n  # duration how long a response must be cached (max value).\n  # If <0, do not cache responses\n  # If 0, use TTL\n  # If > 0, use this value, if TTL is greater\n  # Default: 0\n  maxTime: 30m\n  # Max number of cache entries (responses) to be kept in cache (soft limit). Useful on systems with limited amount of RAM.\n  # Default (0): unlimited\n  maxItemsCount: 0\n  # if true, will preload DNS results for often used queries (default: names queried more than 5 times in a 2-hour time window)\n  # this improves the response time for often used queries, but significantly increases external traffic\n  # default: false\n  prefetching: true\n  # prefetch track time window (in duration format)\n  # default: 120\n  prefetchExpires: 2h\n  # name queries threshold for prefetch\n  # default: 5\n  prefetchThreshold: 5\n  # Max number of domains to be kept in cache for prefetching (soft limit). Useful on systems with limited amount of RAM.\n  # Default (0): unlimited\n  #prefetchMaxItemsCount: 0\n\n# optional: configuration of client name resolution\nclientLookup:\n  # optional: this DNS resolver will be used to perform reverse DNS lookup (typically local router)\n  #upstream: 192.168.178.1\n  # optional: some routers return multiple names for client (host name and user defined name). Define which single name should be used.\n  # Example: take second name if present, if not take first name\n  #singleNameOrder:\n    #- 2\n    #- 1\n  # optional: custom mapping of client name to IP addresses. Useful if reverse DNS does not work properly or just to have custom client names.\n  #clients:\n    #laptop:\n      #- 192.168.178.29\n# optional: configuration for prometheus metrics endpoint\nprometheus:\n  # enabled if true\n  #enable: true\n  # url path, optional (default '/metrics')\n  #path: /metrics\n\n# optional: write query information (question, answer, client, duration etc.) to daily csv file\nqueryLog:\n  # optional one of: mysql, postgresql, csv, csv-client. If empty, log to console\n  #type: mysql\n  # directory (should be mounted as volume in docker) for csv, db connection string for mysql/postgresql\n  #target: db_user:db_password@tcp(db_host_or_ip:3306)/db_name?charset=utf8mb4&parseTime=True&loc=Local\n  #postgresql target: postgres://user:password@db_host_or_ip:5432/db_name\n  # if > 0, deletes log files which are older than ... days\n  #logRetentionDays: 7\n  # optional: Max attempts to create specific query log writer, default: 3\n  #creationAttempts: 1\n  # optional: Time between the creation attempts, default: 2s\n  #creationCooldown: 2s\n\n# optional: Blocky can synchronize its cache and blocking state between multiple instances through redis.\nredis:\n  # Server address and port\n  #address: redis:6379\n  # Password if necessary\n  #password: passwd\n  # Database, default: 0\n  #database: 2\n  # Connection is required for blocky to start. Default: false\n  #required: true\n  # Max connection attempts, default: 3\n  #connectionAttempts: 10\n  # Time between the connection attempts, default: 1s\n  #connectionCooldown: 3s\n\n# optional: DNS listener port(s) and bind ip address(es), default 53 (UDP and TCP). Example: 53, :53, \"127.0.0.1:5353,[::1]:5353\"\nport: 553\n# optional: Port(s) and bind ip address(es) for DoT (DNS-over-TLS) listener. Example: 853, 127.0.0.1:853\n#tlsPort: 853\n# optional: HTTPS listener port(s) and bind ip address(es), default empty = no http listener. If > 0, will be used for prometheus metrics, pprof, REST API, DoH... Example: 443, :443, 127.0.0.1:443\n#httpPort: 4000\n#httpsPort: 443\n# optional: Mininal TLS version that the DoH and DoT server will use\n#minTlsServeVersion: 1.3\n# if https port > 0: path to cert and key file for SSL encryption. if not set, self-signed certificate will be generated\n#certFile: server.crt\n#keyFile: server.key\n# optional: use this DNS server to resolve blacklist urls and upstream DNS servers. Useful if no DNS resolver is configured and blocky needs to resolve a host name. Format net:IP:port, net must be udp or tcp\n#bootstrapDns: tcp+udp:1.1.1.1\n\nfiltering:\n# optional: drop all queries with following query types. Default: empty\n  #queryTypes:\n    #- AAAA\n\n# optional: if path defined, use this file for query resolution (A, AAAA and rDNS). Default: empty\nhostsFile:\n  # optional: Path to hosts file (e.g. /etc/hosts on Linux)\n  #filePath: /etc/hosts\n  # optional: TTL, default: 1h\n  #hostsTTL: 60m\n  # optional: Time between hosts file refresh, default: 1h\n  #refreshPeriod: 30m\n  # optional: Whether loopback hosts addresses (127.0.0.0/8 and ::1) should be filtered or not, default: false\n  #filterLoopback: true\n# optional: Log level (one from debug, info, warn, error). Default: info\n#logLevel: info\n# optional: Log format (text or json). Default: text\n#logFormat: text\n# optional: log timestamps. Default: true\n#logTimestamp: true\n# optional: obfuscate log output (replace all alphanumeric characters with *) for user sensitive data like request domains or responses to increase privacy. Default: false\n#logPrivacy: false\n\n# optional: add EDE error codes to dns response\n#ede: \n  # enabled if true, Default: false\n  #enable: true\nEOF\nmsg_ok \"Installed Blocky\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/blocky.service\n[Unit]\nDescription=Blocky\nAfter=network.target\n[Service]\nUser=root\nWorkingDirectory=/opt/blocky\nExecStart=/opt/blocky/./blocky --config config.yml\n[Install]\nWantedBy=multi-user.target\nEOF\n$STD systemctl enable --now blocky\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/bunkerweb-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y gpg\n$STD apt-get install -y apt-transport-https\n$STD apt-get install -y lsb-release \nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Nginx\"\nwget -qO- https://nginx.org/keys/nginx_signing.key | gpg --dearmor >/usr/share/keyrings/nginx-archive-keyring.gpg\necho \"deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/debian $(lsb_release -cs) nginx\" >/etc/apt/sources.list.d/nginx.list\n$STD apt-get update\n$STD apt-get install -y nginx=1.26.2*\nmsg_ok \"Installed Nginx\"\n\nRELEASE=$(curl -s https://api.github.com/repos/bunkerity/bunkerweb/releases/latest | grep \"tag_name\" | awk '{print substr($2, 3, length($2)-4) }')\nmsg_info \"Installing BunkerWeb v${RELEASE} (Patience)\"\ncurl -fsSL \"https://repo.bunkerweb.io/bunkerity/bunkerweb/gpgkey\" | gpg --dearmor >/etc/apt/keyrings/bunkerity_bunkerweb-archive-keyring.gpg\necho \"deb [signed-by=/etc/apt/keyrings/bunkerity_bunkerweb-archive-keyring.gpg] https://repo.bunkerweb.io/bunkerity/bunkerweb/debian/ bookworm main\" >/etc/apt/sources.list.d/bunkerity_bunkerweb.list\n$STD apt-get update\nexport UI_WIZARD=1\n$STD apt-get install -y bunkerweb=${RELEASE}\ncat <<EOF >/etc/apt/preferences.d/bunkerweb\nPackage: bunkerweb\nPin: version ${RELEASE}\nPin-Priority: 1001\nEOF\necho \"${RELEASE}\" >/opt/${APPLICATION}_version.txt\nmsg_ok \"Installed BunkerWeb v${RELEASE}\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/caddy-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y {debian-keyring,debian-archive-keyring,apt-transport-https,gpg,curl,sudo,mc}\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Caddy\"\ncurl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg\ncurl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' >/etc/apt/sources.list.d/caddy-stable.list\n$STD apt-get update\n$STD apt-get install -y caddy\nmsg_ok \"Installed Caddy\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/calibre-web-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# Co-Author: remz1337\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y imagemagick\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Python Dependencies\"\n$STD apt-get -y install python3-pip\nrm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED\nmsg_ok \"Installed Python Dependencies\"\n\nmsg_info \"Installing Kepubify\"\nmkdir -p /opt/kepubify\ncd /opt/kepubify\ncurl -fsSLO https://github.com/pgaskin/kepubify/releases/latest/download/kepubify-linux-64bit &>/dev/null\nchmod +x kepubify-linux-64bit\nmsg_ok \"Installed Kepubify\"\n\nmsg_info \"Installing Calibre-Web\"\nmkdir -p /opt/calibre-web\n$STD wget https://github.com/janeczku/calibre-web/raw/master/library/metadata.db -P /opt/calibre-web\n$STD pip install calibreweb\n$STD pip install jsonschema\nmsg_ok \"Installed Calibre-Web\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/cps.service\n[Unit]\nDescription=Calibre-Web Server\nAfter=network.target\n\n[Service]\nType=simple\nWorkingDirectory=/opt/calibre-web\nExecStart=/usr/local/bin/cps\nTimeoutStopSec=20\nKillMode=process\nRestart=on-failure\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now cps.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/casaos-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing CasaOS (Patience)\"\nDOCKER_CONFIG_PATH='/etc/docker/daemon.json'\nmkdir -p $(dirname $DOCKER_CONFIG_PATH)\necho -e '{\\n  \"log-driver\": \"journald\"\\n}' > /etc/docker/daemon.json\n$STD bash <(curl -fsSL https://get.casaos.io/v0.4.1)\nmsg_ok \"Installed CasaOS\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/changedetection-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies (Patience)\"\n$STD apt-get install -y \\\n  curl \\\n  sudo \\\n  mc \\\n  git \\\n  build-essential \\\n  dumb-init \\\n  gconf-service \\\n  libjpeg-dev \\\n  libatk-bridge2.0-0 \\\n  libasound2 \\\n  libatk1.0-0 \\\n  libcairo2 \\\n  libcups2 \\\n  libdbus-1-3 \\\n  libexpat1 \\\n  libgbm-dev \\\n  libgbm1 \\\n  libgconf-2-4 \\\n  libgdk-pixbuf2.0-0 \\\n  libglib2.0-0 \\\n  libgtk-3-0 \\\n  libnspr4 \\\n  libnss3 \\\n  libpango-1.0-0 \\\n  libpangocairo-1.0-0 \\\n  qpdf \\\n  xdg-utils \\\n  xvfb \\\n  ca-certificates \\\n  gnupg\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Updating Python3\"\n$STD apt-get install -y \\\n  python3 \\\n  python3-dev \\\n  python3-pip\nrm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED\nmsg_ok \"Updated Python3\"\n\nmsg_info \"Setting up Node.js Repository\"\nmkdir -p /etc/apt/keyrings\ncurl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg\necho \"deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main\" >/etc/apt/sources.list.d/nodesource.list\nmsg_ok \"Set up Node.js Repository\"\n\nmsg_info \"Installing Node.js\"\n$STD apt-get update\n$STD apt-get install -y nodejs\nmsg_ok \"Installed Node.js\"\n\nmsg_info \"Installing Change Detection\"\nmkdir /opt/changedetection\n$STD pip3 install changedetection.io\nmsg_ok \"Installed Change Detection\"\n\nmsg_info \"Installing Browserless & Playwright\"\nmkdir /opt/browserless\n$STD python3 -m pip install playwright\n$STD git clone https://github.com/browserless/chrome /opt/browserless\n$STD npm install --prefix /opt/browserless\n$STD /opt/browserless/node_modules/playwright-core/cli.js install --with-deps chrome chromium firefox webkit\n$STD npm run build --prefix /opt/browserless\n$STD npm run build:function --prefix /opt/browserless\n$STD npm prune production --prefix /opt/browserless\nmsg_ok \"Installed Browserless & Playwright\"\n\nmsg_info \"Installing Font Packages\"\n$STD apt-get install -y \\\n  fontconfig \\\n  libfontconfig1 \\\n  fonts-freefont-ttf \\\n  fonts-gfs-neohellenic \\\n  fonts-indic fonts-ipafont-gothic \\\n  fonts-kacst fonts-liberation \\\n  fonts-noto-cjk \\\n  fonts-noto-color-emoji \\\n  msttcorefonts \\\n  fonts-roboto \\\n  fonts-thai-tlwg \\\n  fonts-wqy-zenhei\nmsg_ok \"Installed Font Packages\"\n\nmsg_info \"Installing X11 Packages\"\n$STD apt-get install -y \\\n  libx11-6 \\\n  libx11-xcb1 \\\n  libxcb1 \\\n  libxcomposite1 \\\n  libxcursor1 \\\n  libxdamage1 \\\n  libxext6 \\\n  libxfixes3 \\\n  libxi6 \\\n  libxrandr2 \\\n  libxrender1 \\\n  libxss1 \\\n  libxtst6\nmsg_ok \"Installed X11 Packages\"\n\nmsg_info \"Creating Services\"\ncat <<EOF >/etc/systemd/system/changedetection.service\n[Unit]\nDescription=Change Detection\nAfter=network-online.target\nAfter=network.target browserless.service\nWants=browserless.service\n[Service]\nType=simple\nWorkingDirectory=/opt/changedetection\nEnvironment=WEBDRIVER_URL=http://127.0.0.1:4444/wd/hub\nEnvironment=PLAYWRIGHT_DRIVER_URL=ws://localhost:3000/chrome?launch={\"defaultViewport\":{\"height\":720,\"width\":1280},\"headless\":false,\"stealth\":true}&blockAds=true\nExecStart=changedetection.io -d /opt/changedetection -p 5000\n[Install]\nWantedBy=multi-user.target\nEOF\n\ncat <<EOF >/etc/systemd/system/browserless.service\n[Unit]\nDescription=browserless service\nAfter=network.target\n[Service]\nWorkingDirectory=/opt/browserless\nExecStart=/opt/browserless/scripts/start.sh\nSyslogIdentifier=browserless\n[Install]\nWantedBy=default.target\nEOF\n\nsystemctl enable -q --now browserless\nsystemctl enable -q --now changedetection\nmsg_ok \"Created Services\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/channels-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y chromium\n$STD apt-get install -y xvfb\nmsg_ok \"Installed Dependencies\"\n\nif [[ \"$CTTYPE\" == \"0\" ]]; then\n  msg_info \"Setting Up Hardware Acceleration\"\n  $STD apt-get -y install \\\n    va-driver-all \\\n    ocl-icd-libopencl1 \\\n    intel-opencl-icd\n  chgrp video /dev/dri\n  chmod 755 /dev/dri\n  chmod 660 /dev/dri/*\n  $STD adduser $(id -u -n) video\n  $STD adduser $(id -u -n) render\n  msg_ok \"Set Up Hardware Acceleration\"\nfi\n\nmsg_info \"Installing Channels DVR Server (Patience)\"\ncd /opt\n$STD bash <(curl -fsSL https://getchannels.com/dvr/setup.sh)\nsed -i -e 's/^sgx:x:104:$/render:x:104:root/' -e 's/^render:x:106:root$/sgx:x:106:/' /etc/group\nmsg_ok \"Installed Channels DVR Server\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/cloudflared-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Cloudflared\"\nmkdir -p --mode=0755 /usr/share/keyrings\nVERSION=\"$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)\"\ncurl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg >/usr/share/keyrings/cloudflare-main.gpg\necho \"deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared $VERSION main\" >/etc/apt/sources.list.d/cloudflared.list\n$STD apt-get update\n$STD apt-get install -y cloudflared\nmsg_ok \"Installed Cloudflared\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/cockpit-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck\n# Co-Author: havardthom\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n# Source: https://github.com/cockpit-project/cockpit\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Cockpit\"\nsource /etc/os-release\necho \"deb http://deb.debian.org/debian ${VERSION_CODENAME}-backports main\" >/etc/apt/sources.list.d/backports.list\n$STD apt-get update\n$STD apt-get install -t ${VERSION_CODENAME}-backports cockpit --no-install-recommends -y\nsed -i \"s/root//g\" /etc/cockpit/disallowed-users\nmsg_ok \"Installed Cockpit\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/commafeed-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y rsync\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Azul Zulu\"\nwget -qO /etc/apt/trusted.gpg.d/zulu-repo.asc \"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xB1998361219BD9C9\"\nwget -q https://cdn.azul.com/zulu/bin/zulu-repo_1.0.0-3_all.deb\n$STD dpkg -i zulu-repo_1.0.0-3_all.deb\n$STD apt-get update\n$STD apt-get -y install zulu17-jdk\nmsg_ok \"Installed Azul Zulu\"\n\nRELEASE=$(curl -sL https://api.github.com/repos/Athou/commafeed/releases/latest | grep '\"tag_name\":' | cut -d'\"' -f4)\nmsg_info \"Installing CommaFeed ${RELEASE}\"\nmkdir /opt/commafeed\nwget -q https://github.com/Athou/commafeed/releases/download/${RELEASE}/commafeed-${RELEASE}-h2-jvm.zip\nunzip -q commafeed-${RELEASE}-h2-jvm.zip\nmv commafeed-${RELEASE}-h2/* /opt/commafeed/\necho \"${RELEASE}\" >/opt/${APPLICATION}_version.txt\nmsg_ok \"Installed CommaFeed ${RELEASE}\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/commafeed.service\n[Unit]\nDescription=CommaFeed Service\nAfter=network.target\n\n[Service]\nExecStart=java -jar quarkus-run.jar\nWorkingDirectory=/opt/commafeed/\nRestart=always\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now commafeed.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\nrm -rf commafeed-${RELEASE}-h2  commafeed-${RELEASE}-h2-jvm.zip  zulu-repo_1.0.0-3_all.deb\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/cronicle-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y git\n$STD apt-get install -y make\n$STD apt-get install -y g++\n$STD apt-get install -y gcc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Node.js\"\n$STD bash <(curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh)\n. ~/.bashrc\n$STD nvm install 16.20.1\nln -sf /root/.nvm/versions/node/v16.20.1/bin/node /usr/bin/node\nmsg_ok \"Installed Node.js\"\n\nmsg_info \"Installing Cronicle Primary Server\"\nLATEST=$(curl -sL https://api.github.com/repos/jhuckaby/Cronicle/releases/latest | grep '\"tag_name\":' | cut -d'\"' -f4)\nIP=$(hostname -I | awk '{print $1}')\nmkdir -p /opt/cronicle\ncd /opt/cronicle\n$STD tar zxvf <(curl -fsSL https://github.com/jhuckaby/Cronicle/archive/${LATEST}.tar.gz) --strip-components 1\n$STD npm install\n$STD node bin/build.js dist\nsed -i \"s/localhost:3012/${IP}:3012/g\" /opt/cronicle/conf/config.json\n$STD /opt/cronicle/bin/control.sh setup\n$STD /opt/cronicle/bin/control.sh start\n$STD cp /opt/cronicle/bin/cronicled.init /etc/init.d/cronicled\nchmod 775 /etc/init.d/cronicled\n$STD update-rc.d cronicled defaults\nmsg_ok \"Installed Cronicle Primary Server\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/daemonsync-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y g++-multilib\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Daemon Sync Server\"\nwget -qL https://github.com/tteck/Proxmox/raw/main/misc/daemonsync_2.2.0.0059_amd64.deb\n$STD dpkg -i daemonsync_2.2.0.0059_amd64.deb\nmsg_ok \"Installed Daemon Sync Server\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\nrm -rf daemonsync_2.2.0.0059_amd64.deb\n$STD apt-get autoremove >/dev/null\n$STD apt-get autoclean >/dev/null\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/dashy-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y gpg\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Setting up Node.js Repository\"\nmkdir -p /etc/apt/keyrings\ncurl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg\necho \"deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main\" >/etc/apt/sources.list.d/nodesource.list\nmsg_ok \"Set up Node.js Repository\"\n\nmsg_info \"Installing Node.js\"\n$STD apt-get update\n$STD apt-get install -y nodejs\nmsg_ok \"Installed Node.js\"\n\nRELEASE=$(curl -s https://api.github.com/repos/Lissy93/dashy/releases/latest | grep \"tag_name\" | awk '{print substr($2, 2, length($2)-3) }')\nmsg_info \"Installing Dashy ${RELEASE} (Patience)\"\nmkdir -p /opt/dashy\nwget -qO- https://github.com/Lissy93/dashy/archive/refs/tags/${RELEASE}.tar.gz | tar -xz -C /opt/dashy --strip-components=1\ncd /opt/dashy\n$STD npm install\n$STD npm run build\necho \"${RELEASE}\" >/opt/${APPLICATION}_version.txt\nmsg_ok \"Installed Dashy ${RELEASE}\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/dashy.service\n[Unit]\nDescription=dashy\n\n[Service]\nType=simple\nWorkingDirectory=/opt/dashy\nExecStart=/usr/bin/npm start\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl -q --now enable dashy\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/debian-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\""
  },
  {
    "path": "install/deconz-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Setting Phoscon Repository\"\nVERSION=\"$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)\"\ncurl -fsSL http://phoscon.de/apt/deconz.pub.key >/etc/apt/trusted.gpg.d/deconz.pub.asc\necho \"deb [arch=amd64] http://phoscon.de/apt/deconz $VERSION main\" >/etc/apt/sources.list.d/deconz.list\nmsg_ok \"Setup Phoscon Repository\"\n\nmsg_info \"Installing deConz\"\nlibssl=$(curl -fsSL \"http://security.ubuntu.com/ubuntu/pool/main/o/openssl/\" | grep -o 'libssl1\\.1_1\\.1\\.1f-1ubuntu2\\.2[^\"]*amd64\\.deb' | head -n1)\nwget -qL http://security.ubuntu.com/ubuntu/pool/main/o/openssl/$libssl\n$STD dpkg -i $libssl\n$STD apt-get update\n$STD apt-get install -y deconz\nmsg_ok \"Installed deConz\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/lib/systemd/system/deconz.service\n[Unit]\nDescription=deCONZ: ZigBee gateway -- REST API\nWants=deconz-init.service deconz-update.service\nStartLimitIntervalSec=0\n\n[Service]\nUser=root\nExecStart=/usr/bin/deCONZ -platform minimal --http-port=80\nRestart=on-failure\nRestartSec=30\nAmbientCapabilities=CAP_NET_BIND_SERVICE CAP_KILL CAP_SYS_BOOT CAP_SYS_TIME\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now deconz\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\nrm -rf $libssl\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/deluge-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y python3-libtorrent\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Updating Python3\"\n$STD apt-get install -y \\\n  python3 \\\n  python3-dev \\\n  python3-pip\nrm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED\nmsg_ok \"Updated Python3\"\n\nmsg_info \"Installing Deluge\"\n$STD pip install deluge[all]\nmsg_ok \"Installed Deluge\"\n\nmsg_info \"Creating Service\"\nservice_path=\"/etc/systemd/system/deluged.service\"\necho \"[Unit]\nDescription=Deluge Bittorrent Client Daemon\nDocumentation=man:deluged\nAfter=network-online.target\n\n[Service]\nType=simple\nUMask=007\nExecStart=/usr/local/bin/deluged -d\nRestart=on-failure\nTimeoutStopSec=300\n\n[Install]\nWantedBy=multi-user.target\" >$service_path\n\nservice_path=\"/etc/systemd/system/deluge-web.service\"\necho \"[Unit]\nDescription=Deluge Bittorrent Client Web Interface\nDocumentation=man:deluge-web\nAfter=deluged.service\nWants=deluged.service\n\n[Service]\nType=simple\nUMask=027\nExecStart=/usr/local/bin/deluge-web -d\nRestart=on-failure\n\n[Install]\nWantedBy=multi-user.target\" >$service_path\nsystemctl enable --now -q deluged.service\nsystemctl enable --now -q deluge-web.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/docker-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<<\"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nget_latest_release() {\n  curl -sL https://api.github.com/repos/$1/releases/latest | grep '\"tag_name\":' | cut -d'\"' -f4\n}\n\nDOCKER_LATEST_VERSION=$(get_latest_release \"moby/moby\")\nPORTAINER_LATEST_VERSION=$(get_latest_release \"portainer/portainer\")\nPORTAINER_AGENT_LATEST_VERSION=$(get_latest_release \"portainer/agent\")\nDOCKER_COMPOSE_LATEST_VERSION=$(get_latest_release \"docker/compose\")\n\nmsg_info \"Installing Docker $DOCKER_LATEST_VERSION\"\nDOCKER_CONFIG_PATH='/etc/docker/daemon.json'\nmkdir -p $(dirname $DOCKER_CONFIG_PATH)\necho -e '{\\n  \"log-driver\": \"journald\"\\n}' >/etc/docker/daemon.json\n$STD sh <(curl -sSL https://get.docker.com)\nmsg_ok \"Installed Docker $DOCKER_LATEST_VERSION\"\n\nread -r -p \"Would you like to add Portainer? <y/N> \" prompt\nif [[ ${prompt,,} =~ ^(y|yes)$ ]]; then\n  msg_info \"Installing Portainer $PORTAINER_LATEST_VERSION\"\n  docker volume create portainer_data >/dev/null\n  $STD docker run -d \\\n    -p 8000:8000 \\\n    -p 9443:9443 \\\n    --name=portainer \\\n    --restart=always \\\n    -v /var/run/docker.sock:/var/run/docker.sock \\\n    -v portainer_data:/data \\\n    portainer/portainer-ce:latest\n  msg_ok \"Installed Portainer $PORTAINER_LATEST_VERSION\"\nelse\n  read -r -p \"Would you like to add the Portainer Agent? <y/N> \" prompt\n  if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then\n    msg_info \"Installing Portainer agent $PORTAINER_AGENT_LATEST_VERSION\"\n    $STD docker run -d \\\n      -p 9001:9001 \\\n      --name portainer_agent \\\n      --restart=always \\\n      -v /var/run/docker.sock:/var/run/docker.sock \\\n      -v /var/lib/docker/volumes:/var/lib/docker/volumes \\\n      portainer/agent\n    msg_ok \"Installed Portainer Agent $PORTAINER_AGENT_LATEST_VERSION\"\n  fi\nfi\nread -r -p \"Would you like to add Docker Compose? <y/N> \" prompt\nif [[ ${prompt,,} =~ ^(y|yes)$ ]]; then\n  msg_info \"Installing Docker Compose $DOCKER_COMPOSE_LATEST_VERSION\"\n  DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker}\n  mkdir -p $DOCKER_CONFIG/cli-plugins\n  curl -sSL https://github.com/docker/compose/releases/download/$DOCKER_COMPOSE_LATEST_VERSION/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose\n  chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose\n  msg_ok \"Installed Docker Compose $DOCKER_COMPOSE_LATEST_VERSION\"\nfi\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/dockge-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<<\"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nget_latest_release() {\n  curl -sL https://api.github.com/repos/$1/releases/latest | grep '\"tag_name\":' | cut -d'\"' -f4\n}\n\nDOCKER_LATEST_VERSION=$(get_latest_release \"moby/moby\")\nDOCKER_COMPOSE_LATEST_VERSION=$(get_latest_release \"docker/compose\")\n\nmsg_info \"Installing Docker $DOCKER_LATEST_VERSION\"\nDOCKER_CONFIG_PATH='/etc/docker/daemon.json'\nmkdir -p $(dirname $DOCKER_CONFIG_PATH)\necho -e '{\\n  \"log-driver\": \"journald\"\\n}' >/etc/docker/daemon.json\n$STD sh <(curl -sSL https://get.docker.com)\nmsg_ok \"Installed Docker $DOCKER_LATEST_VERSION\"\n\nmsg_info \"Installing Docker Compose $DOCKER_COMPOSE_LATEST_VERSION\"\nDOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker}\nmkdir -p $DOCKER_CONFIG/cli-plugins\ncurl -sSL https://github.com/docker/compose/releases/download/$DOCKER_COMPOSE_LATEST_VERSION/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose\nchmod +x $DOCKER_CONFIG/cli-plugins/docker-compose\nmsg_ok \"Installed Docker Compose $DOCKER_COMPOSE_LATEST_VERSION\"\n\nmsg_info \"Installing Dockge\"\nmkdir -p /opt/{dockge,stacks}\nwget -q -O /opt/dockge/compose.yaml https://raw.githubusercontent.com/louislam/dockge/master/compose.yaml\ncd /opt/dockge\n$STD docker compose up -d\nmsg_ok \"Installed Dockge\"\n\nread -r -p \"Would you like to add Immich? <y/N> \" prompt\nif [[ ${prompt,,} =~ ^(y|yes)$ ]]; then\n  msg_info \"Adding Immich compose.yaml\"\n  mkdir -p /opt/stacks/immich\n  wget -q -O /opt/stacks/immich/compose.yaml https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml\n  wget -q -O /opt/stacks/immich/.env https://github.com/immich-app/immich/releases/latest/download/example.env\n  #wget -q -O /opt/stacks/immich/hwaccel.ml.yml https://github.com/immich-app/immich/releases/latest/download/hwaccel.ml.yml\n  msg_ok \"Added Immich compose.yaml\"\nfi\n\nread -r -p \"Would you like to add Home Assistant? <y/N> \" prompt\nif [[ ${prompt,,} =~ ^(y|yes)$ ]]; then\n  msg_info \"Adding Home Assistant compose.yaml\"\n  mkdir -p /opt/stacks/homeassistant\n  cat <<EOF >/opt/stacks/homeassistant/compose.yaml\nversion: \"3\"\nservices:\n  homeassistant:\n    container_name: homeassistant\n    image: ghcr.io/home-assistant/home-assistant:stable\n    volumes:\n      - ./config:/config\n      - /etc/localtime:/etc/localtime:ro\n      - /run/dbus:/run/dbus:ro\n    restart: unless-stopped\n    privileged: true\n    network_mode: host\nEOF\nmsg_ok \"Added Home Assistant compose.yaml\"\nfi\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/emby-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Setting Up Hardware Acceleration\"\n$STD apt-get -y install {va-driver-all,ocl-icd-libopencl1,intel-opencl-icd,vainfo,intel-gpu-tools}\nif [[ \"$CTTYPE\" == \"0\" ]]; then\n  chgrp video /dev/dri\n  chmod 755 /dev/dri\n  chmod 660 /dev/dri/*\n  $STD adduser $(id -u -n) video\n  $STD adduser $(id -u -n) render\nfi\nmsg_ok \"Set Up Hardware Acceleration\"\n\nLATEST=$(curl -sL https://api.github.com/repos/MediaBrowser/Emby.Releases/releases/latest | grep '\"tag_name\":' | cut -d'\"' -f4)\n\nmsg_info \"Installing Emby\"\nwget -q https://github.com/MediaBrowser/Emby.Releases/releases/download/${LATEST}/emby-server-deb_${LATEST}_amd64.deb\n$STD dpkg -i emby-server-deb_${LATEST}_amd64.deb\nif [[ \"$CTTYPE\" == \"0\" ]]; then\n  sed -i -e 's/^ssl-cert:x:104:$/render:x:104:root,emby/' -e 's/^render:x:108:root,emby$/ssl-cert:x:108:/' /etc/group\nelse\n  sed -i -e 's/^ssl-cert:x:104:$/render:x:104:emby/' -e 's/^render:x:108:emby$/ssl-cert:x:108:/' /etc/group\nfi\nmsg_ok \"Installed Emby\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nrm emby-server-deb_${LATEST}_amd64.deb\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/emqx-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing EMQX\"\n$STD bash <(curl -fsSL https://packagecloud.io/install/repositories/emqx/emqx/script.deb.sh)\n$STD apt-get install -y emqx\n$STD systemctl enable --now emqx\nmsg_ok \"Installed EMQX\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\napt-get autoremove >/dev/null\napt-get autoclean >/dev/null\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/ersatztv-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck\n# Co-Author: MickLesk (Canbiz)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n# Source: https://github.com/ErsatzTV/ErsatzTV\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing FFmpeg (Patience)\"\nwget -q https://www.deb-multimedia.org/pool/main/d/deb-multimedia-keyring/deb-multimedia-keyring_2016.8.1_all.deb\n$STD dpkg -i deb-multimedia-keyring_2016.8.1_all.deb\ncat <<EOF >/etc/apt/sources.list.d/backports.list\ndeb https://www.deb-multimedia.org bookworm main non-free\ndeb https://www.deb-multimedia.org bookworm-backports main\nEOF\n$STD apt update\nDEBIAN_FRONTEND=noninteractive $STD apt-get install -t bookworm-backports ffmpeg -y\nrm -rf /etc/apt/sources.list.d/backports.list deb-multimedia-keyring_2016.8.1_all.deb\n$STD apt update\nmsg_ok \"Installed FFmpeg\"\n\nmsg_info \"Setting Up Hardware Acceleration\"\n$STD apt-get -y install {va-driver-all,ocl-icd-libopencl1,intel-opencl-icd,vainfo,intel-gpu-tools}\nif [[ \"$CTTYPE\" == \"0\" ]]; then\n  chgrp video /dev/dri\n  chmod 755 /dev/dri\n  chmod 660 /dev/dri/*\n  $STD adduser $(id -u -n) video\n  $STD adduser $(id -u -n) render\nfi\nmsg_ok \"Set Up Hardware Acceleration\"\n\nmsg_info \"Installing ErsatzTV\" \nRELEASE=$(curl -s https://api.github.com/repos/ErsatzTV/ErsatzTV/releases | grep -oP '\"tag_name\": \"\\K[^\"]+' | head -n 1)\nwget -qO- \"https://github.com/ErsatzTV/ErsatzTV/releases/download/${RELEASE}/ErsatzTV-${RELEASE}-linux-x64.tar.gz\" | tar -xz -C /opt\nmv \"/opt/ErsatzTV-${RELEASE}-linux-x64\" /opt/ErsatzTV\nmsg_ok \"Installed ErsatzTV\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/ersatzTV.service\n[Unit]\nDescription=ErsatzTV Service\nAfter=multi-user.target\n\n[Service]\nType=simple\nUser=root\nWorkingDirectory=/opt/ErsatzTV \nExecStart=/opt/ErsatzTV/ErsatzTV  \nRestart=always\nRestartSec=30\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl -q --now enable ersatzTV.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/esphome-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<<\"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y git\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Updating Python3\"\n$STD apt-get install -y \\\n  python3 \\\n  python3-dev \\\n  python3-pip \\\n  python3-venv\nrm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED\nmsg_ok \"Updated Python3\"\n\nmsg_info \"Installing ESPHome\"\nmkdir /root/config\n$STD pip install esphome tornado esptool\nmsg_ok \"Installed ESPHome\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/esphomeDashboard.service\n[Unit]\nDescription=ESPHome Dashboard\nAfter=network.target\n\n[Service]\nExecStart=/usr/local/bin/esphome dashboard /root/config/\nRestart=always\nUser=root\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now esphomeDashboard.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/evcc-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck\n# Co-Author: MickLesk (Canbiz)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n# Source: https://github.com/evcc-io/evcc\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y \\\n  curl \\\n  sudo \\\n  mc \\\n  lsb-release \\\n  gpg \nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Setting up evcc Repository\"\ncurl -fsSL https://dl.evcc.io/public/evcc/stable/gpg.EAD5D0E07B0EC0FD.key | gpg --dearmor -o /etc/apt/keyrings/evcc-stable.gpg \necho \"deb [signed-by=/etc/apt/keyrings/evcc-stable.gpg] https://dl.evcc.io/public/evcc/stable/deb/debian $(lsb_release -cs) main\" >/etc/apt/sources.list.d/evcc-stable.list \n$STD apt update\nmsg_ok \"evcc Repository setup sucessfully\"\n\nmsg_info \"Installing evcc\"\n$STD apt install -y evcc\nsystemctl enable -q --now evcc.service\nmsg_ok \"Installed evcc\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/fenrus-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# Co-Author: Scorpoon\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n# Source: https://github.com/revenz/Fenrus\n\n\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y curl\n$STD apt-get install -y git\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing ASP.NET Core 7 SDK\"\nvar_os=$(grep \"^ID=\" /etc/os-release | cut -d'=' -f2 | tr -d '\"')\nvar_version=$(grep \"^VERSION_ID=\" /etc/os-release | cut -d'=' -f2 | tr -d '\"')\nif [ \"${var_os}\" = \"debian\" ]; then\n  wget -q \"https://packages.microsoft.com/config/debian/$var_version/packages-microsoft-prod.deb\"\n  $STD dpkg -i packages-microsoft-prod.deb\n  rm packages-microsoft-prod.deb\nfi\n$STD apt-get update\n$STD apt-get install -y dotnet-sdk-7.0\nmsg_ok \"Installed ASP.NET Core 7 SDK\"\n\nmsg_info \"Installing ${APPLICATION}\"\ngit clone -q https://github.com/revenz/Fenrus.git /opt/${APPLICATION}\ncd /opt/${APPLICATION}\n$STD dotnet publish -c Release -o \"/opt/${APPLICATION}/\" Fenrus.csproj\nmsg_ok \"Installed ${APPLICATION}\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/\"${APPLICATION}\".service\n[Unit]\nDescription=${APPLICATION}\n\n[Service]\nWorkingDirectory=/opt/${APPLICATION}\nExecStart=/usr/bin/dotnet Fenrus.dll --urls=http://*:5000\nSyslogIdentifier=${APPLICATION}\nUser=root\n\n[Install]\nWantedBy=multi-user.target\nEOF\n$STD systemctl enable -q --now ${APPLICATION}\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/fhem-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y avahi-daemon\n$STD apt-get install -y gnupg2\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Setting up Fhem Repository\"\ncurl -sSf https://debian.fhem.de/archive.key | gpg --dearmor >/etc/apt/trusted.gpg.d/debianfhemde-archive-keyring.gpg\necho 'deb [signed-by=/etc/apt/trusted.gpg.d/debianfhemde-archive-keyring.gpg] https://debian.fhem.de/nightly/ /' >/etc/apt/sources.list.d/fhem.list\nmsg_ok \"Set up Fhem Repository\"\n\nmsg_info \"Installing Fhem\"\n$STD apt-get update\n$STD apt-get install -y fhem\nmsg_info \"Installed Fhem\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/flaresolverr-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# Co-Author: remz1337\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y apt-transport-https\n$STD apt-get install -y gpg\n$STD apt-get install -y xvfb\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Chrome\"\nwget -qO- https://dl.google.com/linux/linux_signing_key.pub | gpg --dearmor -o /usr/share/keyrings/google-chrome.gpg\necho \"deb [arch=amd64 signed-by=/usr/share/keyrings/google-chrome.gpg] http://dl.google.com/linux/chrome/deb/ stable main\" > /etc/apt/sources.list.d/google-chrome.list\n$STD apt update\n$STD apt install -y google-chrome-stable\nmsg_ok \"Installed Chrome\"\n\nmsg_info \"Installing FlareSolverr\"\nRELEASE=$(wget -q https://github.com/FlareSolverr/FlareSolverr/releases/latest -O - | grep \"title>Release\" | cut -d \" \" -f 4)\n$STD wget -q https://github.com/FlareSolverr/FlareSolverr/releases/download/$RELEASE/flaresolverr_linux_x64.tar.gz\n$STD tar -xzf flaresolverr_linux_x64.tar.gz -C /opt\n$STD rm flaresolverr_linux_x64.tar.gz\necho \"${RELEASE}\" >/opt/${APPLICATION}_version.txt\nmsg_ok \"Installed FlareSolverr\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/flaresolverr.service\n[Unit]\nDescription=FlareSolverr\nAfter=network.target\n[Service]\nSyslogIdentifier=flaresolverr\nRestart=always\nRestartSec=5\nType=simple\nEnvironment=\"LOG_LEVEL=info\"\nEnvironment=\"CAPTCHA_SOLVER=none\"\nWorkingDirectory=/opt/flaresolverr\nExecStart=/opt/flaresolverr/flaresolverr\nTimeoutStopSec=30\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now flaresolverr.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/flowiseai-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y gpg\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Node.js\"\nmkdir -p /etc/apt/keyrings\ncurl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg\necho \"deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main\" >/etc/apt/sources.list.d/nodesource.list\n$STD apt-get update\n$STD apt-get install -y nodejs\nmsg_ok \"Installed Node.js\"\n\nmsg_info \"Installing FlowiseAI (Patience)\"\n$STD npm install -g flowise\nmkdir -p /opt/flowiseai\nwget -q https://raw.githubusercontent.com/FlowiseAI/Flowise/main/packages/server/.env.example -O /opt/flowiseai/.env\nmsg_ok \"Installed FlowiseAI\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/flowise.service\n[Unit]\nDescription=FlowiseAI\nAfter=network.target\n\n[Service]\nEnvironmentFile=/opt/flowiseai/.env\nExecStart=npx flowise start\nRestart=always\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now flowise.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/forgejo-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y git\n$STD apt-get install -y git-lfs\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Forgejo\"\nmkdir -p /opt/forgejo\nRELEASE=$(curl -s https://codeberg.org/api/v1/repos/forgejo/forgejo/releases/latest | grep -oP '\"tag_name\":\\s*\"\\K[^\"]+' | sed 's/^v//')\nwget -qO /opt/forgejo/forgejo-$RELEASE-linux-amd64 \"https://codeberg.org/forgejo/forgejo/releases/download/v${RELEASE}/forgejo-${RELEASE}-linux-amd64\"\nchmod +x /opt/forgejo/forgejo-$RELEASE-linux-amd64\nln -sf /opt/forgejo/forgejo-$RELEASE-linux-amd64 /usr/local/bin/forgejo\nmsg_ok \"Installed Forgejo\"\n\nmsg_info \"Setting up Forgejo\"\n$STD adduser --system --shell /bin/bash --gecos 'Git Version Control' --group --disabled-password --home /home/git  git\nmkdir /var/lib/forgejo\nchown git:git /var/lib/forgejo\nchmod 750 /var/lib/forgejo\nmkdir /etc/forgejo\nchown root:git /etc/forgejo\nchmod 770 /etc/forgejo\nmsg_ok \"Setup Forgejo\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/forgejo.service\n[Unit]\nDescription=Forgejo\nAfter=syslog.target\nAfter=network.target\n[Service]\nRestartSec=2s\nType=simple\nUser=git\nGroup=git\nWorkingDirectory=/var/lib/forgejo/ \nExecStart=/usr/local/bin/forgejo web --config /etc/forgejo/app.ini\nRestart=always\nEnvironment=USER=git HOME=/home/git GITEA_WORK_DIR=/var/lib/forgejo\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now forgejo\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/frigate-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# Co-Author: remz1337\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<<\"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies (Patience)\"\n$STD apt-get install -y {curl,sudo,mc,git,gpg,automake,build-essential,xz-utils,libtool,ccache,pkg-config,libgtk-3-dev,libavcodec-dev,libavformat-dev,libswscale-dev,libv4l-dev,libxvidcore-dev,libx264-dev,libjpeg-dev,libpng-dev,libtiff-dev,gfortran,openexr,libatlas-base-dev,libssl-dev,libtbb2,libtbb-dev,libdc1394-22-dev,libopenexr-dev,libgstreamer-plugins-base1.0-dev,libgstreamer1.0-dev,gcc,gfortran,libopenblas-dev,liblapack-dev,libusb-1.0-0-dev,jq,moreutils}\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Python3 Dependencies\"\n$STD apt-get install -y {python3,python3-dev,python3-setuptools,python3-distutils,python3-pip}\n$STD pip install --upgrade pip\nmsg_ok \"Installed Python3 Dependencies\"\n\nmsg_info \"Installing Node.js\"\nmkdir -p /etc/apt/keyrings\ncurl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg\necho \"deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main\" >/etc/apt/sources.list.d/nodesource.list\n$STD apt-get update\n$STD apt-get install -y nodejs\nmsg_ok \"Installed Node.js\"\n\nmsg_info \"Installing go2rtc\"\nmkdir -p /usr/local/go2rtc/bin\ncd /usr/local/go2rtc/bin\nwget -qO go2rtc \"https://github.com/AlexxIT/go2rtc/releases/latest/download/go2rtc_linux_amd64\"\nchmod +x go2rtc\n$STD ln -svf /usr/local/go2rtc/bin/go2rtc /usr/local/bin/go2rtc\nmsg_ok \"Installed go2rtc\"\n\nmsg_info \"Setting Up Hardware Acceleration\"\n$STD apt-get -y install {va-driver-all,ocl-icd-libopencl1,intel-opencl-icd,vainfo,intel-gpu-tools}\nif [[ \"$CTTYPE\" == \"0\" ]]; then\n  chgrp video /dev/dri\n  chmod 755 /dev/dri\n  chmod 660 /dev/dri/*\nfi\nmsg_ok \"Set Up Hardware Acceleration\"\n\nRELEASE=$(curl -s https://api.github.com/repos/blakeblackshear/frigate/releases/latest | jq -r '.tag_name')\nmsg_ok \"Stop spinner to prevent segmentation fault\"\nmsg_info \"Installing Frigate $RELEASE (Perseverance)\"\nif [ -n \"$SPINNER_PID\" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi\ncd ~\nmkdir -p /opt/frigate/models\nwget -q https://github.com/blakeblackshear/frigate/archive/refs/tags/${RELEASE}.tar.gz -O frigate.tar.gz\ntar -xzf frigate.tar.gz -C /opt/frigate --strip-components 1\nrm -rf frigate.tar.gz\ncd /opt/frigate\n$STD pip3 wheel --wheel-dir=/wheels -r /opt/frigate/docker/main/requirements-wheels.txt\ncp -a /opt/frigate/docker/main/rootfs/. /\nexport TARGETARCH=\"amd64\"\necho 'libc6 libraries/restart-without-asking boolean true' | debconf-set-selections\n$STD /opt/frigate/docker/main/install_deps.sh\n$STD apt update\n$STD ln -svf /usr/lib/btbn-ffmpeg/bin/ffmpeg /usr/local/bin/ffmpeg\n$STD ln -svf /usr/lib/btbn-ffmpeg/bin/ffprobe /usr/local/bin/ffprobe\n$STD pip3 install -U /wheels/*.whl\nldconfig\n$STD pip3 install -r /opt/frigate/docker/main/requirements-dev.txt\n$STD /opt/frigate/.devcontainer/initialize.sh\n$STD make version\ncd /opt/frigate/web\n$STD npm install\n$STD npm run build\ncp -r /opt/frigate/web/dist/* /opt/frigate/web/\ncp -r /opt/frigate/config/. /config\nsed -i '/^s6-svc -O \\.$/s/^/#/' /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/frigate/run\ncat <<EOF >/config/config.yml\nmqtt:\n  enabled: false\ncameras:\n  test:\n    ffmpeg:\n      #hwaccel_args: preset-vaapi\n      inputs:\n        - path: /media/frigate/person-bicycle-car-detection.mp4\n          input_args: -re -stream_loop -1 -fflags +genpts\n          roles:\n            - detect\n            - rtmp\n    detect:\n      height: 1080\n      width: 1920\n      fps: 5\nEOF\nln -sf /config/config.yml /opt/frigate/config/config.yml\nif [[ \"$CTTYPE\" == \"0\" ]]; then\n  sed -i -e 's/^kvm:x:104:$/render:x:104:root,frigate/' -e 's/^render:x:105:root$/kvm:x:105:/' /etc/group\nelse\n  sed -i -e 's/^kvm:x:104:$/render:x:104:frigate/' -e 's/^render:x:105:$/kvm:x:105:/' /etc/group\nfi\necho \"tmpfs   /tmp/cache      tmpfs   defaults        0       0\" >> /etc/fstab\nmsg_ok \"Installed Frigate $RELEASE\"\n\nif grep -q -o -m1 'avx[^ ]*' /proc/cpuinfo; then\n  msg_ok \"AVX Support Detected\"\n  msg_info \"Installing Openvino Object Detection Model (Resilience)\"\n  $STD pip install -r /opt/frigate/docker/main/requirements-ov.txt\n  cd /opt/frigate/models\n  export ENABLE_ANALYTICS=NO\n  $STD /usr/local/bin/omz_downloader --name ssdlite_mobilenet_v2 --num_attempts 2\n  $STD /usr/local/bin/omz_converter --name ssdlite_mobilenet_v2 --precision FP16 --mo /usr/local/bin/mo\n  cd /\n  cp -r /opt/frigate/models/public/ssdlite_mobilenet_v2 openvino-model\n  wget -q https://github.com/openvinotoolkit/open_model_zoo/raw/master/data/dataset_classes/coco_91cl_bkgr.txt -O openvino-model/coco_91cl_bkgr.txt\n  sed -i 's/truck/car/g' openvino-model/coco_91cl_bkgr.txt\n  cat <<EOF >>/config/config.yml\ndetectors:\n  ov:\n    type: openvino\n    device: CPU\n    model:\n      path: /openvino-model/FP16/ssdlite_mobilenet_v2.xml\nmodel:\n  width: 300\n  height: 300\n  input_tensor: nhwc\n  input_pixel_format: bgr\n  labelmap_path: /openvino-model/coco_91cl_bkgr.txt\nEOF\n  msg_ok \"Installed Openvino Object Detection Model\"\nelse\n  cat <<EOF >>/config/config.yml\nmodel:\n  path: /cpu_model.tflite\nEOF\nfi\n\nmsg_info \"Installing Coral Object Detection Model (Patience)\"\ncd /opt/frigate\nexport CCACHE_DIR=/root/.ccache\nexport CCACHE_MAXSIZE=2G\nwget -q https://github.com/libusb/libusb/archive/v1.0.26.zip\nunzip -q v1.0.26.zip\nrm v1.0.26.zip\ncd libusb-1.0.26\n$STD ./bootstrap.sh\n$STD ./configure --disable-udev --enable-shared\n$STD make -j $(nproc --all)\ncd /opt/frigate/libusb-1.0.26/libusb\nmkdir -p /usr/local/lib\n$STD /bin/bash ../libtool  --mode=install /usr/bin/install -c libusb-1.0.la '/usr/local/lib'\nmkdir -p /usr/local/include/libusb-1.0\n$STD /usr/bin/install -c -m 644 libusb.h '/usr/local/include/libusb-1.0'\nldconfig\ncd /\nwget -qO edgetpu_model.tflite https://github.com/google-coral/test_data/raw/release-frogfish/ssdlite_mobiledet_coco_qat_postprocess_edgetpu.tflite\nwget -qO cpu_model.tflite https://github.com/google-coral/test_data/raw/release-frogfish/ssdlite_mobiledet_coco_qat_postprocess.tflite\ncp /opt/frigate/labelmap.txt /labelmap.txt\nwget -qO yamnet-tflite-classification-tflite-v1.tar.gz https://www.kaggle.com/api/v1/models/google/yamnet/tfLite/classification-tflite/1/download\ntar xzf yamnet-tflite-classification-tflite-v1.tar.gz\nrm -rf yamnet-tflite-classification-tflite-v1.tar.gz\nmv 1.tflite cpu_audio_model.tflite\ncp /opt/frigate/audio-labelmap.txt /audio-labelmap.txt\nmkdir -p /media/frigate\nwget -qO /media/frigate/person-bicycle-car-detection.mp4 https://github.com/intel-iot-devkit/sample-videos/raw/master/person-bicycle-car-detection.mp4\nmsg_ok \"Installed Coral Object Detection Model\"\n\nmsg_info \"Building Nginx with Custom Modules\"\n$STD /opt/frigate/docker/main/build_nginx.sh\nsed -e '/s6-notifyoncheck/ s/^#*/#/' -i /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/nginx/run\nln -sf /usr/local/nginx/sbin/nginx  /usr/local/bin/nginx\nmsg_ok \"Built Nginx\"\n\nmsg_info \"Installing Tempio\"\nsed -i 's|/rootfs/usr/local|/usr/local|g' /opt/frigate/docker/main/install_tempio.sh\n$STD /opt/frigate/docker/main/install_tempio.sh\nln -sf /usr/local/tempio/bin/tempio /usr/local/bin/tempio\nmsg_ok \"Installed Tempio\"\n\nmsg_info \"Creating Services\"\ncat <<EOF >/etc/systemd/system/create_directories.service\n[Unit]\nDescription=Create necessary directories for logs\n\n[Service]\nType=oneshot\nExecStart=/bin/bash -c '/bin/mkdir -p /dev/shm/logs/{frigate,go2rtc,nginx} && /bin/touch /dev/shm/logs/{frigate/current,go2rtc/current,nginx/current} && /bin/chmod -R 777 /dev/shm/logs'\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now create_directories\nsleep 3\ncat <<EOF >/etc/systemd/system/go2rtc.service\n[Unit]\nDescription=go2rtc service\nAfter=network.target\nAfter=create_directories.service\nStartLimitIntervalSec=0\n\n[Service]\nType=simple\nRestart=always\nRestartSec=1\nUser=root\nExecStartPre=+rm /dev/shm/logs/go2rtc/current\nExecStart=/bin/bash -c \"bash /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/run 2> >(/usr/bin/ts '%%Y-%%m-%%d %%H:%%M:%%.S ' >&2) | /usr/bin/ts '%%Y-%%m-%%d %%H:%%M:%%.S '\"\nStandardOutput=file:/dev/shm/logs/go2rtc/current\nStandardError=file:/dev/shm/logs/go2rtc/current\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now go2rtc\nsleep 3\ncat <<EOF >/etc/systemd/system/frigate.service\n[Unit]\nDescription=Frigate service\nAfter=go2rtc.service\nAfter=create_directories.service\nStartLimitIntervalSec=0\n\n[Service]\nType=simple\nRestart=always\nRestartSec=1\nUser=root\n# Environment=PLUS_API_KEY=\nExecStartPre=+rm /dev/shm/logs/frigate/current\nExecStart=/bin/bash -c \"bash /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/frigate/run 2> >(/usr/bin/ts '%%Y-%%m-%%d %%H:%%M:%%.S ' >&2) | /usr/bin/ts '%%Y-%%m-%%d %%H:%%M:%%.S '\"\nStandardOutput=file:/dev/shm/logs/frigate/current\nStandardError=file:/dev/shm/logs/frigate/current\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now frigate\nsleep 3\ncat <<EOF >/etc/systemd/system/nginx.service\n[Unit]\nDescription=Nginx service\nAfter=frigate.service\nAfter=create_directories.service\nStartLimitIntervalSec=0\n\n[Service]\nType=simple\nRestart=always\nRestartSec=1\nUser=root\nExecStartPre=+rm /dev/shm/logs/nginx/current\nExecStart=/bin/bash -c \"bash /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/nginx/run 2> >(/usr/bin/ts '%%Y-%%m-%%d %%H:%%M:%%.S ' >&2) | /usr/bin/ts '%%Y-%%m-%%d %%H:%%M:%%.S '\"\nStandardOutput=file:/dev/shm/logs/nginx/current\nStandardError=file:/dev/shm/logs/nginx/current\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now nginx\nmsg_ok \"Configured Services\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/gitea-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# Co-author: Rogue-King\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y git\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y sqlite3\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Gitea\"\nRELEASE=$(wget -q https://github.com/go-gitea/gitea/releases/latest -O - | grep \"title>Release\" | cut -d \" \" -f 4 | sed 's/^v//')\nwget -q https://github.com/go-gitea/gitea/releases/download/v$RELEASE/gitea-$RELEASE-linux-amd64\nmv gitea* /usr/local/bin/gitea\nchmod +x /usr/local/bin/gitea\nadduser --system --group --disabled-password --shell /bin/bash --home /etc/gitea gitea > /dev/null\nmkdir -p /var/lib/gitea/{custom,data,log}\nchown -R gitea:gitea /var/lib/gitea/\nchmod -R 750 /var/lib/gitea/\nchown root:gitea /etc/gitea\nchmod 770 /etc/gitea\nsudo -u gitea ln -s /var/lib/gitea/data/.ssh/ /etc/gitea/.ssh\nmsg_ok \"Installed Gitea\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/gitea.service\n[Unit]\nDescription=Gitea (Git with a cup of tea)\nAfter=syslog.target\nAfter=network.target\n\n[Service]\n# Uncomment notify and watchdog if you want to use them\n# Uncomment the next line if you have repos with lots of files and get a HTTP 500 error because of that\n# LimitNOFILE=524288:524288\nRestartSec=2s\nType=simple\n#Type=notify\nUser=gitea\nGroup=gitea\n#The mount point we added to the container\nWorkingDirectory=/var/lib/gitea\n#Create directory in /run\nRuntimeDirectory=gitea\nExecStart=/usr/local/bin/gitea web --config /etc/gitea/app.ini\nRestart=always\nEnvironment=USER=gitea HOME=/var/lib/gitea/data GITEA_WORK_DIR=/var/lib/gitea\n#WatchdogSec=30s\n#Capabilities to bind to low-numbered ports\n#CapabilityBoundingSet=CAP_NET_BIND_SERVICE\n#AmbientCapabilities=CAP_NET_BIND_SERVICE\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now gitea\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/go2rtc-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing go2rtc\"\nmkdir -p /opt/go2rtc\ncd /opt/go2rtc\nwget -q https://github.com/AlexxIT/go2rtc/releases/latest/download/go2rtc_linux_amd64\nchmod +x go2rtc_linux_amd64\nmsg_ok \"Installed go2rtc\"\n\nmsg_info \"Creating Service\"\nservice_path=\"/etc/systemd/system/go2rtc.service\"\necho \"[Unit]\nDescription=go2rtc service\nAfter=network.target\n\n[Service]\nType=simple\nUser=root\nExecStart=/opt/go2rtc/go2rtc_linux_amd64\n\n[Install]\nWantedBy=multi-user.target\" >$service_path\nsystemctl enable -q --now go2rtc\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/gokapi-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Gokapi\"\nLATEST=$(curl -sL https://api.github.com/repos/Forceu/Gokapi/releases/latest | grep '\"tag_name\":' | cut -d'\"' -f4)\nmkdir -p /opt/gokapi/{data,config}\nwget -q https://github.com/Forceu/Gokapi/releases/download/$LATEST/gokapi-linux_amd64.zip\nunzip -q gokapi-linux_amd64.zip -d /opt/gokapi\nrm gokapi-linux_amd64.zip\nchmod +x /opt/gokapi/gokapi-linux_amd64\nmsg_ok \"Installed Gokapi\"\n\nmsg_info \"Creating Service\" \ncat <<EOF >/etc/systemd/system/gokapi.service\n[Unit]\nDescription=gokapi\n\n[Service]\nType=simple\nEnvironment=GOKAPI_DATA_DIR=/opt/gokapi/data\nEnvironment=GOKAPI_CONFIG_DIR=/opt/gokapi/config\nExecStart=/opt/gokapi/gokapi-linux_amd64\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now gokapi\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/gotify-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Gotify\"\nRELEASE=$(curl -s https://api.github.com/repos/gotify/server/releases/latest | grep \"tag_name\" | awk '{print substr($2, 3, length($2)-4) }')\nmkdir -p /opt/gotify\ncd /opt/gotify\nwget -q https://github.com/gotify/server/releases/download/v${RELEASE}/gotify-linux-amd64.zip\n$STD unzip gotify-linux-amd64.zip\nrm -rf gotify-linux-amd64.zip\nchmod +x gotify-linux-amd64\necho \"${RELEASE}\" >/opt/${APPLICATION}_version.txt\nmsg_ok \"Installed Gotify\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/gotify.service\n[Unit]\nDescription=Gotify\nRequires=network.target\nAfter=network.target\n\n[Service]\nType=simple\nUser=root\nWorkingDirectory=/opt/gotify\nExecStart=/opt/gotify/./gotify-linux-amd64\nRestart=always\nRestartSec=3\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now gotify\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/grafana-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y gnupg\n$STD apt-get install -y apt-transport-https\n$STD apt-get install -y software-properties-common\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Setting up Grafana Repository\"\nwget -q -O /usr/share/keyrings/grafana.key https://apt.grafana.com/gpg.key\nsh -c 'echo \"deb [signed-by=/usr/share/keyrings/grafana.key] https://apt.grafana.com stable main\" > /etc/apt/sources.list.d/grafana.list'\nmsg_ok \"Set up Grafana Repository\"\n\nmsg_info \"Installing Grafana\"\n$STD apt-get update\n$STD apt-get install -y grafana\nsystemctl start grafana-server\nsystemctl enable --now -q grafana-server.service\nmsg_ok \"Installed Grafana\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/grocy-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y apt-transport-https\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing PHP8.2\"\nVERSION=\"$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)\"\ncurl -sSLo /usr/share/keyrings/deb.sury.org-php.gpg https://packages.sury.org/php/apt.gpg\necho -e \"deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ $VERSION main\" >/etc/apt/sources.list.d/php.list\n$STD apt-get update\n$STD apt-get install -y php8.2\n$STD apt-get install -y libapache2-mod-php8.2\n$STD apt-get install -y php8.2-sqlite3\n$STD apt-get install -y php8.2-gd\n$STD apt-get install -y php8.2-intl\n$STD apt-get install -y php8.2-mbstring\nmsg_ok \"Installed PHP8.2\"\n\nmsg_info \"Installing grocy\"\nlatest=$(curl -s https://api.github.com/repos/grocy/grocy/releases/latest | grep \"tag_name\" | awk '{print substr($2, 3, length($2)-4) }')\nwget -q https://github.com/grocy/grocy/releases/download/v${latest}/grocy_${latest}.zip\n$STD unzip grocy_${latest}.zip -d /var/www/html\nchown -R www-data:www-data /var/www/html\ncp /var/www/html/config-dist.php /var/www/html/data/config.php\nchmod +x /var/www/html/update.sh\n\ncat <<EOF >/etc/apache2/sites-available/grocy.conf\n<VirtualHost *:80>\n  ServerAdmin webmaster@localhost\n  DocumentRoot /var/www/html/public\n  ErrorLog /var/log/apache2/error.log\n<Directory /var/www/html/public>\n  Options Indexes FollowSymLinks MultiViews\n  AllowOverride All\n  Order allow,deny\n  allow from all\n</Directory>\n</VirtualHost>\nEOF\n\n$STD a2dissite 000-default.conf\n$STD a2ensite grocy.conf\n$STD a2enmod rewrite\nsystemctl reload apache2\nmsg_ok \"Installed grocy\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nrm -rf /root/grocy_${latest}.zip\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/headscale-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nRELEASE=$(curl -s https://api.github.com/repos/juanfont/headscale/releases/latest | grep \"tag_name\" | awk '{print substr($2, 3, length($2)-4) }')\nmsg_info \"Installing ${APPLICATION} v${RELEASE}\"\nwget -q https://github.com/juanfont/headscale/releases/download/v${RELEASE}/headscale_${RELEASE}_linux_amd64.deb\n$STD dpkg -i headscale_${RELEASE}_linux_amd64.deb\nsystemctl enable -q --now headscale\necho \"${RELEASE}\" >/opt/${APPLICATION}_version.txt\nmsg_ok \"Installed ${APPLICATION} v${RELEASE}\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\nrm headscale_${RELEASE}_linux_amd64.deb\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/heimdall-dashboard-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y apt-transport-https\n$STD apt-get install -y composer\n$STD apt-get install -y php8.2-{bz2,curl,sqlite3,zip,xml}\nmsg_ok \"Installed Dependencies\"\n\nRELEASE=$(curl -sX GET \"https://api.github.com/repos/linuxserver/Heimdall/releases/latest\" | awk '/tag_name/{print $4;exit}' FS='[\"\"]')\necho \"${RELEASE}\" >/opt/${APPLICATION}_version.txt\nmsg_info \"Installing Heimdall Dashboard ${RELEASE}\"\nwget -q https://github.com/linuxserver/Heimdall/archive/${RELEASE}.tar.gz\ntar xzf ${RELEASE}.tar.gz\nVER=$(curl -s https://api.github.com/repos/linuxserver/Heimdall/releases/latest | grep \"tag_name\" | awk '{print substr($2, 3, length($2)-4) }')\nrm -rf ${RELEASE}.tar.gz\nmv Heimdall-${VER} /opt/Heimdall\ncd /opt/Heimdall\ncp .env.example .env\n$STD php artisan key:generate\nmsg_ok \"Installed Heimdall Dashboard ${RELEASE}\"\n\nmsg_info \"Creating Service\"\nservice_path=\"/etc/systemd/system/heimdall.service\"\necho \"[Unit]\nDescription=Heimdall\nAfter=network.target\n\n[Service]\nRestart=always\nRestartSec=5\nType=simple\nUser=root\nWorkingDirectory=/opt/Heimdall\nExecStart=\"/usr/bin/php\" artisan serve --port 7990 --host 0.0.0.0\nTimeoutStopSec=30\n\n[Install]\nWantedBy=multi-user.target\" >$service_path\nsystemctl enable -q --now heimdall.service\ncd /opt/Heimdall\nCOMPOSER_ALLOW_SUPERUSER=1 composer dump-autoload &>/dev/null\nsystemctl restart heimdall.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/hivemq-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y gpg\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing OpenJDK\"\nwget -qO- https://packages.adoptium.net/artifactory/api/gpg/key/public | gpg --dearmor >/etc/apt/trusted.gpg.d/adoptium.gpg\necho 'deb [arch=amd64 signed-by=/etc/apt/trusted.gpg.d/adoptium.gpg] https://packages.adoptium.net/artifactory/deb bookworm main' >/etc/apt/sources.list.d/adoptium.list\n$STD apt-get update\n$STD apt-get install -y temurin-17-jre\nmsg_ok \"Installed OpenJDK\"\n\nmsg_info \"Installing HiveMQ CE\"\nRELEASE=$(curl -s https://api.github.com/repos/hivemq/hivemq-community-edition/releases/latest | grep \"tag_name\" | awk '{print substr($2, 2, length($2)-3) }')\nwget -q https://github.com/hivemq/hivemq-community-edition/releases/download/${RELEASE}/hivemq-ce-${RELEASE}.zip\nunzip -q hivemq-ce-${RELEASE}.zip\nmkdir -p /opt/hivemq\nmv hivemq-ce-${RELEASE}/* /opt/hivemq\nuseradd -d /opt/hivemq hivemq\nchown -R hivemq:hivemq /opt/hivemq\nchmod +x /opt/hivemq/bin/run.sh\ncp /opt/hivemq/bin/init-script/hivemq.service /etc/systemd/system/hivemq.service\nrm /opt/hivemq/conf/config.xml\nmv /opt/hivemq/conf/examples/configuration/config-sample-tcp-and-websockets.xml /opt/hivemq/conf/config.xml\nsystemctl enable -q --now hivemq\nmsg_ok \"Installed HiveMQ CE\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\nrm -rf hivemq-ce-${RELEASE}.zip\nrm -rf ../hivemq-ce-${RELEASE}\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/homarr-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y git\n$STD apt-get install -y ca-certificates\n$STD apt-get install -y gnupg\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Setting up Node.js Repository\"\nmkdir -p /etc/apt/keyrings\ncurl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg\necho \"deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main\" >/etc/apt/sources.list.d/nodesource.list\nmsg_ok \"Set up Node.js Repository\"\n\nmsg_info \"Installing Node.js/Yarn\"\n$STD apt-get update\n$STD apt-get install -y nodejs\n$STD npm install -g npm@latest\n$STD npm install -g yarn\nmsg_ok \"Installed Node.js/Yarn\"\n\nmsg_info \"Installing Homarr (Patience)\"\n$STD git clone -b dev https://github.com/ajnart/homarr.git /opt/homarr\ncat <<EOF >/opt/homarr/.env\nDATABASE_URL=\"file:./database/db.sqlite\"\nNEXTAUTH_URL=\"http://localhost:3000\"\nNEXTAUTH_SECRET=\"$(openssl rand -base64 32)\"\nNEXT_PUBLIC_DISABLE_ANALYTICS=\"true\"\nDEFAULT_COLOR_SCHEME=\"dark\"\nEOF\ncd /opt/homarr\n$STD yarn install\n$STD yarn build\n$STD yarn db:migrate\nmsg_ok \"Installed Homarr\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/homarr.service\n[Unit]\nDescription=Homarr Service\nAfter=network.target\n\n[Service]\nType=exec\nWorkingDirectory=/opt/homarr\nEnvironmentFile=-/opt/homarr/.env\nExecStart=/usr/bin/yarn start\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now homarr.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/homeassistant-core-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<<\"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies (Patience)\"\n$STD apt-get install -y git curl sudo mc bluez libffi-dev libssl-dev libjpeg-dev zlib1g-dev autoconf build-essential libopenjp2-7 libturbojpeg0-dev ffmpeg liblapack3 liblapack-dev dbus-broker libpcap-dev libavdevice-dev libavformat-dev libavcodec-dev libavutil-dev libavfilter-dev libmariadb-dev-compat libatlas-base-dev pip python3.12-dev\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing UV\"\n$STD pip install uv\nmsg_ok \"Installed UV\"\n\nmsg_info \"Setting up Home Assistant-Core environment\"\nmkdir /srv/homeassistant\ncd /srv/homeassistant\nuv venv . &>/dev/null\nsource bin/activate\nmsg_ok \"Created virtual environment with UV\"\n\nmsg_info \"Installing Home Assistant-Core and packages\"\n$STD uv pip install webrtcvad wheel homeassistant mysqlclient psycopg2-binary isal\nmkdir -p /root/.homeassistant\nmsg_ok \"Installed Home Assistant-Core and required packages\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/homeassistant.service\n[Unit]\nDescription=Home Assistant\nAfter=network-online.target\n[Service]\nType=simple\nWorkingDirectory=/root/.homeassistant\nEnvironment=\"PATH=/srv/homeassistant/bin:/usr/local/bin:/usr/bin:/usr/local/bin/uv\"\nExecStart=/srv/homeassistant/bin/python3 -m homeassistant --config /root/.homeassistant\nRestart=always\nRestartForceExitStatus=100\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now homeassistant\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/homeassistant-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<<\"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Updating Python3\"\n$STD apt-get install -y \\\n  python3 \\\n  python3-dev \\\n  python3-pip \\\n  python3-venv\nrm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED\nmsg_ok \"Updated Python3\"\n\nmsg_info \"Installing runlike\"\n$STD pip install runlike\nmsg_ok \"Installed runlike\"\n\nget_latest_release() {\n  curl -sL https://api.github.com/repos/$1/releases/latest | grep '\"tag_name\":' | cut -d'\"' -f4\n}\n\nDOCKER_LATEST_VERSION=$(get_latest_release \"moby/moby\")\nCORE_LATEST_VERSION=$(get_latest_release \"home-assistant/core\")\nPORTAINER_LATEST_VERSION=$(get_latest_release \"portainer/portainer\")\n\nmsg_info \"Installing Docker $DOCKER_LATEST_VERSION\"\nDOCKER_CONFIG_PATH='/etc/docker/daemon.json'\nmkdir -p $(dirname $DOCKER_CONFIG_PATH)\necho -e '{\\n  \"log-driver\": \"journald\"\\n}' >/etc/docker/daemon.json\n$STD sh <(curl -sSL https://get.docker.com)\nmsg_ok \"Installed Docker $DOCKER_LATEST_VERSION\"\n\nmsg_info \"Pulling Portainer $PORTAINER_LATEST_VERSION Image\"\n$STD docker pull portainer/portainer-ce:latest\nmsg_ok \"Pulled Portainer $PORTAINER_LATEST_VERSION Image\"\n\nmsg_info \"Installing Portainer $PORTAINER_LATEST_VERSION\"\n$STD docker volume create portainer_data\n$STD docker run -d \\\n  -p 8000:8000 \\\n  -p 9443:9443 \\\n  --name=portainer \\\n  --restart=always \\\n  -v /var/run/docker.sock:/var/run/docker.sock \\\n  -v portainer_data:/data \\\n  portainer/portainer-ce:latest\nmsg_ok \"Installed Portainer $PORTAINER_LATEST_VERSION\"\n\nmsg_info \"Pulling Home Assistant $CORE_LATEST_VERSION Image\"\n$STD docker pull ghcr.io/home-assistant/home-assistant:stable\nmsg_ok \"Pulled Home Assistant $CORE_LATEST_VERSION Image\"\n\nmsg_info \"Installing Home Assistant $CORE_LATEST_VERSION\"\n$STD docker volume create hass_config\n$STD docker run -d \\\n  --name homeassistant \\\n  --privileged \\\n  --restart unless-stopped \\\n  -v /var/run/docker.sock:/var/run/docker.sock \\\n  -v /dev:/dev \\\n  -v hass_config:/config \\\n  -v /etc/localtime:/etc/localtime:ro \\\n  --net=host \\\n  ghcr.io/home-assistant/home-assistant:stable\nmkdir /root/hass_config\nmsg_ok \"Installed Home Assistant $CORE_LATEST_VERSION\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/homebox-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck\n# Co-Author: MickLesk (Canbiz)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n# Source: https://github.com/sysadminsmedia/homebox\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y \\\n  curl \\\n  sudo \\\n  mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Homebox\"\nRELEASE=$(curl -s https://api.github.com/repos/sysadminsmedia/homebox/releases/latest | grep \"tag_name\" | awk '{print substr($2, 2, length($2)-3) }')\nwget -qO- https://github.com/sysadminsmedia/homebox/releases/download/${RELEASE}/homebox_Linux_x86_64.tar.gz | tar -xzf - -C /opt\nchmod +x /opt/homebox\necho \"${RELEASE}\" >\"/opt/${APPLICATION}_version.txt\"\nmsg_ok \"Installed Homebox\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/homebox.service\n[Unit]\nDescription=Start Homebox Service\nAfter=network.target\n\n[Service]\nWorkingDirectory=/opt\nExecStart=/opt/homebox\nRestart=on-failure\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now homebox.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/homebridge-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y avahi-daemon\n$STD apt-get install -y gnupg2\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Setting up Homebridge Repository\"\ncurl -sSf https://repo.homebridge.io/KEY.gpg | gpg --dearmor >/etc/apt/trusted.gpg.d/homebridge.gpg\necho 'deb [signed-by=/etc/apt/trusted.gpg.d/homebridge.gpg] https://repo.homebridge.io stable main' >/etc/apt/sources.list.d/homebridge.list\nmsg_ok \"Set up Homebridge Repository\"\n\nmsg_info \"Installing Homebridge\"\n$STD apt update\n$STD apt-get install -y homebridge\nmsg_ok \"Installed Homebridge\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/homepage-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y gpg\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Setting up Node.js Repository\"\nmkdir -p /etc/apt/keyrings\ncurl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg\necho \"deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main\" >/etc/apt/sources.list.d/nodesource.list\nmsg_ok \"Set up Node.js Repository\"\n\nmsg_info \"Installing Node.js\"\n$STD apt-get update\n$STD apt-get install -y nodejs\n$STD npm install -g pnpm\nmsg_ok \"Installed Node.js\"\n\nRELEASE=$(curl -s https://api.github.com/repos/gethomepage/homepage/releases/latest | grep \"tag_name\" | awk '{print substr($2, 3, length($2)-4) }')\nmsg_info \"Installing Homepage v${RELEASE} (Patience)\"\nwget -q https://github.com/gethomepage/homepage/archive/refs/tags/v${RELEASE}.tar.gz\n$STD tar -xzf v${RELEASE}.tar.gz\nrm -rf v${RELEASE}.tar.gz\nmkdir -p /opt/homepage/config\nmv homepage-${RELEASE}/* /opt/homepage\nrm -rf homepage-${RELEASE}\ncd /opt/homepage\ncp /opt/homepage/src/skeleton/* /opt/homepage/config\n$STD pnpm install\n$STD pnpm build\necho \"${RELEASE}\" >/opt/${APPLICATION}_version.txt\nmsg_ok \"Installed Homepage v${RELEASE}\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/homepage.service\n[Unit]\nDescription=Homepage\nAfter=network.target\nStartLimitIntervalSec=0\n[Service]\nType=simple\nRestart=always\nRestartSec=1\nUser=root\nWorkingDirectory=/opt/homepage/\nExecStart=pnpm start\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now homepage\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/homer-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y pip\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Homer\"\nmkdir -p /opt/homer\ncd /opt/homer\nwget -q https://github.com/bastienwirtz/homer/releases/latest/download/homer.zip\n$STD unzip homer.zip\nrm -rf homer.zip\ncp assets/config.yml.dist assets/config.yml\nmsg_ok \"Installed Homer\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/homer.service\n[Unit]\nDescription=Homer Dashboard\nAfter=network-online.target\n[Service]\nType=simple\nWorkingDirectory=/opt/homer\nExecStart=python3 -m http.server 8010\n[Install]\nWantedBy=multi-user.target\nEOF\n$STD systemctl enable --now homer\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/hyperhdr-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y gpg\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing HyperHDR\"\ncurl -fsSL https://awawa-dev.github.io/hyperhdr.public.apt.gpg.key >/usr/share/keyrings/hyperhdr.public.apt.gpg.key\nchmod go+r /usr/share/keyrings/hyperhdr.public.apt.gpg.key\necho \"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hyperhdr.public.apt.gpg.key] https://awawa-dev.github.io $(awk -F= '/VERSION_CODENAME/ {print $2}' /etc/os-release) main\" >/etc/apt/sources.list.d/hyperhdr.list\n$STD apt-get update\n$STD apt-get install -y hyperhdr\nmsg_ok \"Installed HyperHDR\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/hyperhdr.service\n[Unit]\nDescription=HyperHDR Service\nAfter=syslog.target network.target\n\n[Service]\nRestart=on-failure\nRestartSec=5\nType=simple\nExecStart=/usr/bin/hyperhdr\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now hyperhdr\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/hyperion-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y lsb-release\n$STD apt-get install -y gpg\n$STD apt-get install -y apt-transport-https\n$STD apt-get install -y libpython3.11\n\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Hyperion\"\nwget -qO- https://releases.hyperion-project.org/hyperion.pub.key | gpg --dearmor -o /usr/share/keyrings/hyperion.pub.gpg\necho \"deb [signed-by=/usr/share/keyrings/hyperion.pub.gpg] https://apt.releases.hyperion-project.org/ $(lsb_release -cs) main\" >/etc/apt/sources.list.d/hyperion.list\n$STD apt-get update\n$STD apt-get install -y hyperion\n$STD systemctl enable --now hyperion@root.service\nmsg_ok \"Installed Hyperion\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get autoremove >/dev/null\n$STD apt-get autoclean >/dev/null\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/influxdb-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y lsb-base\n$STD apt-get install -y lsb-release\n$STD apt-get install -y gnupg2\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Setting up InfluxDB Repository\"\nwget -qO- https://repos.influxdata.com/influxdata-archive_compat.key | gpg --dearmor > /etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg\necho \"deb [signed-by=/etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg] https://repos.influxdata.com/debian stable main\" > /etc/apt/sources.list.d/influxdata.list\nmsg_ok \"Set up InfluxDB Repository\"\n\nread -r -p \"Which version of InfluxDB to install? (1 or 2) \" prompt\nif [[ $prompt == \"2\" ]]; then\n  INFLUX=\"2\"\nelse\n  INFLUX=\"1\"\nfi\n\nmsg_info \"Installing InfluxDB\"\n$STD apt-get update\nif [[ $INFLUX == \"2\" ]]; then\n  $STD apt-get install -y influxdb2\nelse\n  $STD apt-get install -y influxdb\n  wget -q https://dl.influxdata.com/chronograf/releases/chronograf_1.10.1_amd64.deb\n  $STD dpkg -i chronograf_1.10.1_amd64.deb\nfi\n$STD systemctl enable --now influxdb\nmsg_ok \"Installed InfluxDB\"\n\nread -r -p \"Would you like to add Telegraf? <y/N> \" prompt\nif [[ \"${prompt,,}\" =~ ^(y|yes)$ ]]; then\n  msg_info \"Installing Telegraf\"\n  $STD apt-get install -y telegraf\n  msg_ok \"Installed Telegraf\"\nfi\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/iobroker-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y ca-certificates\n$STD apt-get install -y gnupg\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Setting up Node.js Repository\"\nmkdir -p /etc/apt/keyrings\ncurl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg\necho \"deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main\" >/etc/apt/sources.list.d/nodesource.list\nmsg_ok \"Set up Node.js Repository\"\n\nmsg_info \"Installing Node.js\"\n$STD apt-get update\n$STD apt-get install -y nodejs\nmsg_ok \"Installed Node.js\"\n\nmsg_info \"Installing ioBroker (Patience)\"\n$STD bash <(curl -fsSL https://iobroker.net/install.sh)\nmsg_ok \"Installed ioBroker\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/iventoy-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nRELEASE=$(curl -s https://api.github.com/repos/ventoy/pxe/releases/latest | grep \"tag_name\" | awk '{print substr($2, 3, length($2)-4) }')\nmsg_info \"Installing iVentoy v${RELEASE}\"\nmkdir -p /opt/iventoy/{data,iso}\nwget -q https://github.com/ventoy/PXE/releases/download/v${RELEASE}/iventoy-${RELEASE}-linux-free.tar.gz\ntar -C /tmp -xzf iventoy*.tar.gz\nmv /tmp/iventoy*/* /opt/iventoy/\nrm -rf iventoy*.tar.gz\nmsg_ok \"Installed iVentoy\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/iventoy.service\n[Unit]\nDescription=iVentoy PXE Booter\nDocumentation=https://www.iventoy.com\nWants=network-online.target\n[Service]\nType=forking\nEnvironment=IVENTOY_API_ALL=1\nEnvironment=IVENTOY_AUTO_RUN=1\nEnvironment=LIBRARY_PATH=/opt/iventoy/lib/lin64\nEnvironment=LD_LIBRARY_PATH=/opt/iventoy/lib/lin64\nExecStart=sh ./iventoy.sh -R start\nWorkingDirectory=/opt/iventoy\nRestart=on-failure\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now iventoy.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/jackett-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Jackett\"\nRELEASE=$(wget -q https://github.com/Jackett/Jackett/releases/latest -O - | grep \"title>Release\" | cut -d \" \" -f 4)\nwget -q https://github.com/Jackett/Jackett/releases/download/$RELEASE/Jackett.Binaries.LinuxAMDx64.tar.gz\ntar -xzf Jackett.Binaries.LinuxAMDx64.tar.gz -C /opt\nrm -rf Jackett.Binaries.LinuxAMDx64.tar.gz\necho \"${RELEASE}\" >/opt/${APPLICATION}_version.txt\nmsg_ok \"Installed Jackett\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/jackett.service\n[Unit]\nDescription=Jackett Daemon\nAfter=network.target\n[Service]\nSyslogIdentifier=jackett\nRestart=always\nRestartSec=5\nType=simple\nWorkingDirectory=/opt/Jackett\nExecStart=/bin/sh /opt/Jackett/jackett_launcher.sh\nTimeoutStopSec=30\nEnvironment=\"DisableRootWarning=true\"\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now jackett.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/jellyfin-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y gpg\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Setting Up Hardware Acceleration\"\n$STD apt-get -y install {va-driver-all,ocl-icd-libopencl1,intel-opencl-icd,vainfo,intel-gpu-tools}\nif [[ \"$CTTYPE\" == \"0\" ]]; then\n  chgrp video /dev/dri\n  chmod 755 /dev/dri\n  chmod 660 /dev/dri/*\n  $STD adduser $(id -u -n) video\n  $STD adduser $(id -u -n) render\nfi\nmsg_ok \"Set Up Hardware Acceleration\"\n\nmsg_info \"Installing Jellyfin\"\nVERSION=\"$( awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release )\"\n# If the keyring directory is absent, create it\nif [[ ! -d /etc/apt/keyrings ]]; then\n    mkdir -p /etc/apt/keyrings\nfi\n# Download the repository signing key and install it to the keyring directory\ncurl -fsSL https://repo.jellyfin.org/jellyfin_team.gpg.key | gpg --dearmor --yes --output /etc/apt/keyrings/jellyfin.gpg\n# Install the Deb822 format jellyfin.sources entry\ncat <<EOF >/etc/apt/sources.list.d/jellyfin.sources\nTypes: deb\nURIs: https://repo.jellyfin.org/${PCT_OSTYPE}\nSuites: ${VERSION}\nComponents: main\nArchitectures: amd64\nSigned-By: /etc/apt/keyrings/jellyfin.gpg\nEOF\n# Install Jellyfin using the metapackage (which will fetch jellyfin-server, jellyfin-web, and jellyfin-ffmpeg5)\n$STD apt-get update\n$STD apt-get install -y jellyfin\nchown -R jellyfin:adm /etc/jellyfin\nsleep 10\nsystemctl restart jellyfin\nif [[ \"$CTTYPE\" == \"0\" ]]; then\n  sed -i -e 's/^ssl-cert:x:104:$/render:x:104:root,jellyfin/' -e 's/^render:x:108:root,jellyfin$/ssl-cert:x:108:/' /etc/group\nelse\n  sed -i -e 's/^ssl-cert:x:104:$/render:x:104:jellyfin/' -e 's/^render:x:108:jellyfin$/ssl-cert:x:108:/' /etc/group\nfi\nmsg_ok \"Installed Jellyfin\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/jellyseerr-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y git\n$STD apt-get install -y gpg\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Setting up Node.js Repository\"\nmkdir -p /etc/apt/keyrings\ncurl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg\necho \"deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main\" >/etc/apt/sources.list.d/nodesource.list\nmsg_ok \"Set up Node.js Repository\"\n\nmsg_info \"Installing Node.js\"\n$STD apt-get update\n$STD apt-get install -y nodejs\nmsg_ok \"Installed Node.js\"\n\nmsg_info \"Installing pnpm\"\n$STD npm install -g pnpm\nmsg_ok \"Installed pnpm\"\n\nmsg_info \"Installing Jellyseerr (Patience)\"\ngit clone -q https://github.com/Fallenbagel/jellyseerr.git /opt/jellyseerr\ncd /opt/jellyseerr\n$STD git checkout main\nexport CYPRESS_INSTALL_BINARY=0\n$STD pnpm install --frozen-lockfile\nexport NODE_OPTIONS=\"--max-old-space-size=3072\"\n$STD pnpm build\nmkdir -p /etc/jellyseerr/\ncat <<EOF >/etc/jellyseerr/jellyseerr.conf\nPORT=5055\n# HOST=0.0.0.0\n# JELLYFIN_TYPE=emby\nEOF\nmsg_ok \"Installed Jellyseerr\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/jellyseerr.service\n[Unit]\nDescription=jellyseerr Service\nAfter=network.target\n\n[Service]\nEnvironmentFile=/etc/jellyseerr/jellyseerr.conf\nEnvironment=NODE_ENV=production\nType=exec\nWorkingDirectory=/opt/jellyseerr\nExecStart=/usr/bin/node dist/index.js\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now jellyseerr.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/kavita-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Kavita\"\ncd /opt\nRELEASE=$(curl -s https://api.github.com/repos/Kareadita/Kavita/releases/latest | grep \"tag_name\" | awk '{print substr($2, 2, length($2)-3) }')\n$STD tar -xvzf <(curl -fsSL https://github.com/Kareadita/Kavita/releases/download/$RELEASE/kavita-linux-x64.tar.gz) --no-same-owner\nmsg_ok \"Installed Kavita\"\n\nmsg_info \"Creating Service\"\nservice_path=\"/etc/systemd/system/kavita.service\"\necho \"[Unit]\nDescription=Kavita Server\nAfter=network.target\n\n[Service]\nType=simple\nWorkingDirectory=/opt/Kavita\nExecStart=/opt/Kavita/Kavita\nTimeoutStopSec=20\nKillMode=process\nRestart=on-failure\n\n[Install]\nWantedBy=multi-user.target\" >$service_path\nchmod +x /opt/Kavita/* && chown root /opt/Kavita/*\nsystemctl enable --now -q kavita.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/keycloak-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies (Patience)\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y ca-certificates-java\n$STD apt-get install -y openjdk-17-jre-headless\nmsg_ok \"Installed Dependencies\"\n\nRELEASE=$(curl -s https://api.github.com/repos/keycloak/keycloak/releases/latest | grep \"tag_name\" | awk '{print substr($2, 2, length($2)-3) }')\nmsg_info \"Installing Keycloak v$RELEASE\"\ncd /opt\nwget -q https://github.com/keycloak/keycloak/releases/download/$RELEASE/keycloak-$RELEASE.tar.gz\n$STD tar -xvf keycloak-$RELEASE.tar.gz\nmv keycloak-$RELEASE keycloak\nmsg_ok \"Installed Keycloak\"\n\nmsg_info \"Creating Service\"\nservice_path=\"/etc/systemd/system/keycloak.service\"\necho \"[Unit]\nDescription=Keycloak\nAfter=network-online.target\n[Service]\nUser=root\nWorkingDirectory=/opt/keycloak\nExecStart=/opt/keycloak/bin/kc.sh start-dev\n[Install]\nWantedBy=multi-user.target\" >$service_path\n$STD systemctl enable --now keycloak.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/kubo-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# Co-Author: ulmentflam\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y gpg\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing IPFS\"\nRELEASE=$(wget -q https://github.com/ipfs/kubo/releases/latest -O - | grep \"title>Release\" | cut -d \" \" -f 4)\n$STD wget -q \"https://github.com/ipfs/kubo/releases/download/${RELEASE}/kubo_${RELEASE}_linux-amd64.tar.gz\"\ntar -xzf \"kubo_${RELEASE}_linux-amd64.tar.gz\" -C /usr/local\n$STD ln -s /usr/local/kubo/ipfs /usr/local/bin/ipfs\n$STD ipfs init\nipfs config Addresses.API /ip4/0.0.0.0/tcp/5001\nipfs config Addresses.Gateway /ip4/0.0.0.0/tcp/8080\nLXCIP=$(hostname -I | awk '{print $1}')\nipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin \"[\\\"http://${LXCIP}:5001\\\", \\\"http://localhost:3000\\\", \\\"http://127.0.0.1:5001\\\", \\\"https://webui.ipfs.io\\\", \\\"http://0.0.0.0:5001\\\"]\"\nipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods '[\"PUT\", \"POST\"]'\necho \"${RELEASE}\" >\"/opt/${APPLICATION}_version.txt\"\n$STD rm \"kubo_${RELEASE}_linux-amd64.tar.gz\"\nmsg_ok \"Installed IPFS\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/ipfs.service\n[Unit]\nDescription=IPFS Daemon\nAfter=syslog.target network.target\n\n[Service]\nType=simple\nExecStart=/usr/local/bin/ipfs daemon\nRestart=on-failure\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable --now -q ipfs.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/lazylibrarian-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck\n# Co-Author: MountyMapleSyrup (MountyMapleSyrup)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y git\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Python3 Dependencies\"\n$STD apt-get install -y pip\n$STD apt-get install -y python3-irc\n$STD pip install jaraco.stream\n$STD pip install python-Levenshtein\n$STD pip install soupsieve\nmsg_ok \"Installed Python3 Dependencies\"\n\nmsg_info \"Installing LazyLibrarian\"\n$STD git clone https://gitlab.com/LazyLibrarian/LazyLibrarian /opt/LazyLibrarian\nmsg_ok \"Installed LazyLibrarian\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/lazylibrarian.service\n[Unit]\nDescription=LazyLibrarian Daemon\nAfter=syslog.target network.target\n[Service]\nUMask=0002\nType=simple\nExecStart=/usr/bin/python3 /opt/LazyLibrarian/LazyLibrarian.py\nTimeoutStopSec=20\nKillMode=process\nRestart=on-failure\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable --now -q lazylibrarian\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/lidarr-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y sqlite3\n$STD apt-get install -y libchromaprint-tools\n$STD apt-get install -y mediainfo\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Lidarr\"\nmkdir -p /var/lib/lidarr/\nchmod 775 /var/lib/lidarr/\n$STD wget --content-disposition 'https://lidarr.servarr.com/v1/update/master/updatefile?os=linux&runtime=netcore&arch=x64'\n$STD tar -xvzf Lidarr.master.*.tar.gz\nmv Lidarr /opt\nchmod 775 /opt/Lidarr\nmsg_ok \"Installed Lidarr\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/lidarr.service\n[Unit]\nDescription=Lidarr Daemon\nAfter=syslog.target network.target\n[Service]\nUMask=0002\nType=simple\nExecStart=/opt/Lidarr/Lidarr -nobrowser -data=/var/lib/lidarr/\nTimeoutStopSec=20\nKillMode=process\nRestart=on-failure\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl -q daemon-reload\nsystemctl enable --now -q lidarr\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\nrm -rf Lidarr.master.*.tar.gz\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/linkwarden-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y git\n$STD apt-get install -y gpg\n$STD apt-get install -y postgresql\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Setting up Node.js Repository\"\nmkdir -p /etc/apt/keyrings\ncurl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg\necho \"deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main\" >/etc/apt/sources.list.d/nodesource.list\nmsg_ok \"Set up Node.js Repository\"\n\nmsg_info \"Installing Node.js/Yarn\"\n$STD apt-get update\n$STD apt-get install -y nodejs\n$STD npm install -g yarn\nmsg_ok \"Installed Node.js/Yarn\"\n\nmsg_info \"Clone Linkwarden Repository\"\n$STD git clone https://github.com/linkwarden/linkwarden.git /opt/linkwarden\ncd /opt/linkwarden\nmsg_ok \"Cloned Linkwarden Repository\"\n\nmsg_info \"Setting up PostgreSQL DB\"\nDB_NAME=linkwardendb\nDB_USER=linkwarden\nDB_PASS=\"$(openssl rand -base64 18 | tr -d '/' | cut -c1-13)\"\n$STD sudo -u postgres psql -c \"CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';\"\n$STD sudo -u postgres psql -c \"CREATE DATABASE $DB_NAME WITH OWNER $DB_USER TEMPLATE template0;\"\n\necho \"\" >>~/linkwarden.creds\necho -e \"Linkwarden Database User: \\e[32m$DB_USER\\e[0m\" >>~/linkwarden.creds\necho -e \"Linkwarden Database Password: \\e[32m$DB_PASS\\e[0m\" >>~/linkwarden.creds\necho -e \"Linkwarden Database Name: \\e[32m$DB_NAME\\e[0m\" >>~/linkwarden.creds\nmsg_ok \"Set up PostgreSQL DB\"\n\nread -r -p \"Would you like to add Adminer? <y/N> \" prompt\nif [[ \"${prompt,,}\" =~ ^(y|yes)$ ]]; then\n  msg_info \"Installing Adminer\"\n  $STD apt install -y adminer\n  $STD a2enconf adminer\n  systemctl reload apache2\n  IP=$(hostname -I | awk '{print $1}')\n  echo \"\" >>~/linkwarden.creds\n  echo -e \"Adminer Interface: \\e[32m$IP/adminer/\\e[0m\" >>~/linkwarden.creds\n  echo -e \"Adminer System: \\e[32mPostgreSQL\\e[0m\" >>~/linkwarden.creds\n  echo -e \"Adminer Server: \\e[32mlocalhost:5432\\e[0m\" >>~/linkwarden.creds\n  echo -e \"Adminer Username: \\e[32m$DB_USER\\e[0m\" >>~/linkwarden.creds\n  echo -e \"Adminer Password: \\e[32m$DB_PASS\\e[0m\" >>~/linkwarden.creds\n  echo -e \"Adminer Database: \\e[32m$DB_NAME\\e[0m\" >>~/linkwarden.creds\n  msg_ok \"Installed Adminer\"\nfi\n\nmsg_info \"Installing Linkwarden (Patience)\"\nRELEASE=$(curl -s https://api.github.com/repos/linkwarden/linkwarden/releases/latest | grep \"tag_name\" | awk '{print substr($2, 2, length($2)-3) }')\necho \"${RELEASE}\" >/opt/${APPLICATION}_version.txt\n$STD yarn\n$STD npx playwright install-deps\n$STD yarn playwright install\nIP=$(hostname -I | awk '{print $1}')\nSECRET_KEY=\"$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32)\"\nenv_path=\"/opt/linkwarden/.env\"\necho \" \nNEXTAUTH_SECRET=${SECRET_KEY}\nNEXTAUTH_URL=http://${IP}:3000\nDATABASE_URL=postgresql://${DB_USER}:${DB_PASS}@localhost:5432/${DB_NAME}\n\" >$env_path\n$STD yarn build\n$STD yarn prisma migrate deploy\nmsg_ok \"Installed Linkwarden\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/linkwarden.service\n[Unit]\nDescription=Linkwarden Service\nAfter=network.target\n\n[Service]\nType=exec\nWorkingDirectory=/opt/linkwarden\nExecStart=/usr/bin/yarn start\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now linkwarden.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/lldap-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# Co-Author: remz1337\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y gpg\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing lldap\"\nsource /etc/os-release\nos=$ID\nif [ \"$os\" == \"ubuntu\" ]; then\n  DISTRO=\"xUbuntu\"\nelse\n  DISTRO=\"${os^}\"\nfi\necho \"deb http://download.opensuse.org/repositories/home:/Masgalor:/LLDAP/${DISTRO}_${VERSION_ID}/ /\" >/etc/apt/sources.list.d/home:Masgalor:LLDAP.list\ncurl -fsSL https://download.opensuse.org/repositories/home:Masgalor:LLDAP/${DISTRO}_${VERSION_ID}/Release.key | gpg --dearmor >/etc/apt/trusted.gpg.d/home_Masgalor_LLDAP.gpg\n$STD apt update\n$STD apt install -y lldap\nsystemctl enable -q --now lldap\nmsg_ok \"Installed lldap\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/mafl-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y make\n$STD apt-get install -y g++\n$STD apt-get install -y gcc\n$STD apt-get install -y ca-certificates\n$STD apt-get install -y gnupg\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Setting up Node.js Repository\"\nmkdir -p /etc/apt/keyrings\ncurl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg\necho \"deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main\" >/etc/apt/sources.list.d/nodesource.list\nmsg_ok \"Set up Node.js Repository\"\n\nmsg_info \"Installing Node.js\"\n$STD apt-get update\n$STD apt-get install -y nodejs\n$STD npm install -g npm@latest\n$STD npm install -g yarn\nmsg_ok \"Installed Node.js\"\n\nRELEASE=$(curl -s https://api.github.com/repos/hywax/mafl/releases/latest | grep \"tag_name\" | awk '{print substr($2, 3, length($2)-4) }')\nmsg_info \"Installing Mafl v${RELEASE}\"\nwget -q https://github.com/hywax/mafl/archive/refs/tags/v${RELEASE}.tar.gz\ntar -xzf v${RELEASE}.tar.gz\nmkdir -p /opt/mafl/data\nwget -q -O /opt/mafl/data/config.yml https://raw.githubusercontent.com/hywax/mafl/main/.example/config.yml\nmv mafl-${RELEASE}/* /opt/mafl\nrm -rf mafl-${RELEASE}\ncd /opt/mafl\nexport NUXT_TELEMETRY_DISABLED=true\n$STD yarn install\n$STD yarn build\nmsg_ok \"Installed Mafl v${RELEASE}\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/mafl.service\n[Unit]\nDescription=Mafl\nAfter=network.target\nStartLimitIntervalSec=0\n\n[Service]\nType=simple\nRestart=always\nRestartSec=1\nUser=root\nWorkingDirectory=/opt/mafl/\nExecStart=yarn preview\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now mafl\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/magicmirror-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y git\n$STD apt-get install -y ca-certificates\n$STD apt-get install -y gnupg\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Setting up Node.js Repository\"\nmkdir -p /etc/apt/keyrings\ncurl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg\necho \"deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main\" >/etc/apt/sources.list.d/nodesource.list\nmsg_ok \"Set up Node.js Repository\"\n\nmsg_info \"Installing Node.js\"\n$STD apt-get update\n$STD apt-get install -y nodejs\nmsg_ok \"Installed Node.js\"\n\nmsg_info \"Setting up MagicMirror Repository\"\n$STD git clone https://github.com/MichMich/MagicMirror /opt/magicmirror\nmsg_ok \"Set up MagicMirror Repository\"\n\nmsg_info \"Installing MagicMirror\"\ncd /opt/magicmirror\n$STD npm install --only=prod --omit=dev\n\ncat <<EOF >/opt/magicmirror/config/config.js\nlet config = {\n        address: \"0.0.0.0\",     \n        port: 8080,\n        basePath: \"/\",  \n        ipWhitelist: [],        \n        useHttps: false,              \n        httpsPrivateKey: \"\",    \n        httpsCertificate: \"\",   \n        language: \"en\",\n        locale: \"en-US\",\n        logLevel: [\"INFO\", \"LOG\", \"WARN\", \"ERROR\"], \n        timeFormat: 24,\n        units: \"metric\",\n        serverOnly:  true,\n        modules: [\n                {\n                        module: \"alert\",\n                },\n                {\n                        module: \"updatenotification\",\n                        position: \"top_bar\"\n                },\n                {\n                        module: \"clock\",\n                        position: \"top_left\"\n                },\n                {\n                        module: \"calendar\",\n                        header: \"US Holidays\",\n                        position: \"top_left\",\n                        config: {\n                                calendars: [\n                                        {\n                                                symbol: \"calendar-check\",\n                                                url: \"webcal://www.calendarlabs.com/ical-calendar/ics/76/US_Holidays.ics\"\n                                        }\n                                ]\n                        }\n                },\n                {\n                        module: \"compliments\",\n                        position: \"lower_third\"\n                },\n                {\n                        module: \"weather\",\n                        position: \"top_right\",\n                        config: {\n                                weatherProvider: \"openweathermap\",\n                                type: \"current\",\n                                location: \"New York\",\n                                locationID: \"5128581\", //ID from http://bulk.openweathermap.org/sample/city.list.json.gz; unzip the gz file and find your city\n                                apiKey: \"YOUR_OPENWEATHER_API_KEY\"\n                        }\n                },\n                {\n                        module: \"weather\",\n                        position: \"top_right\",\n                        header: \"Weather Forecast\",\n                        config: {\n                                weatherProvider: \"openweathermap\",\n                                type: \"forecast\",\n                                location: \"New York\",\n                                locationID: \"5128581\", //ID from http://bulk.openweathermap.org/sample/city.list.json.gz; unzip the gz file and find your city\n                                apiKey: \"YOUR_OPENWEATHER_API_KEY\"\n                        }\n                },\n                {\n                        module: \"newsfeed\",\n                        position: \"bottom_bar\",\n                        config: {\n                                feeds: [\n                                        {\n                                                title: \"New York Times\",\n                                                url: \"https://rss.nytimes.com/services/xml/rss/nyt/HomePage.xml\"\n                                        }\n                                ],\n                                showSourceTitle: true,\n                                showPublishDate: true,\n                                broadcastNewsFeeds: true,\n                                broadcastNewsUpdates: true\n                        }\n                },\n        ]\n};\n\n/*************** DO NOT EDIT THE LINE BELOW ***************/\nif (typeof module !== \"undefined\") {module.exports = config;}\nEOF\nmsg_ok \"Installed MagicMirror\"\n\nmsg_info \"Creating Service\"\nservice_path=\"/etc/systemd/system/magicmirror.service\"\necho \"[Unit]\nDescription=Magic Mirror\nAfter=network.target\nStartLimitIntervalSec=0\n\n[Service]\nType=simple\nRestart=always\nRestartSec=1\nUser=root\nWorkingDirectory=/opt/magicmirror/\nExecStart=/usr/bin/node serveronly\n\n[Install]\nWantedBy=multi-user.target\" >$service_path\n$STD systemctl enable --now magicmirror\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/mariadb-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing MariaDB\"\n$STD apt-get install -y mariadb-server\nsed -i 's/^# *\\(port *=.*\\)/\\1/' /etc/mysql/my.cnf\nsed -i 's/^bind-address/#bind-address/g' /etc/mysql/mariadb.conf.d/50-server.cnf\nmsg_ok \"Installed MariaDB\"\n\nread -r -p \"Would you like to add PhpMyAdmin? <y/N> \" prompt\nif [[ ${prompt,,} =~ ^(y|yes)$ ]]; then\n  msg_info \"Installing phpMyAdmin\"\n  $STD apt-get install -y \\\n    apache2 \\\n    php \\\n    php-mysqli \\\n    php-mbstring \\\n    php-zip \\\n    php-gd \\\n    php-json \\\n    php-curl \n\t\n\twget -q \"https://files.phpmyadmin.net/phpMyAdmin/5.2.1/phpMyAdmin-5.2.1-all-languages.tar.gz\"\n\tmkdir -p /var/www/html/phpMyAdmin\n\ttar xf phpMyAdmin-5.2.1-all-languages.tar.gz --strip-components=1 -C /var/www/html/phpMyAdmin\n\tcp /var/www/html/phpMyAdmin/config.sample.inc.php /var/www/html/phpMyAdmin/config.inc.php\n\tSECRET=$(openssl rand -base64 24)\n\tsed -i \"s#\\$cfg\\['blowfish_secret'\\] = '';#\\$cfg['blowfish_secret'] = '${SECRET}';#\" /var/www/html/phpMyAdmin/config.inc.php\n\tchmod 660 /var/www/html/phpMyAdmin/config.inc.php\n\tchown -R www-data:www-data /var/www/html/phpMyAdmin\n\tsystemctl restart apache2\n  msg_ok \"Installed phpMyAdmin\"\nfi\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/matterbridge-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck\n# Co-Author: MickLesk (Canbiz)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n# Source: https://github.com/Luligu/matterbridge/\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y gpg\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Setting up Node.js Repository\"\nmkdir -p /etc/apt/keyrings\ncurl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg\necho \"deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main\" >/etc/apt/sources.list.d/nodesource.list\nmsg_ok \"Set up Node.js Repository\"\n\nmsg_info \"Installing Node.js\"\n$STD apt-get update\n$STD apt-get install -y nodejs\nmsg_ok \"Installed Node.js\"\n\nmsg_info \"Install Matterbridge\" \nmkdir -p /root/Matterbridge\n$STD npm install -g matterbridge\nmsg_ok \"Installed Matterbridge\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/matterbridge.service\n[Unit]\nDescription=matterbridge\nAfter=network-online.target\n\n[Service]\nType=simple\nExecStart=matterbridge -bridge -service\nWorkingDirectory=/root/Matterbridge\nStandardOutput=inherit\nStandardError=inherit\nRestart=always\nRestartSec=10s\nTimeoutStopSec=30s\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now matterbridge.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/mediamtx-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y ffmpeg\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing MediaMTX\"\nRELEASE=$(curl -s https://api.github.com/repos/bluenviron/mediamtx/releases/latest | grep \"tag_name\" | awk '{print substr($2, 2, length($2)-3) }')\nmkdir -p /opt/mediamtx\ncd /opt/mediamtx\nwget -q https://github.com/bluenviron/mediamtx/releases/download/${RELEASE}/mediamtx_${RELEASE}_linux_amd64.tar.gz\ntar xzf mediamtx_${RELEASE}_linux_amd64.tar.gz\nrm -rf mediamtx_${RELEASE}_linux_amd64.tar.gz\nmsg_ok \"Installed MediaMTX\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/mediamtx.service\n[Unit]\nDescription=MediaMTX\nAfter=syslog.target network-online.target\n\n[Service]\nExecStart=/opt/mediamtx/./mediamtx\nWorkingDirectory=/opt/mediamtx\nRestart=always\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now mediamtx.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/medusa-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y gpg\n$STD apt-get install -y git-core\n$STD apt-get install -y mediainfo\ncat <<EOF >/etc/apt/sources.list.d/non-free.list\ndeb http://deb.debian.org/debian bookworm main contrib non-free non-free-firmware\nEOF\n$STD apt-get update\n$STD apt-get install -y unrar\nrm /etc/apt/sources.list.d/non-free.list\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Medusa\"\n$STD git clone https://github.com/pymedusa/Medusa.git /opt/medusa\nmsg_ok \"Installed Medusa\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/medusa.service\n[Unit]\nDescription=Medusa Daemon\nAfter=network.target\n\n[Service]\nType=simple\nExecStart=/usr/bin/python3 /opt/medusa/start.py -q --nolaunch --datadir=/opt/medusa\nTimeoutStopSec=25\nKillMode=process\nRestart=on-failure\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now medusa.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/memos-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck\n# Co-Author: MickLesk (Canbiz)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n# Source: https://github.com/usememos/memos\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y \\\n  build-essential \\\n  git \\\n  curl \\\n  sudo \\\n  tzdata \\\n  mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Setting up Node.js Repository\"\nmkdir -p /etc/apt/keyrings\ncurl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg\necho \"deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main\" >/etc/apt/sources.list.d/nodesource.list\nmsg_ok \"Set up Node.js Repository\"\n\nmsg_info \"Installing Node.js\"\n$STD apt-get update\n$STD apt-get install -y nodejs\nmsg_ok \"Installed Node.js\"\n\nmsg_info \"Installing pnpm\"\n$STD npm install -g pnpm\nmsg_ok \"Installed pnpm\"\n\nmsg_info \"Installing Golang\"\nset +o pipefail\nGOLANG=$(curl -s https://go.dev/dl/ | grep -o \"go.*\\linux-amd64.tar.gz\" | head -n 1)\nwget -q https://golang.org/dl/$GOLANG\ntar -xzf $GOLANG -C /usr/local\nln -s /usr/local/go/bin/go /usr/local/bin/go\nset -o pipefail\nmsg_ok \"Installed Golang\"\n\nmsg_info \"Installing Memos (Patience)\"\nmkdir -p /opt/memos_data\n$STD sudo git clone https://github.com/usememos/memos.git /opt/memos\ncd /opt/memos/web \n$STD pnpm i --frozen-lockfile\n$STD pnpm build\ncd /opt/memos\nmkdir -p /opt/memos/server/dist\ncp -r web/dist/* /opt/memos/server/dist/\ncp -r web/dist/* /opt/memos/server/router/frontend/dist/\n$STD go build -o /opt/memos/memos -tags=embed bin/memos/main.go\nmsg_ok \"Installed Memos\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/memos.service\n[Unit]\nDescription=Memos Server\nAfter=network.target\n\n[Service]\nExecStart=/opt/memos/memos\nEnvironment=\"MEMOS_MODE=prod\"\nEnvironment=\"MEMOS_PORT=9030\"\nEnvironment=\"MEMOS_DATA=/opt/memos_data\"\nWorkingDirectory=/opt/memos\nRestart=always\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now memos.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/meshcentral-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y ca-certificates\n$STD apt-get install -y gnupg\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Setting up Node.js Repository\"\nmkdir -p /etc/apt/keyrings\ncurl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg\necho \"deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main\" >/etc/apt/sources.list.d/nodesource.list\nmsg_ok \"Set up Node.js Repository\"\n\nmsg_info \"Installing Node.js\"\n$STD apt-get update\n$STD apt-get install -y nodejs\nmsg_ok \"Installed Node.js\"\n\nmsg_info \"Installing MeshCentral\"\nmkdir /opt/meshcentral\ncd /opt/meshcentral\n$STD npm install meshcentral\n$STD node node_modules/meshcentral --install\nmsg_ok \"Installed MeshCentral\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/metube-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck\n# Co-Author: MickLesk (Canbiz)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n# Source: https://github.com/alexta69/metube\n\nsource /dev/stdin <<<\"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y --no-install-recommends \\\n  build-essential \\\n  curl \\\n  aria2 \\\n  coreutils \\\n  gcc \\\n  g++ \\\n  musl-dev \\\n  sudo \\\n  ffmpeg \\\n  git \\\n  make \\\n  gnupg \\\n  ca-certificates \\\n  mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Python3\"\n$STD apt-get install -y \\\n  python3 \\\n  python3-dev \\\n  python3-pip \\\n  python3-venv\nmsg_ok \"Installed Python3\"\n\nmsg_info \"Setting up Node.js Repository\"\nmkdir -p /etc/apt/keyrings\ncurl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg\necho \"deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main\" >/etc/apt/sources.list.d/nodesource.list\nmsg_ok \"Set up Node.js Repository\"\n\nmsg_info \"Installing Node.js\"\n$STD apt-get update\n$STD apt-get install -y nodejs\nmsg_ok \"Installed Node.js\"\n\nmsg_info \"Installing MeTube\"\n$STD git clone https://github.com/alexta69/metube /opt/metube\ncd /opt/metube/ui\n$STD npm install\n$STD node_modules/.bin/ng build\ncd /opt/metube\n$STD pip3 install pipenv\n$STD pipenv install\nmkdir -p /opt/metube_downloads /opt/metube_downloads/.metube /opt/metube_downloads/music /opt/metube_downloads/videos \ncat <<EOF >/opt/metube/.env\nDOWNLOAD_DIR=/opt/metube_downloads\nSTATE_DIR=/opt/metube_downloads/.metube\nTEMP_DIR=/opt/metube_downloads\nYTDL_OPTIONS={\"trim_file_name\":10}\nEOF\nmsg_ok \"Installed MeTube\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/metube.service\n[Unit]\nDescription=Metube - YouTube Downloader\nAfter=network.target\n\n[Service]\nType=simple\nWorkingDirectory=/opt/metube\nEnvironmentFile=/opt/metube/.env\nExecStart=/usr/local/bin/pipenv run python3 app/main.py\nRestart=always\nUser=root\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now metube.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/mongodb-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y gnupg\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing MongoDB\"\nwget -qO- https://www.mongodb.org/static/pgp/server-7.0.asc | gpg --dearmor >/usr/share/keyrings/mongodb-server-7.0.gpg\necho \"deb [signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg] http://repo.mongodb.org/apt/debian $(grep '^VERSION_CODENAME=' /etc/os-release | cut -d'=' -f2)/mongodb-org/7.0 main\" >/etc/apt/sources.list.d/mongodb-org-7.0.list\n$STD apt-get update\n$STD apt-get install -y mongodb-org\nsed -i 's/bindIp: 127.0.0.1/bindIp: 0.0.0.0/' /etc/mongod.conf\nsystemctl enable -q --now mongod.service\nmsg_ok \"Installed MongoDB\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/motioneye-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y git\n$STD apt-get install -y cifs-utils\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Updating Python3\"\n$STD apt-get install -y \\\n  python3 \\\n  python3-dev \\\n  python3-pip\nrm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED\nmsg_ok \"Updated Python3\"\n\nmsg_info \"Installing Motion\"\n$STD apt-get install -y motion\nsystemctl stop motion\n$STD systemctl disable motion\nmsg_ok \"Installed Motion\"\n\nmsg_info \"Installing FFmpeg\"\n$STD apt-get install -y ffmpeg v4l-utils\nmsg_ok \"Installed FFmpeg\"\n\nmsg_info \"Installing MotionEye\"\n$STD apt-get update\n$STD pip install git+https://github.com/motioneye-project/motioneye.git@dev\nmkdir -p /etc/motioneye\nchown -R root:root /etc/motioneye\nchmod -R 777 /etc/motioneye\nwget -qO /etc/motioneye/motioneye.conf https://raw.githubusercontent.com/motioneye-project/motioneye/dev/motioneye/extra/motioneye.conf.sample\nmkdir -p /var/lib/motioneye\nmsg_ok \"Installed MotionEye\"\n\nmsg_info \"Creating Service\"\nwget -qO /etc/systemd/system/motioneye.service https://raw.githubusercontent.com/motioneye-project/motioneye/dev/motioneye/extra/motioneye.systemd\nsystemctl enable -q --now motioneye\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/mqtt-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y gpg\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Mosquitto MQTT Broker\"\n$STD apt-get -y install mosquitto\n$STD apt-get -y install mosquitto-clients\ncat <<EOF >/etc/mosquitto/conf.d/default.conf\nallow_anonymous false\npersistence true\npassword_file /etc/mosquitto/passwd\nlistener 1883\nEOF\nmsg_ok \"Installed Mosquitto MQTT Broker\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/myspeed-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck\n# Co-Author: MickLesk (Canbiz)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n# Source: https://github.com/gnmyt/myspeed\n\nsource /dev/stdin <<<\"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y \\\n  curl \\\n  sudo \\\n  make \\\n  gpg \\\n  ca-certificates \\\n  mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Setting up Node.js Repository\"\nmkdir -p /etc/apt/keyrings\ncurl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg\necho \"deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main\" >/etc/apt/sources.list.d/nodesource.list\nmsg_ok \"Set up Node.js Repository\"\n\nmsg_info \"Installing Node.js\"\n$STD apt-get update\n$STD apt-get install -y nodejs\nmsg_ok \"Installed Node.js\"\n\nmsg_info \"Installing MySpeed\"\nRELEASE=$(wget -q https://github.com/gnmyt/myspeed/releases/latest -O - | grep \"title>Release\" | cut -d \" \" -f 5)\ncd /opt\nwget -q https://github.com/gnmyt/myspeed/releases/download/v$RELEASE/MySpeed-$RELEASE.zip\nunzip -q MySpeed-$RELEASE.zip -d myspeed\ncd myspeed\n$STD npm install\necho \"${RELEASE}\" >/opt/${APPLICATION}_version.txt\nmsg_ok \"Installed MySpeed\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/myspeed.service\n[Unit]\nDescription=MySpeed\nAfter=network.target\n\n[Service]\nType=simple\nExecStart=/usr/bin/node server\nRestart=always\nUser=root\nEnvironment=NODE_ENV=production\nWorkingDirectory=/opt/myspeed \n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now myspeed.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\nrm -rf /opt/MySpeed-$RELEASE.zip\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\""
  },
  {
    "path": "install/mysql-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck\n# Co-Author: MickLesk (Canbiz)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n# Source: https://www.mysql.com/products/community | https://www.phpmyadmin.net\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y \\\n  sudo \\\n  lsb-release \\\n  curl \\\n  gnupg \\\n  mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing MySQL\"\ncurl -fsSL https://repo.mysql.com/RPM-GPG-KEY-mysql-2023 | gpg --dearmor  -o /usr/share/keyrings/mysql.gpg\necho \"deb [signed-by=/usr/share/keyrings/mysql.gpg] http://repo.mysql.com/apt/debian $(lsb_release -sc) mysql-8.0\" >/etc/apt/sources.list.d/mysql.list\n$STD apt-get update\nexport DEBIAN_FRONTEND=noninteractive\n$STD apt-get install -y \\\n  mysql-community-client \\\n  mysql-community-server\nmsg_ok \"Installed MySQL\"\n\nmsg_info \"Configure MySQL Server\"\nADMIN_PASS=\"$(openssl rand -base64 18 | cut -c1-13)\"\n$STD mysql -uroot -p\"$ADMIN_PASS\" -e \"ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '$ADMIN_PASS'; FLUSH PRIVILEGES;\"\necho \"\" >~/mysql.creds\necho -e \"MySQL user: root\" >>~/mysql.creds\necho -e \"MySQL password: $ADMIN_PASS\" >>~/mysql.creds\nmsg_ok \"MySQL Server configured\"\n\nread -r -p \"Would you like to add PhpMyAdmin? <y/N> \" prompt\nif [[ ${prompt,,} =~ ^(y|yes)$ ]]; then\n  msg_info \"Installing phpMyAdmin\"\n  $STD apt-get install -y \\\n    apache2 \\\n    php \\\n    php-mysqli \\\n    php-mbstring \\\n    php-zip \\\n    php-gd \\\n    php-json \\\n    php-curl \n\t\n\twget -q \"https://files.phpmyadmin.net/phpMyAdmin/5.2.1/phpMyAdmin-5.2.1-all-languages.tar.gz\"\n\tmkdir -p /var/www/html/phpMyAdmin\n\ttar xf phpMyAdmin-5.2.1-all-languages.tar.gz --strip-components=1 -C /var/www/html/phpMyAdmin\n\tcp /var/www/html/phpMyAdmin/config.sample.inc.php /var/www/html/phpMyAdmin/config.inc.php\n\tSECRET=$(openssl rand -base64 24)\n\tsed -i \"s#\\$cfg\\['blowfish_secret'\\] = '';#\\$cfg['blowfish_secret'] = '${SECRET}';#\" /var/www/html/phpMyAdmin/config.inc.php\n\tchmod 660 /var/www/html/phpMyAdmin/config.inc.php\n\tchown -R www-data:www-data /var/www/html/phpMyAdmin\n\tsystemctl restart apache2\n  msg_ok \"Installed phpMyAdmin\"\nfi\n\nmsg_info \"Start Service\"\nsystemctl enable -q --now mysql\nmsg_ok \"Service started\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/n8n-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y ca-certificates\n$STD apt-get install -y gnupg\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Setting up Node.js Repository\"\nmkdir -p /etc/apt/keyrings\ncurl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg\necho \"deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main\" >/etc/apt/sources.list.d/nodesource.list\nmsg_ok \"Set up Node.js Repository\"\n\nmsg_info \"Installing Node.js\"\n$STD apt-get update\n$STD apt-get install -y nodejs\nmsg_ok \"Installed Node.js\"\n\nmsg_info \"Installing n8n (Patience)\"\n$STD npm install --global patch-package\n$STD npm install --global n8n\nmsg_ok \"Installed n8n\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/n8n.service\n[Unit]\nDescription=n8n\n\n[Service]\nType=simple\nEnvironment=\"N8N_SECURE_COOKIE=false\"\nExecStart=n8n start\n[Install]\nWantedBy=multi-user.target\nEOF\n$STD systemctl enable --now n8n\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/navidrome-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies (patience)\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y ffmpeg\nmsg_ok \"Installed Dependencies\"\n\nRELEASE=$(curl -s https://api.github.com/repos/navidrome/navidrome/releases/latest | grep \"tag_name\" | awk '{print substr($2, 3, length($2)-4) }')\n\nmsg_info \"Installing Navidrome\"\ninstall -d -o root -g root /opt/navidrome\ninstall -d -o root -g root /var/lib/navidrome\nwget -q https://github.com/navidrome/navidrome/releases/download/v${RELEASE}/navidrome_${RELEASE}_linux_amd64.tar.gz -O Navidrome.tar.gz\n$STD tar -xvzf Navidrome.tar.gz -C /opt/navidrome/\nchown -R root:root /opt/navidrome\nmkdir -p /music\ncat <<EOF >/var/lib/navidrome/navidrome.toml\nMusicFolder = '/music'\nEOF\nmsg_ok \"Installed Navidrome\"\n\nmsg_info \"Creating Service\"\nservice_path=\"/etc/systemd/system/navidrome.service\"\n\necho \"[Unit]\nDescription=Navidrome Music Server and Streamer compatible with Subsonic/Airsonic\nAfter=remote-fs.target network.target\nAssertPathExists=/var/lib/navidrome\n\n[Service]\nUser=root\nGroup=root\nType=simple\nExecStart=/opt/navidrome/navidrome --configfile '/var/lib/navidrome/navidrome.toml'\nWorkingDirectory=/var/lib/navidrome\nTimeoutStopSec=20\nKillMode=process\nRestart=on-failure\nDevicePolicy=closed\nNoNewPrivileges=yes\nPrivateTmp=yes\nPrivateUsers=yes\nProtectControlGroups=yes\nProtectKernelModules=yes\nProtectKernelTunables=yes\nRestrictAddressFamilies=AF_UNIX AF_INET AF_INET6\nRestrictNamespaces=yes\nRestrictRealtime=yes\nSystemCallFilter=~@clock @debug @module @mount @obsolete @reboot @setuid @swap\nReadWritePaths=/var/lib/navidrome\nProtectSystem=full\n\n[Install]\nWantedBy=multi-user.target\" >$service_path\nsystemctl daemon-reload\n$STD systemctl enable --now navidrome.service\n\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nrm -rf /root/Navidrome.tar.gz\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/neo4j-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck\n# Co-Author: havardthom\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y gpg\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Neo4j (patience)\"\nwget -qO- https://debian.neo4j.com/neotechnology.gpg.key | gpg --dearmor -o /etc/apt/keyrings/neotechnology.gpg\necho 'deb [signed-by=/etc/apt/keyrings/neotechnology.gpg] https://debian.neo4j.com stable latest' > /etc/apt/sources.list.d/neo4j.list\n$STD apt-get update\n$STD apt-get install -y neo4j\nsed -i '/server.default_listen_address/s/^#//' /etc/neo4j/neo4j.conf\nsystemctl enable -q --now neo4j\nmsg_ok \"Installed Neo4j\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/nextcloudpi-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing NextCloudPi (Patience)\"\n$STD apt-get install -y systemd-resolved\nsystemctl enable -q --now systemd-resolved\ncat <<'EOF' >/etc/systemd/resolved.conf\n[Resolve]\nDNS=8.8.8.8\nFallbackDNS=8.8.4.4\nEOF\nsystemctl restart systemd-resolved\n$STD bash <(curl -fsSL https://raw.githubusercontent.com/nextcloud/nextcloudpi/master/install.sh)\nsystemctl disable -q --now systemd-resolved\n$STD apt-get remove -y systemd-resolved\nmsg_ok \"Installed NextCloudPi\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/nginxproxymanager-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<<\"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get update\n$STD apt-get -y install \\\n  sudo \\\n  mc \\\n  curl \\\n  gnupg \\\n  make \\\n  gcc \\\n  g++ \\\n  ca-certificates \\\n  apache2-utils \\\n  logrotate \\\n  build-essential \\\n  git\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Python Dependencies\"\n$STD apt-get install -y \\\n  python3 \\\n  python3-dev \\\n  python3-pip \\\n  python3-venv \\\n  python3-cffi \\\n  python3-certbot \\\n  python3-certbot-dns-cloudflare\n$STD pip3 install certbot-dns-multi\n$STD python3 -m venv /opt/certbot/\nrm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED\nmsg_ok \"Installed Python Dependencies\"\n\nVERSION=\"$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)\"\n\nmsg_info \"Installing Openresty\"\nwget -qO - https://openresty.org/package/pubkey.gpg | gpg --dearmor -o /etc/apt/trusted.gpg.d/openresty-archive-keyring.gpg\necho -e \"deb http://openresty.org/package/debian bullseye openresty\" >/etc/apt/sources.list.d/openresty.list\n$STD apt-get update\n$STD apt-get -y install openresty\nmsg_ok \"Installed Openresty\"\n\nmsg_info \"Installing Node.js\"\n$STD bash <(curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh)\nsource ~/.bashrc\n$STD nvm install 16.20.2\nln -sf /root/.nvm/versions/node/v16.20.2/bin/node /usr/bin/node\nmsg_ok \"Installed Node.js\"\n\nmsg_info \"Installing pnpm\"\n$STD npm install -g pnpm@8.15\nmsg_ok \"Installed pnpm\"\n\nRELEASE=$(curl -s https://api.github.com/repos/NginxProxyManager/nginx-proxy-manager/releases/latest |\n  grep \"tag_name\" |\n  awk '{print substr($2, 3, length($2)-4) }')\n\nread -r -p \"Would you like to install an older version (v2.10.4)? <y/N> \" prompt\nif [[ ${prompt,,} =~ ^(y|yes)$ ]]; then\n  msg_info \"Downloading Nginx Proxy Manager v2.10.4\"\n  wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v2.10.4 -O - | tar -xz\n  cd ./nginx-proxy-manager-2.10.4\n  msg_ok \"Downloaded Nginx Proxy Manager v2.10.4\"\nelse\n  msg_info \"Downloading Nginx Proxy Manager v${RELEASE}\"\n  wget -q https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v${RELEASE} -O - | tar -xz\n  cd ./nginx-proxy-manager-${RELEASE}\n  msg_ok \"Downloaded Nginx Proxy Manager v${RELEASE}\"\nfi\nmsg_info \"Setting up Enviroment\"\nln -sf /usr/bin/python3 /usr/bin/python\nln -sf /usr/bin/certbot /opt/certbot/bin/certbot\nln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx\nln -sf /usr/local/openresty/nginx/ /etc/nginx\nif [[ ${prompt,,} =~ ^(y|yes)$ ]]; then\n  sed -i \"s|\\\"version\\\": \\\"0.0.0\\\"|\\\"version\\\": \\\"2.10.4\\\"|\" backend/package.json\n  sed -i \"s|\\\"version\\\": \\\"0.0.0\\\"|\\\"version\\\": \\\"2.10.4\\\"|\" frontend/package.json\nelse\n  sed -i \"s|\\\"version\\\": \\\"0.0.0\\\"|\\\"version\\\": \\\"$RELEASE\\\"|\" backend/package.json\n  sed -i \"s|\\\"version\\\": \\\"0.0.0\\\"|\\\"version\\\": \\\"$RELEASE\\\"|\" frontend/package.json\nfi\nsed -i 's|\"fork-me\": \".*\"|\"fork-me\": \"Proxmox VE Helper-Scripts\"|' frontend/js/i18n/messages.json\nsed -i \"s|https://github.com.*source=nginx-proxy-manager|https://helper-scripts.com|g\" frontend/js/app/ui/footer/main.ejs\nsed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf\nNGINX_CONFS=$(find \"$(pwd)\" -type f -name \"*.conf\")\nfor NGINX_CONF in $NGINX_CONFS; do\n  sed -i 's+include conf.d+include /etc/nginx/conf.d+g' \"$NGINX_CONF\"\ndone\n\nmkdir -p /var/www/html /etc/nginx/logs\ncp -r docker/rootfs/var/www/html/* /var/www/html/\ncp -r docker/rootfs/etc/nginx/* /etc/nginx/\ncp docker/rootfs/etc/letsencrypt.ini /etc/letsencrypt.ini\ncp docker/rootfs/etc/logrotate.d/nginx-proxy-manager /etc/logrotate.d/nginx-proxy-manager\nln -sf /etc/nginx/nginx.conf /etc/nginx/conf/nginx.conf\nrm -f /etc/nginx/conf.d/dev.conf\n\nmkdir -p /tmp/nginx/body \\\n  /run/nginx \\\n  /data/nginx \\\n  /data/custom_ssl \\\n  /data/logs \\\n  /data/access \\\n  /data/nginx/default_host \\\n  /data/nginx/default_www \\\n  /data/nginx/proxy_host \\\n  /data/nginx/redirection_host \\\n  /data/nginx/stream \\\n  /data/nginx/dead_host \\\n  /data/nginx/temp \\\n  /var/lib/nginx/cache/public \\\n  /var/lib/nginx/cache/private \\\n  /var/cache/nginx/proxy_temp\n\nchmod -R 777 /var/cache/nginx\nchown root /tmp/nginx\n\necho resolver \"$(awk 'BEGIN{ORS=\" \"} $1==\"nameserver\" {print ($2 ~ \":\")? \"[\"$2\"]\": $2}' /etc/resolv.conf);\" >/etc/nginx/conf.d/include/resolvers.conf\n\nif [ ! -f /data/nginx/dummycert.pem ] || [ ! -f /data/nginx/dummykey.pem ]; then\n  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 &>/dev/null\nfi\n\nmkdir -p /app/global /app/frontend/images\ncp -r backend/* /app\ncp -r global/* /app/global\nmsg_ok \"Set up Enviroment\"\n\nmsg_info \"Building Frontend\"\ncd ./frontend\n$STD pnpm install\n$STD pnpm upgrade\n$STD pnpm run build\ncp -r dist/* /app/frontend\ncp -r app-images/* /app/frontend/images\nmsg_ok \"Built Frontend\"\n\nmsg_info \"Initializing Backend\"\nrm -rf /app/config/default.json\nif [ ! -f /app/config/production.json ]; then\n  cat <<'EOF' >/app/config/production.json\n{\n  \"database\": {\n    \"engine\": \"knex-native\",\n    \"knex\": {\n      \"client\": \"sqlite3\",\n      \"connection\": {\n        \"filename\": \"/data/database.sqlite\"\n      }\n    }\n  }\n}\nEOF\nfi\ncd /app\n$STD pnpm install\nmsg_ok \"Initialized Backend\"\n\nmsg_info \"Creating Service\"\ncat <<'EOF' >/lib/systemd/system/npm.service\n[Unit]\nDescription=Nginx Proxy Manager\nAfter=network.target\nWants=openresty.service\n\n[Service]\nType=simple\nEnvironment=NODE_ENV=production\nExecStartPre=-mkdir -p /tmp/nginx/body /data/letsencrypt-acme-challenge\nExecStart=/usr/bin/node index.js --abort_on_uncaught_exception --max_old_space_size=250\nWorkingDirectory=/app\nRestart=on-failure\n\n[Install]\nWantedBy=multi-user.target\nEOF\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Starting Services\"\nsed -i 's/user npm/user root/g; s/^pid/#pid/g' /usr/local/openresty/nginx/conf/nginx.conf\nsed -r -i 's/^([[:space:]]*)su npm npm/\\1#su npm npm/g;' /etc/logrotate.d/nginx-proxy-manager\nsed -i 's/include-system-site-packages = false/include-system-site-packages = true/g' /opt/certbot/pyvenv.cfg\nsystemctl enable -q --now openresty\nsystemctl enable -q --now npm\nmsg_ok \"Started Services\"\n\nmsg_info \"Cleaning up\"\nrm -rf ../nginx-proxy-manager-*\nsystemctl restart openresty\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/nocodb-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing NocoDB\"\nmkdir -p /opt/nocodb\ncd /opt/nocodb\ncurl -s http://get.nocodb.com/linux-x64 -o nocodb -L\nchmod +x nocodb\nmsg_ok \"Installed NocoDB\"\n\nmsg_info \"Creating Service\"\nservice_path=\"/etc/systemd/system/nocodb.service\"\necho \"[Unit]\nDescription=nocodb\n\n[Service]\nType=simple\nRestart=always\nUser=root\nWorkingDirectory=/opt/nocodb\nExecStart=/opt/nocodb/./nocodb\n\n[Install]\nWantedBy=multi-user.target\" >$service_path\nsystemctl enable -q --now nocodb.service &>/dev/null\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/node-red-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y git\n$STD apt-get install -y ca-certificates\n$STD apt-get install -y gnupg\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Setting up Node.js Repository\"\nmkdir -p /etc/apt/keyrings\ncurl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg\necho \"deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main\" >/etc/apt/sources.list.d/nodesource.list\nmsg_ok \"Set up Node.js Repository\"\n\nmsg_info \"Installing Node.js\"\n$STD apt-get update\n$STD apt-get install -y nodejs\nmsg_ok \"Installed Node.js\"\n\nmsg_info \"Installing Node-Red\"\n$STD npm install -g --unsafe-perm node-red\necho \"journalctl -f -n 100 -u nodered -o cat\" >/usr/bin/node-red-log\nchmod +x /usr/bin/node-red-log\necho \"systemctl stop nodered\" >/usr/bin/node-red-stop\nchmod +x /usr/bin/node-red-stop\necho \"systemctl start nodered\" >/usr/bin/node-red-start\nchmod +x /usr/bin/node-red-start\necho \"systemctl restart nodered\" >/usr/bin/node-red-restart\nchmod +x /usr/bin/node-red-restart\nmsg_ok \"Installed Node-Red\"\n\nmsg_info \"Creating Service\"\nservice_path=\"/etc/systemd/system/nodered.service\"\necho \"[Unit]\nDescription=Node-RED\nAfter=syslog.target network.target\n\n[Service]\nExecStart=/usr/bin/node-red --max-old-space-size=128 -v\nRestart=on-failure\nKillSignal=SIGINT\n\nSyslogIdentifier=node-red\nStandardOutput=syslog\n\nWorkingDirectory=/root/\nUser=root\nGroup=root\n\n[Install]\nWantedBy=multi-user.target\" >$service_path\n$STD systemctl enable --now nodered.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/notifiarr-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y gpg\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Notifiarr\"\n$STD groupadd notifiarr\n$STD useradd -g notifiarr notifiarr\nwget -qO- https://packagecloud.io/golift/pkgs/gpgkey | gpg --dearmor >/usr/share/keyrings/golift-archive-keyring.gpg\necho \"deb [signed-by=/usr/share/keyrings/golift-archive-keyring.gpg] https://packagecloud.io/golift/pkgs/ubuntu focal main\" >/etc/apt/sources.list.d/golift.list\n$STD apt-get update\n$STD apt-get install -y notifiarr\nmsg_ok \"Installed Notifiarr\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/ntfy-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y gpg\n$STD apt-get install -y apt-transport-https\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing ntfy\"\nmkdir -p /etc/apt/keyrings\ncurl -fsSL https://archive.heckel.io/apt/pubkey.txt | gpg --dearmor -o /etc/apt/keyrings/archive.heckel.io.gpg\necho \"deb [arch=amd64 signed-by=/etc/apt/keyrings/archive.heckel.io.gpg] https://archive.heckel.io/apt debian main\" >/etc/apt/sources.list.d/archive.heckel.io.list  \n$STD apt-get update\n$STD apt-get install -y ntfy\nsystemctl enable -q --now ntfy\nmsg_ok \"Installed ntfy\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/nzbget-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck\n# Co-Author: havardthom\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y gpg\n$STD apt-get install -y par2\ncat <<EOF >/etc/apt/sources.list.d/non-free.list\ndeb http://deb.debian.org/debian bookworm main contrib non-free non-free-firmware\nEOF\n$STD apt-get update\n$STD apt-get install -y unrar\nrm /etc/apt/sources.list.d/non-free.list\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing NZBGet\"\nmkdir -p /etc/apt/keyrings\ncurl -fsSL https://nzbgetcom.github.io/nzbgetcom.asc | gpg --dearmor -o /etc/apt/keyrings/nzbgetcom.gpg\necho \"deb [signed-by=/etc/apt/keyrings/nzbgetcom.gpg] https://nzbgetcom.github.io/deb stable main\" >/etc/apt/sources.list.d/nzbgetcom.list\n$STD apt-get update\n$STD apt-get install -y nzbget\nmsg_ok \"Installed NZBGet\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/octoprint-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y git\n$STD apt-get install -y libyaml-dev\n$STD apt-get install -y build-essential\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Updating Python3\"\n$STD apt-get install -y \\\n  python3 \\\n  python3-dev \\\n  python3-pip \\\n  python3-venv\n\n$STD apt-get install -y python3-setuptools\nrm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED\nmsg_ok \"Updated Python3\"\n\nmsg_info \"Creating user octoprint\"\nuseradd -m -s /bin/bash -p $(openssl passwd -1 octoprint) octoprint\nusermod -aG sudo,tty,dialout octoprint\nchown -R octoprint:octoprint /opt\necho \"octoprint ALL=NOPASSWD: $(command -v systemctl) restart octoprint, $(command -v reboot), $(command -v poweroff)\" > /etc/sudoers.d/octoprint\nmsg_ok \"Created user octoprint\"\n\nmsg_info \"Installing OctoPrint\"\n$STD sudo -u octoprint bash << EOF\nmkdir /opt/octoprint\ncd /opt/octoprint\npython3 -m venv .\nsource bin/activate\npip install --upgrade pip\npip install wheel\npip install octoprint\nEOF\nmsg_ok \"Installed OctoPrint\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/octoprint.service\n[Unit]\nDescription=The snappy web interface for your 3D printer\nAfter=network-online.target\nWants=network-online.target\n\n[Service]\nEnvironment=\"LC_ALL=C.UTF-8\"\nEnvironment=\"LANG=C.UTF-8\"\nType=exec\nUser=octoprint\nExecStart=/opt/octoprint/bin/octoprint serve\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now octoprint.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/ollama-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck\n# Co-Author: havardthom\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y gpg\n$STD apt-get install -y git\n$STD apt-get install -y build-essential\n$STD apt-get install -y pkg-config\n$STD apt-get install -y cmake\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Golang\"\n$STD wget https://golang.org/dl/go1.23.2.linux-amd64.tar.gz\n$STD tar -xzf go1.23.2.linux-amd64.tar.gz -C /usr/local\n$STD ln -s /usr/local/go/bin/go /usr/local/bin/go\nrm -rf go1.23.2.linux-amd64.tar.gz\nmsg_ok \"Installed Golang\"\n\nmsg_info \"Setting up Intel® Repositories\"\nmkdir -p /etc/apt/keyrings\ncurl -fsSL https://repositories.intel.com/gpu/intel-graphics.key | gpg --dearmor -o /etc/apt/keyrings/intel-graphics.gpg\necho \"deb [arch=amd64,i386 signed-by=/etc/apt/keyrings/intel-graphics.gpg] https://repositories.intel.com/gpu/ubuntu jammy client\" >/etc/apt/sources.list.d/intel-gpu-jammy.list\ncurl -fsSL https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB | gpg --dearmor -o /etc/apt/keyrings/oneapi-archive-keyring.gpg\necho \"deb [signed-by=/etc/apt/keyrings/oneapi-archive-keyring.gpg] https://apt.repos.intel.com/oneapi all main\" >/etc/apt/sources.list.d/oneAPI.list\n$STD apt-get update\nmsg_ok \"Set up Intel® Repositories\"\n\nmsg_info \"Setting Up Hardware Acceleration\"\n$STD apt-get -y install {va-driver-all,ocl-icd-libopencl1,intel-opencl-icd,vainfo,intel-gpu-tools,intel-level-zero-gpu,level-zero,level-zero-dev}\nif [[ \"$CTTYPE\" == \"0\" ]]; then\n  chgrp video /dev/dri\n  chmod 755 /dev/dri\n  chmod 660 /dev/dri/*\n  $STD adduser $(id -u -n) video\n  $STD adduser $(id -u -n) render\nfi\nmsg_ok \"Set Up Hardware Acceleration\"\n\nmsg_info \"Installing Intel® oneAPI Base Toolkit (Patience)\"\n$STD apt-get install -y --no-install-recommends intel-basekit-2024.1\nmsg_ok \"Installed Intel® oneAPI Base Toolkit\"\n\nmsg_info \"Installing Ollama (Patience)\"\n$STD git clone https://github.com/ollama/ollama.git /opt/ollama\ncd /opt/ollama\n$STD go generate ./...\n$STD go build .\nmsg_ok \"Installed Ollama\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/ollama.service\n[Unit]\nDescription=Ollama Service\nAfter=network-online.target\n\n[Service]\nType=exec\nExecStart=/opt/ollama/ollama serve\nEnvironment=HOME=$HOME\nEnvironment=OLLAMA_INTEL_GPU=true\nEnvironment=OLLAMA_HOST=0.0.0.0\nEnvironment=OLLAMA_NUM_GPU=999\nEnvironment=SYCL_CACHE_PERSISTENT=1\nEnvironment=ZES_ENABLE_SYSMAN=1\nRestart=always\nRestartSec=3\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now ollama.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/omada-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y gnupg\n$STD apt-get install -y jsvc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Azul Zulu\"\nwget -qO /etc/apt/trusted.gpg.d/zulu-repo.asc \"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xB1998361219BD9C9\"\nwget -q https://cdn.azul.com/zulu/bin/zulu-repo_1.0.0-3_all.deb\n$STD dpkg -i zulu-repo_1.0.0-3_all.deb\n$STD apt-get update\n$STD apt-get -y install zulu8-jdk\nmsg_ok \"Installed Azul Zulu\"\n\nmsg_info \"Installing MongoDB\"\nlibssl=$(curl -fsSL \"http://security.ubuntu.com/ubuntu/pool/main/o/openssl/\" | grep -o 'libssl1\\.1_1\\.1\\.1f-1ubuntu2\\.2[^\"]*amd64\\.deb' | head -n1)\nwget -qL http://security.ubuntu.com/ubuntu/pool/main/o/openssl/$libssl\n$STD dpkg -i $libssl\nwget -qL https://repo.mongodb.org/apt/ubuntu/dists/bionic/mongodb-org/3.6/multiverse/binary-amd64/mongodb-org-server_3.6.23_amd64.deb\n$STD dpkg -i mongodb-org-server_3.6.23_amd64.deb\nmsg_ok \"Installed MongoDB\"\n\nlatest_url=$(curl -fsSL \"https://www.tp-link.com/en/support/download/omada-software-controller/\" | grep -o 'https://.*x64.deb' | head -n1)\nlatest_version=$(basename \"$latest_url\")\n\nmsg_info \"Installing Omada Controller\"\nwget -qL ${latest_url}\n$STD dpkg -i ${latest_version}\nmsg_ok \"Installed Omada Controller\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\nrm -rf ${latest_version} mongodb-org-server_3.6.23_amd64.deb zulu-repo_1.0.0-3_all.deb $libssl\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/ombi-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Ombi\"\nRELEASE=$(curl -sL https://api.github.com/repos/Ombi-app/Ombi/releases/latest | grep '\"tag_name\":' | cut -d'\"' -f4)\nwget -q https://github.com/Ombi-app/Ombi/releases/download/${RELEASE}/linux-x64.tar.gz\necho \"${RELEASE}\" >/opt/${APPLICATION}_version.txt\nmkdir -p /opt/ombi\ntar -xzf linux-x64.tar.gz -C /opt/ombi\nrm -rf linux-x64.tar.gz\nmsg_ok \"Installed Ombi\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/ombi.service\n[Unit]\nDescription=Ombi\nAfter=syslog.target network-online.target\n\n[Service]\nExecStart=/opt/ombi/./Ombi\nWorkingDirectory=/opt/ombi\nRestart=always\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now ombi.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/omv-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y gpg\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing OpenMediaVault (Patience)\"\nwget -qO- https://packages.openmediavault.org/public/archive.key | gpg --dearmor >\"/etc/apt/trusted.gpg.d/openmediavault-archive-keyring.gpg\"\n\ncat <<EOF >/etc/apt/sources.list.d/openmediavault.list\ndeb [signed-by=/etc/apt/trusted.gpg.d/openmediavault-archive-keyring.gpg] http://packages.openmediavault.org/public sandworm main\nEOF\n\nexport LANG=C.UTF-8\nexport DEBIAN_FRONTEND=noninteractive\nexport APT_LISTCHANGES_FRONTEND=none\n$STD apt-get update\napt-get -y --auto-remove --show-upgraded --allow-downgrades --allow-change-held-packages --no-install-recommends --option DPkg::Options::=\"--force-confdef\" --option DPkg::Options::=\"--force-confold\" install openmediavault-keyring openmediavault &>/dev/null\nomv-confdbadm populate &>/dev/null\nmsg_ok \"Installed OpenMediaVault\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/openhab-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y gnupg\n$STD apt-get install -y apt-transport-https\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Azul Zulu\"\nwget -qO /etc/apt/trusted.gpg.d/zulu-repo.asc \"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xB1998361219BD9C9\"\nwget -q https://cdn.azul.com/zulu/bin/zulu-repo_1.0.0-3_all.deb\n$STD dpkg -i zulu-repo_1.0.0-3_all.deb\n$STD apt-get update\n$STD apt-get -y install zulu17-jdk\nmsg_ok \"Installed Azul Zulu\"\n\nmsg_info \"Installing openHAB\"\ncurl -fsSL \"https://openhab.jfrog.io/artifactory/api/gpg/key/public\" | gpg --dearmor >openhab.gpg\nmv openhab.gpg /usr/share/keyrings\nchmod u=rw,g=r,o=r /usr/share/keyrings/openhab.gpg\necho \"deb [signed-by=/usr/share/keyrings/openhab.gpg] https://openhab.jfrog.io/artifactory/openhab-linuxpkg stable main\" > /etc/apt/sources.list.d/openhab.list\n$STD apt update\n$STD apt-get -y install openhab\nsystemctl daemon-reload\nsystemctl enable -q --now openhab.service\nmsg_ok \"Installed openHAB\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/openobserve-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing OpenObserve\"\nmkdir -p /opt/openobserve/data\nLATEST=$(curl -sL https://api.github.com/repos/openobserve/openobserve/releases/latest | grep '\"tag_name\":' | cut -d'\"' -f4)\n$STD tar zxvf <(curl -fsSL https://github.com/openobserve/openobserve/releases/download/$LATEST/openobserve-${LATEST}-linux-amd64.tar.gz) -C /opt/openobserve\n\ncat <<EOF >/opt/openobserve/data/.env\nZO_ROOT_USER_EMAIL = \"admin@example.com\"\nZO_ROOT_USER_PASSWORD = \"$(openssl rand -base64 18 | cut -c1-13)\"\nZO_DATA_DIR = \"/opt/openobserve/data\"\nZO_HTTP_PORT = \"5080\"\nEOF\nmsg_ok \"Installed OpenObserve\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/openobserve.service\n[Unit]\nDescription=OpenObserve\nAfter=network.target\n\n[Service]\nType=simple\nEnvironmentFile=/opt/openobserve/data/.env\nExecStart=/opt/openobserve/openobserve\nExecStop=killall -QUIT openobserve\nRestart=on-failure\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now openobserve\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/openwebui-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck\n# Co-Author: havardthom\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y gpg\n$STD apt-get install -y git\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Python3 Dependencies\"\n$STD apt-get install -y --no-install-recommends \\\n  python3 \\\n  python3-pip\nmsg_ok \"Installed Python3 Dependencies\"\n\nmsg_info \"Setting up Node.js Repository\"\nmkdir -p /etc/apt/keyrings\ncurl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg\necho \"deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main\" >/etc/apt/sources.list.d/nodesource.list\nmsg_ok \"Set up Node.js Repository\"\n\nmsg_info \"Installing Node.js\"\n$STD apt-get update\n$STD apt-get install -y nodejs\nmsg_ok \"Installed Node.js\"\n\nmsg_info \"Installing Open WebUI (Patience)\"\n$STD git clone https://github.com/open-webui/open-webui.git /opt/open-webui\ncd /opt/open-webui/backend\n$STD pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu\n$STD pip3 install -r requirements.txt -U\ncd /opt/open-webui\ncp .env.example .env\ncat <<EOF >/opt/open-webui/.env\nENV=prod\nENABLE_OLLAMA_API=false\nOLLAMA_BASE_URL=http://0.0.0.0:11434\nEOF\n$STD npm install\nexport NODE_OPTIONS=\"--max-old-space-size=3584\"\n$STD npm run build\nmsg_ok \"Installed Open WebUI\"\n\nread -r -p \"Would you like to add Ollama? <y/N> \" prompt\nif [[ ${prompt,,} =~ ^(y|yes)$ ]]; then\n  msg_info \"Installing Ollama\"\n  curl -fsSLO https://ollama.com/download/ollama-linux-amd64.tgz\n  tar -C /usr -xzf ollama-linux-amd64.tgz\n  rm -rf ollama-linux-amd64.tgz\n  cat <<EOF >/etc/systemd/system/ollama.service\n[Unit]\nDescription=Ollama Service\nAfter=network-online.target\n\n[Service]\nType=exec\nExecStart=/usr/bin/ollama serve\nEnvironment=HOME=$HOME\nEnvironment=OLLAMA_HOST=0.0.0.0\nRestart=always\nRestartSec=3\n\n[Install]\nWantedBy=multi-user.target\nEOF\n  systemctl enable -q --now ollama.service\n  sed -i 's/ENABLE_OLLAMA_API=false/ENABLE_OLLAMA_API=true/g' /opt/open-webui/.env\n  msg_ok \"Installed Ollama\"\nfi\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/open-webui.service\n[Unit]\nDescription=Open WebUI Service\nAfter=network.target\n\n[Service]\nType=exec\nWorkingDirectory=/opt/open-webui\nEnvironmentFile=/opt/open-webui/.env\nExecStart=/opt/open-webui/backend/start.sh\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now open-webui.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/overseerr-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y git\n$STD apt-get install -y ca-certificates\n$STD apt-get install -y gnupg\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Setting up Node.js Repository\"\nmkdir -p /etc/apt/keyrings\ncurl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg\necho \"deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main\" >/etc/apt/sources.list.d/nodesource.list\nmsg_ok \"Set up Node.js Repository\"\n\nmsg_info \"Installing Node.js\"\n$STD apt-get update\n$STD apt-get install -y nodejs\nmsg_ok \"Installed Node.js\"\n\nmsg_info \"Installing Yarn\"\n$STD npm install -g yarn\nmsg_ok \"Installed Yarn\"\n\nmsg_info \"Installing Overseerr (Patience)\"\ngit clone -q https://github.com/sct/overseerr.git /opt/overseerr\ncd /opt/overseerr\n$STD yarn install\n$STD yarn build\nmsg_ok \"Installed Overseerr\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/overseerr.service\n[Unit]\nDescription=Overseerr Service\nAfter=network.target\n\n[Service]\nType=exec\nWorkingDirectory=/opt/overseerr\nExecStart=/usr/bin/yarn start\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now overseerr.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/owncast-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies (Patience)\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y ffmpeg\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Owncast\"\nmkdir /opt/owncast\ncd /opt/owncast\nwget -q $(curl -s https://api.github.com/repos/owncast/owncast/releases/latest | grep download | grep linux-64bit | cut -d\\\" -f4)\n$STD unzip owncast*.zip\nrm owncast*.zip\nmsg_ok \"Installed Owncast\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/owncast.service\n[Unit]\nDescription=Owncast\nAfter=syslog.target network-online.target\n\n[Service]\nExecStart=/opt/owncast/./owncast\nWorkingDirectory=/opt/owncast\nRestart=always\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now owncast.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/pairdrop-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y git\n$STD apt-get install -y gpg\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Setting up Node.js Repository\"\nmkdir -p /etc/apt/keyrings\ncurl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg\necho \"deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main\" >/etc/apt/sources.list.d/nodesource.list\nmsg_ok \"Set up Node.js Repository\"\n\nmsg_info \"Installing Node.js\"\n$STD apt-get update\n$STD apt-get install -y nodejs\nmsg_ok \"Installed Node.js\"\n\nmsg_info \"Installing PairDrop\"\ngit clone -q https://github.com/schlagmichdoch/PairDrop.git /opt/pairdrop\ncd /opt/pairdrop\n$STD npm install\nmsg_ok \"Installed PairDrop\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/pairdrop.service\n[Unit]\nDescription=PairDrop Service\nAfter=network.target\n\n[Service]\nExecStart=npm start\nWorkingDirectory=/opt/pairdrop\nRestart=always\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now pairdrop.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/paperless-ngx-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<<\"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies (Patience)\"\n$STD apt-get install -y --no-install-recommends \\\n  redis \\\n  postgresql \\\n  build-essential \\\n  imagemagick \\\n  fonts-liberation \\\n  optipng \\\n  gnupg \\\n  libpq-dev \\\n  libmagic-dev \\\n  mime-support \\\n  libzbar0 \\\n  poppler-utils \\\n  default-libmysqlclient-dev \\\n  automake \\\n  libtool \\\n  pkg-config \\\n  git \\\n  curl \\\n  libtiff-dev \\\n  libpng-dev \\\n  libleptonica-dev \\\n  sudo \\\n  mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Python3 Dependencies (Patience)\"\n$STD apt-get install -y --no-install-recommends \\\n  python3 \\\n  python3-pip \\\n  python3-dev \\\n  python3-setuptools \\\n  python3-wheel\nmsg_ok \"Installed Python3 Dependencies\"\n\nmsg_info \"Installing OCR Dependencies (Patience)\"\n$STD apt-get install -y --no-install-recommends \\\n  unpaper \\\n  icc-profiles-free \\\n  qpdf \\\n  liblept5 \\\n  libxml2 \\\n  pngquant \\\n  zlib1g \\\n  tesseract-ocr \\\n  tesseract-ocr-eng\n  \ncd /tmp\nwget -q https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/gs10040/ghostscript-10.04.0.tar.gz\n$STD tar -xzf ghostscript-10.04.0.tar.gz\ncd ghostscript-10.04.0\n$STD ./configure\n$STD make\n$STD sudo make install\nmsg_ok \"Installed OCR Dependencies\"\n\nmsg_info \"Installing JBIG2\"\n$STD git clone https://github.com/ie13/jbig2enc /opt/jbig2enc\ncd /opt/jbig2enc\n$STD bash ./autogen.sh\n$STD bash ./configure\n$STD make\n$STD make install\nrm -rf /opt/jbig2enc\nmsg_ok \"Installed JBIG2\"\n\nmsg_info \"Installing Paperless-ngx (Patience)\"\nPaperlessngx=$(wget -q https://github.com/paperless-ngx/paperless-ngx/releases/latest -O - | grep \"title>Release\" | cut -d \" \" -f 5)\ncd /opt\n$STD wget https://github.com/paperless-ngx/paperless-ngx/releases/download/$Paperlessngx/paperless-ngx-$Paperlessngx.tar.xz\n$STD tar -xf paperless-ngx-$Paperlessngx.tar.xz -C /opt/\nmv paperless-ngx paperless\nrm paperless-ngx-$Paperlessngx.tar.xz\ncd /opt/paperless\n$STD pip install --upgrade pip\n$STD pip install -r requirements.txt\ncurl -s -o /opt/paperless/paperless.conf https://raw.githubusercontent.com/paperless-ngx/paperless-ngx/main/paperless.conf.example\nmkdir -p {consume,data,media,static}\nsed -i -e 's|#PAPERLESS_REDIS=redis://localhost:6379|PAPERLESS_REDIS=redis://localhost:6379|' /opt/paperless/paperless.conf\nsed -i -e \"s|#PAPERLESS_CONSUMPTION_DIR=../consume|PAPERLESS_CONSUMPTION_DIR=/opt/paperless/consume|\" /opt/paperless/paperless.conf\nsed -i -e \"s|#PAPERLESS_DATA_DIR=../data|PAPERLESS_DATA_DIR=/opt/paperless/data|\" /opt/paperless/paperless.conf\nsed -i -e \"s|#PAPERLESS_MEDIA_ROOT=../media|PAPERLESS_MEDIA_ROOT=/opt/paperless/media|\" /opt/paperless/paperless.conf\nsed -i -e \"s|#PAPERLESS_STATICDIR=../static|PAPERLESS_STATICDIR=/opt/paperless/static|\" /opt/paperless/paperless.conf\necho \"${Paperlessngx}\" >/opt/${APPLICATION}_version.txt\nmsg_ok \"Installed Paperless-ngx\"\n\nmsg_info \"Installing Natural Language Toolkit (Patience)\"\n$STD python3 -m nltk.downloader -d /usr/share/nltk_data all\nmsg_ok \"Installed Natural Language Toolkit\"\n\nmsg_info \"Setting up PostgreSQL database\"\nDB_NAME=paperlessdb\nDB_USER=paperless\nDB_PASS=\"$(openssl rand -base64 18 | cut -c1-13)\"\nSECRET_KEY=\"$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32)\"\n$STD sudo -u postgres psql -c \"CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';\"\n$STD sudo -u postgres psql -c \"CREATE DATABASE $DB_NAME WITH OWNER $DB_USER ENCODING 'UTF8' TEMPLATE template0;\"\n$STD sudo -u postgres psql -c \"ALTER ROLE $DB_USER SET client_encoding TO 'utf8';\"\n$STD sudo -u postgres psql -c \"ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';\"\n$STD sudo -u postgres psql -c \"ALTER ROLE $DB_USER SET timezone TO 'UTC'\"\necho \"\" >>~/paperless.creds\necho -e \"Paperless-ngx Database User: \\e[32m$DB_USER\\e[0m\" >>~/paperless.creds\necho -e \"Paperless-ngx Database Password: \\e[32m$DB_PASS\\e[0m\" >>~/paperless.creds\necho -e \"Paperless-ngx Database Name: \\e[32m$DB_NAME\\e[0m\" >>~/paperless.creds\nsed -i -e 's|#PAPERLESS_DBHOST=localhost|PAPERLESS_DBHOST=localhost|' /opt/paperless/paperless.conf\nsed -i -e 's|#PAPERLESS_DBPORT=5432|PAPERLESS_DBPORT=5432|' /opt/paperless/paperless.conf\nsed -i -e \"s|#PAPERLESS_DBNAME=paperless|PAPERLESS_DBNAME=$DB_NAME|\" /opt/paperless/paperless.conf\nsed -i -e \"s|#PAPERLESS_DBUSER=paperless|PAPERLESS_DBUSER=$DB_USER|\" /opt/paperless/paperless.conf\nsed -i -e \"s|#PAPERLESS_DBPASS=paperless|PAPERLESS_DBPASS=$DB_PASS|\" /opt/paperless/paperless.conf\nsed -i -e \"s|#PAPERLESS_SECRET_KEY=change-me|PAPERLESS_SECRET_KEY=$SECRET_KEY|\" /opt/paperless/paperless.conf\ncd /opt/paperless/src\n$STD python3 manage.py migrate\nmsg_ok \"Set up PostgreSQL database\"\n\nread -r -p \"Would you like to add Adminer? <y/N> \" prompt\nif [[ \"${prompt,,}\" =~ ^(y|yes)$ ]]; then\n  msg_info \"Installing Adminer\"\n  $STD apt install -y adminer\n  $STD a2enconf adminer\n  systemctl reload apache2\n  IP=$(hostname -I | awk '{print $1}')\n  echo \"\" >>~/paperless.creds\n  echo -e \"Adminer Interface: \\e[32m$IP/adminer/\\e[0m\" >>~/paperless.creds\n  echo -e \"Adminer System: \\e[32mPostgreSQL\\e[0m\" >>~/paperless.creds\n  echo -e \"Adminer Server: \\e[32mlocalhost:5432\\e[0m\" >>~/paperless.creds\n  echo -e \"Adminer Username: \\e[32m$DB_USER\\e[0m\" >>~/paperless.creds\n  echo -e \"Adminer Password: \\e[32m$DB_PASS\\e[0m\" >>~/paperless.creds\n  echo -e \"Adminer Database: \\e[32m$DB_NAME\\e[0m\" >>~/paperless.creds\n  msg_ok \"Installed Adminer\"\nfi\n\nmsg_info \"Setting up admin Paperless-ngx User & Password\"\n## From https://github.com/linuxserver/docker-paperless-ngx/blob/main/root/etc/cont-init.d/99-migrations\ncat <<EOF | python3 /opt/paperless/src/manage.py shell\nfrom django.contrib.auth import get_user_model\nUserModel = get_user_model()\nuser = UserModel.objects.create_user('admin', password='$DB_PASS')\nuser.is_superuser = True\nuser.is_staff = True\nuser.save()\nEOF\necho \"\" >>~/paperless.creds\necho -e \"Paperless-ngx WebUI User: \\e[32madmin\\e[0m\" >>~/paperless.creds\necho -e \"Paperless-ngx WebUI Password: \\e[32m$DB_PASS\\e[0m\" >>~/paperless.creds\necho \"\" >>~/paperless.creds\nmsg_ok \"Set up admin Paperless-ngx User & Password\"\n\nmsg_info \"Creating Services\"\ncat <<EOF >/etc/systemd/system/paperless-scheduler.service\n[Unit]\nDescription=Paperless Celery beat\nRequires=redis.service\n\n[Service]\nWorkingDirectory=/opt/paperless/src\nExecStart=celery --app paperless beat --loglevel INFO\n\n[Install]\nWantedBy=multi-user.target\nEOF\n\ncat <<EOF >/etc/systemd/system/paperless-task-queue.service\n[Unit]\nDescription=Paperless Celery Workers\nRequires=redis.service\nAfter=postgresql.service\n\n[Service]\nWorkingDirectory=/opt/paperless/src\nExecStart=celery --app paperless worker --loglevel INFO\n\n[Install]\nWantedBy=multi-user.target\nEOF\n\ncat <<EOF >/etc/systemd/system/paperless-consumer.service\n[Unit]\nDescription=Paperless consumer\nRequires=redis.service\n\n[Service]\nWorkingDirectory=/opt/paperless/src\nExecStart=python3 manage.py document_consumer\n\n[Install]\nWantedBy=multi-user.target\nEOF\n\ncat <<EOF >/etc/systemd/system/paperless-webserver.service\n[Unit]\nDescription=Paperless webserver\nAfter=network.target\nWants=network.target\nRequires=redis.service\n\n[Service]\nWorkingDirectory=/opt/paperless/src\nExecStart=/usr/local/bin/gunicorn -c /opt/paperless/gunicorn.conf.py paperless.asgi:application\n\n[Install]\nWantedBy=multi-user.target\nEOF\n\nsed -i -e 's/rights=\"none\" pattern=\"PDF\"/rights=\"read|write\" pattern=\"PDF\"/' /etc/ImageMagick-6/policy.xml\n\nsystemctl daemon-reload\n$STD systemctl enable --now paperless-consumer paperless-webserver paperless-scheduler paperless-task-queue.service\nmsg_ok \"Created Services\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\nrm -rf /opt/paperless/docker\nrm -rf /tmp/ghostscript*\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/pbs-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Proxmox Backup Server\"\nwget -q https://enterprise.proxmox.com/debian/proxmox-release-bookworm.gpg -O /etc/apt/trusted.gpg.d/proxmox-release-bookworm.gpg\ncat <<EOF >>/etc/apt/sources.list\ndeb http://download.proxmox.com/debian/pbs bookworm pbs-no-subscription\nEOF\n$STD apt-get update\n$STD apt-get install -y proxmox-backup-server\nmsg_ok \"Installed Proxmox Backup Server\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/peanut-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# Co-Author: remz1337\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y gpg\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Node.js\"\nmkdir -p /etc/apt/keyrings\ncurl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg\necho \"deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main\" >/etc/apt/sources.list.d/nodesource.list\n$STD apt-get update\n$STD apt-get install -y nodejs\nmsg_ok \"Installed Node.js\"\n\nmsg_info \"Installing NUT\"\n$STD apt-get install -y nut-client\nmsg_ok \"Installed NUT\"\n\nmsg_info \"Installing Peanut\"\nRELEASE=$(curl -sL https://api.github.com/repos/Brandawg93/PeaNUT/releases/latest | grep '\"tag_name\":' | cut -d'\"' -f4)\nwget -qO peanut.tar.gz https://api.github.com/repos/Brandawg93/PeaNUT/tarball/${RELEASE}\nmkdir -p /opt/peanut\ntar -xzf peanut.tar.gz -C /opt/peanut --strip-components 1\nrm peanut.tar.gz\ncd /opt/peanut\n$STD npm install -g pnpm\n$STD pnpm i\n$STD pnpm run build\ncp -r .next/static .next/standalone/.next/\nmkdir -p /opt/peanut/.next/standalone/config\nmkdir -p /etc/peanut/\ncat <<EOF >/etc/peanut/settings.yml\nWEB_HOST: 0.0.0.0\nWEB_PORT: 3000\nNUT_HOST: 0.0.0.0\nNUT_PORT: 3493\nEOF\nln -sf /etc/peanut/settings.yml /opt/peanut/.next/standalone/config/settings.yml\nmsg_ok \"Installed Peanut\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/peanut.service\n[Unit]\nDescription=Peanut\nAfter=network.target\n[Service]\nSyslogIdentifier=peanut\nRestart=always\nRestartSec=5\nType=simple\nEnvironment=\"NODE_ENV=production\"\n#Environment=\"NUT_HOST=localhost\"\n#Environment=\"NUT_PORT=3493\"\n#Environment=\"WEB_HOST=0.0.0.0\"\n#Environment=\"WEB_PORT=3000\"\nWorkingDirectory=/opt/peanut\nExecStart=node /opt/peanut/.next/standalone/server.js\nTimeoutStopSec=30\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now peanut.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/petio-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y gnupg\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing MongoDB 4.4\"\nwget -qO- https://www.mongodb.org/static/pgp/server-4.4.asc | gpg --dearmor >/usr/share/keyrings/mongodb-server-4.4.gpg\n# Determine OS ID\nOS_ID=$(grep '^ID=' /etc/os-release | cut -d'=' -f2)\n\nif [ \"$OS_ID\" = \"debian\" ]; then\necho \"deb [ signed-by=/usr/share/keyrings/mongodb-server-4.4.gpg ] http://repo.mongodb.org/apt/debian $(grep '^VERSION_CODENAME=' /etc/os-release | cut -d'=' -f2)/mongodb-org/4.4 main\" > /etc/apt/sources.list.d/mongodb-org-4.4.list\nelse\necho \"deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-4.4.gpg ] https://repo.mongodb.org/apt/ubuntu $(grep '^VERSION_CODENAME=' /etc/os-release | cut -d'=' -f2)/mongodb-org/4.4 multiverse\" > /etc/apt/sources.list.d/mongodb-org-4.4.list\nfi\n\n$STD apt-get update\n$STD apt-get install -y mongodb-org\nsed -i 's/bindIp: 127.0.0.1/bindIp: 0.0.0.0/' /etc/mongod.conf\nsystemctl enable -q --now mongod.service\nmsg_ok \"MongoDB 4.4 Installed\"\n\n\nmsg_info \"Installing Petio\"\nuseradd -M --shell=/bin/false petio\nmkdir /opt/Petio\nwget -q https://petio.tv/releases/latest -O petio-latest.zip\n$STD unzip -q petio-latest.zip -d /opt/Petio\nrm -rf petio-latest.zip\nchown -R petio:petio /opt/Petio\nmsg_ok \"Installed Petio\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/petio.service\n[Unit]\nDescription=Petio a content request system\nAfter=network.target mongod.service\n\n[Service]\nType=simple\nUser=petio\nRestart=on-failure\nRestartSec=1\nExecStart=/opt/Petio/bin/petio-linux\n\n[Install]\nWantedBy=multi-user.target\n\n\nEOF\nsystemctl enable -q --now petio.service\nmsg_ok \"Created Service\"\n\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/photoprism-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies (Patience)\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y exiftool\n$STD apt-get install -y ffmpeg\n$STD apt-get install -y libheif1\n$STD apt-get install -y libpng-dev\n$STD apt-get install -y libjpeg-dev\n$STD apt-get install -y libtiff-dev\n$STD apt-get install -y imagemagick\n$STD apt-get install -y darktable\n$STD apt-get install -y rawtherapee\n$STD apt-get install -y libvips42\n\necho 'export PATH=/usr/local:$PATH' >>~/.bashrc\nexport PATH=/usr/local:$PATH\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing PhotoPrism (Patience)\"\nmkdir -p /opt/photoprism/{cache,config,photos/originals,photos/import,storage,temp}\nwget -q -cO - https://dl.photoprism.app/pkg/linux/amd64.tar.gz | tar -xz -C /opt/photoprism --strip-components=1\nif [[ ${PCT_OSTYPE} == \"ubuntu\" ]]; then \n  wget -q -cO - https://dl.photoprism.app/dist/libheif/libheif-jammy-amd64-v1.17.1.tar.gz | tar -xzf - -C /usr/local --strip-components=1\nelse\n  wget -q -cO - https://dl.photoprism.app/dist/libheif/libheif-bookworm-amd64-v1.17.1.tar.gz | tar -xzf - -C /usr/local --strip-components=1\nfi\nldconfig\ncat <<EOF >/opt/photoprism/config/.env\nPHOTOPRISM_AUTH_MODE='password'\nPHOTOPRISM_ADMIN_PASSWORD='helper-scripts.com'\nPHOTOPRISM_HTTP_HOST='0.0.0.0'\nPHOTOPRISM_HTTP_PORT='2342'\nPHOTOPRISM_SITE_CAPTION='https://tteck.github.io/Proxmox/'\nPHOTOPRISM_STORAGE_PATH='/opt/photoprism/storage'\nPHOTOPRISM_ORIGINALS_PATH='/opt/photoprism/photos/originals'\nPHOTOPRISM_IMPORT_PATH='/opt/photoprism/photos/import'\nEOF\nln -sf /opt/photoprism/bin/photoprism /usr/local/bin/photoprism\nmsg_ok \"Installed PhotoPrism\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/photoprism.service\n[Unit]\nDescription=PhotoPrism service\nAfter=network.target\n\n[Service]\nType=forking\nUser=root\nWorkingDirectory=/opt/photoprism\nEnvironmentFile=/opt/photoprism/config/.env\nExecStart=/opt/photoprism/bin/photoprism up -d\nExecStop=/opt/photoprism/bin/photoprism down\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now photoprism\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/pialert-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get -y install \\\n  sudo \\\n  mc \\\n  curl \\\n  apt-utils \\\n  avahi-utils \\\n  lighttpd \\\n  sqlite3 \\\n  mmdb-bin \\\n  arp-scan \\\n  dnsutils \\\n  net-tools \\\n  nbtscan \\\n  libwww-perl \\\n  nmap \\\n  zip \\\n  aria2 \\\n  wakeonlan\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing PHP Dependencies\"\n$STD apt-get -y install \\\n  php \\\n  php-cgi \\\n  php-fpm \\\n  php-curl \\\n  php-xml \\\n  php-sqlite3\n$STD lighttpd-enable-mod fastcgi-php\nservice lighttpd force-reload\nmsg_ok \"Installed PHP Dependencies\"\n\nmsg_info \"Installing Python Dependencies\"\n$STD apt-get -y install \\\n  python3-pip \\\n  python3-requests \\\n  python3-tz \\\n  python3-tzlocal\nrm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED\n$STD pip3 install mac-vendor-lookup\n$STD pip3 install fritzconnection\n$STD pip3 install cryptography\n$STD pip3 install pyunifi\nmsg_ok \"Installed Python Dependencies\"\n\nmsg_info \"Installing Pi.Alert\"\ncurl -sL https://github.com/leiweibau/Pi.Alert/raw/main/tar/pialert_latest.tar | tar xvf - -C /opt >/dev/null 2>&1\nrm -rf /var/lib/ieee-data /var/www/html/index.html\nsed -i -e 's#^sudo cp -n /usr/share/ieee-data/.* /var/lib/ieee-data/#\\# &#' -e '/^sudo mkdir -p 2_backup$/s/^/# /' -e '/^sudo cp \\*.txt 2_backup$/s/^/# /' -e '/^sudo cp \\*.csv 2_backup$/s/^/# /' /opt/pialert/back/update_vendors.sh\nmv /var/www/html/index.lighttpd.html /var/www/html/index.lighttpd.html.old\nln -s /usr/share/ieee-data/ /var/lib/\nln -s /opt/pialert/install/index.html /var/www/html/index.html\nln -s /opt/pialert/front /var/www/html/pialert\nchmod go+x /opt/pialert /opt/pialert/back/shoutrrr/x86/shoutrrr\nchgrp -R www-data /opt/pialert/db /opt/pialert/front/reports /opt/pialert/config /opt/pialert/config/pialert.conf\nchmod -R 775 /opt/pialert/db /opt/pialert/db/temp /opt/pialert/config /opt/pialert/front/reports\ntouch /opt/pialert/log/pialert.vendors.log /opt/pialert/log/pialert.IP.log /opt/pialert/log/pialert.1.log /opt/pialert/log/pialert.cleanup.log /opt/pialert/log/pialert.webservices.log\nsrc_dir=\"/opt/pialert/log\"\ndest_dir=\"/opt/pialert/front/php/server\"\nfor file in pialert.vendors.log pialert.IP.log pialert.1.log pialert.cleanup.log pialert.webservices.log; do\n    ln -s \"$src_dir/$file\" \"$dest_dir/$file\"\ndone\nsed -i 's#PIALERT_PATH\\s*=\\s*'\\''/home/pi/pialert'\\''#PIALERT_PATH           = '\\''/opt/pialert'\\''#' /opt/pialert/config/pialert.conf\nsed -i 's/$HOME/\\/opt/g' /opt/pialert/install/pialert.cron\ncrontab /opt/pialert/install/pialert.cron\necho \"bash -c \\\"\\$(wget -qLO - https://github.com/leiweibau/Pi.Alert/raw/main/install/pialert_update.sh)\\\" -s --lxc\" >/usr/bin/update\nchmod +x /usr/bin/update\necho \"python3 /opt/pialert/back/pialert.py 1\" >/usr/bin/scan\nchmod +x /usr/bin/scan\necho \"/opt/pialert/back/pialert-cli set_permissions --lxc\" >/usr/bin/permissions\nchmod +x /usr/bin/permissions\necho \"/opt/pialert/back/pialert-cli set_sudoers --lxc\" >/usr/bin/sudoers\nchmod +x /usr/bin/sudoers\nmsg_ok \"Installed Pi.Alert\"\n\nmsg_info \"Start Pi.Alert Scan (Patience)\"\n$STD python3 /opt/pialert/back/pialert.py update_vendors\n$STD python3 /opt/pialert/back/pialert.py internet_IP\n$STD python3 /opt/pialert/back/pialert.py 1\nmsg_ok \"Finished Pi.Alert Scan\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/pihole-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y ufw\n$STD apt-get install -y ntp\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Pi-hole\"\nmkdir -p /etc/pihole/\ncat <<EOF >/etc/pihole/setupVars.conf\nPIHOLE_INTERFACE=eth0\nPIHOLE_DNS_1=8.8.8.8\nPIHOLE_DNS_2=8.8.4.4\nQUERY_LOGGING=true\nINSTALL_WEB_SERVER=true\nINSTALL_WEB_INTERFACE=true\nLIGHTTPD_ENABLED=true\nCACHE_SIZE=10000\nDNS_FQDN_REQUIRED=true\nDNS_BOGUS_PRIV=true\nDNSMASQ_LISTENING=local\nWEBPASSWORD=$(openssl rand -base64 48)\nBLOCKING_ENABLED=true\nEOF\n# View script https://install.pi-hole.net\n$STD bash <(curl -fsSL https://install.pi-hole.net) --unattended\nmsg_ok \"Installed Pi-hole\"\n\nread -r -p \"Would you like to add Unbound? <y/N> \" prompt\nif [[ ${prompt,,} =~ ^(y|yes)$ ]]; then\n  msg_info \"Installing Unbound\"\n  $STD apt-get install -y unbound\n  cat <<EOF >/etc/unbound/unbound.conf.d/pi-hole.conf\nserver:\n  verbosity: 0\n  interface: 127.0.0.1\n  port: 5335\n  do-ip6: no\n  do-ip4: yes\n  do-udp: yes\n  do-tcp: yes\n  num-threads: 1\n  hide-identity: yes\n  hide-version: yes\n  harden-glue: yes\n  harden-dnssec-stripped: yes\n  harden-referral-path: yes\n  use-caps-for-id: no\n  harden-algo-downgrade: no\n  qname-minimisation: yes\n  aggressive-nsec: yes\n  rrset-roundrobin: yes\n  cache-min-ttl: 300\n  cache-max-ttl: 14400\n  msg-cache-slabs: 8\n  rrset-cache-slabs: 8\n  infra-cache-slabs: 8\n  key-cache-slabs: 8\n  serve-expired: yes\n  root-hints: /var/lib/unbound/root.hints\n  serve-expired-ttl: 3600\n  edns-buffer-size: 1232\n  prefetch: yes\n  prefetch-key: yes\n  target-fetch-policy: \"3 2 1 1 1\"\n  unwanted-reply-threshold: 10000000\n  rrset-cache-size: 256m\n  msg-cache-size: 128m\n  so-rcvbuf: 1m\n  private-address: 192.168.0.0/16\n  private-address: 169.254.0.0/16\n  private-address: 172.16.0.0/12\n  private-address: 10.0.0.0/8\n  private-address: fd00::/8\n  private-address: fe80::/10\nEOF\n  mkdir -p /etc/dnsmasq.d/\n  cat <<EOF >/etc/dnsmasq.d/99-edns.conf\nedns-packet-max=1232\nEOF\n  wget -qO /var/lib/unbound/root.hints https://www.internic.net/domain/named.root\n  sed -i -e 's/PIHOLE_DNS_1=8.8.8.8/PIHOLE_DNS_1=127.0.0.1#5335/' -e 's/PIHOLE_DNS_2=8.8.4.4/#PIHOLE_DNS_2=8.8.4.4/' /etc/pihole/setupVars.conf\n  systemctl enable -q --now unbound\n  systemctl restart pihole-FTL.service\n  msg_ok \"Installed Unbound\"\nfi\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/pingvin-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y git\n$STD apt-get install -y gnupg\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Setting up Node.js Repository\"\nmkdir -p /etc/apt/keyrings\ncurl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg\necho \"deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main\" >/etc/apt/sources.list.d/nodesource.list\nmsg_ok \"Set up Node.js Repository\"\n\nmsg_info \"Installing Node.js\"\n$STD apt-get update\n$STD apt-get install -y nodejs\n$STD npm install pm2 -g\nmsg_ok \"Installed Node.js\"\n\nmsg_info \"Installing Pingvin Share (Patience)\"\ngit clone -q https://github.com/stonith404/pingvin-share /opt/pingvin-share\ncd /opt/pingvin-share\n$STD git fetch --tags\n$STD git checkout $(git describe --tags `git rev-list --tags --max-count=1`)\ncd backend\n$STD npm install\n$STD npm run build\n$STD pm2 start --name=\"pingvin-share-backend\" npm -- run prod\ncd ../frontend\nsed -i '/\"admin.config.smtp.allow-unauthorized-certificates\":\\|admin.config.smtp.allow-unauthorized-certificates.description\":/,+1d' ./src/i18n/translations/fr-FR.ts\n$STD npm install\n$STD npm run build\n$STD pm2 start --name=\"pingvin-share-frontend\" npm -- run start\n# create and enable pm2-root systemd script\n$STD pm2 startup systemd \n# save running pm2 processes so pingvin-share can survive reboots\n$STD pm2 save\nmsg_ok \"Installed Pingvin Share\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/plex-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y gpg\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Setting Up Hardware Acceleration\"\n$STD apt-get -y install {va-driver-all,ocl-icd-libopencl1,intel-opencl-icd,vainfo,intel-gpu-tools}\nif [[ \"$CTTYPE\" == \"0\" ]]; then\n  chgrp video /dev/dri\n  chmod 755 /dev/dri\n  chmod 660 /dev/dri/*\n  $STD adduser $(id -u -n) video\n  $STD adduser $(id -u -n) render\nfi\nmsg_ok \"Set Up Hardware Acceleration\"\n\nmsg_info \"Setting Up Plex Media Server Repository\"\nwget -qO- https://downloads.plex.tv/plex-keys/PlexSign.key >/usr/share/keyrings/PlexSign.asc\necho \"deb [signed-by=/usr/share/keyrings/PlexSign.asc] https://downloads.plex.tv/repo/deb/ public main\" >/etc/apt/sources.list.d/plexmediaserver.list\nmsg_ok \"Set Up Plex Media Server Repository\"\n\nmsg_info \"Installing Plex Media Server\"\n$STD apt-get update\n$STD apt-get -o Dpkg::Options::=\"--force-confold\" install -y plexmediaserver\nif [[ \"$CTTYPE\" == \"0\" ]]; then\n  sed -i -e 's/^ssl-cert:x:104:plex$/render:x:104:root,plex/' -e 's/^render:x:108:root$/ssl-cert:x:108:plex/' /etc/group\nelse\n  sed -i -e 's/^ssl-cert:x:104:plex$/render:x:104:plex/' -e 's/^render:x:108:$/ssl-cert:x:108:/' /etc/group\nfi\nmsg_ok \"Installed Plex Media Server\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/pocketbase-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Pocketbase\"\nRELEASE=$(curl -s https://api.github.com/repos/pocketbase/pocketbase/releases/latest | grep \"tag_name\" | awk '{print substr($2, 3, length($2)-4) }')\nwget -q https://github.com/pocketbase/pocketbase/releases/download/v${RELEASE}/pocketbase_${RELEASE}_linux_amd64.zip -O /tmp/pocketbase.zip\nmkdir -p /opt/pocketbase/{pb_public,pb_migrations,pb_hooks}\nunzip -q -o /tmp/pocketbase.zip -d /opt/pocketbase\n\ncat <<EOF >/etc/systemd/system/pocketbase.service\n[Unit]\nDescription = pocketbase\n\n[Service]\nType           = simple\nLimitNOFILE    = 4096\nRestart        = always\nRestartSec     = 5s\nStandardOutput = append:/opt/pocketbase/errors.log\nStandardError  = append:/opt/pocketbase/errors.log\nExecStart      = /opt/pocketbase/pocketbase serve --http=0.0.0.0:8080\n\n[Install]\nWantedBy = multi-user.target\nEOF\n\nsystemctl enable -q --now pocketbase.service\nmsg_ok \"Installed Pocketbase\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/podman-homeassistant-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Podman\"\n$STD apt-get -y install podman\n$STD systemctl enable --now podman.socket\nmsg_ok \"Installed Podman\"\n\nmsg_info \"Pulling Home Assistant Image\"\n$STD podman pull docker.io/homeassistant/home-assistant:stable\nmsg_ok \"Pulled Home Assistant Image\"\n\nmsg_info \"Installing Home Assistant\"\n$STD podman volume create hass_config\n$STD podman run -d \\\n  --name homeassistant \\\n  --restart unless-stopped \\\n  -v /dev:/dev \\\n  -v hass_config:/config \\\n  -v /etc/localtime:/etc/localtime:ro \\\n  -v /etc/timezone:/etc/timezone:ro \\\n  --net=host \\\n  homeassistant/home-assistant:stable\npodman generate systemd \\\n  --new --name homeassistant \\\n  >/etc/systemd/system/homeassistant.service\n$STD systemctl enable --now homeassistant\nmsg_ok \"Installed Home Assistant\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/podman-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Podman\"\n$STD apt-get -y install podman\n$STD systemctl enable --now podman.socket\necho -e 'unqualified-search-registries=[\"docker.io\"]' >> /etc/containers/registries.conf\nmsg_ok \"Installed Podman\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/postgresql-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y gnupg\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Setting up PostgreSQL Repository\"\nVERSION=\"$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)\"\necho \"deb http://apt.postgresql.org/pub/repos/apt ${VERSION}-pgdg main\" >/etc/apt/sources.list.d/pgdg.list\ncurl -sSL https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor --output /etc/apt/trusted.gpg.d/postgresql.gpg\nmsg_ok \"Setup PostgreSQL Repository\"\n\nmsg_info \"Installing PostgreSQL\"\n$STD apt-get update\n$STD apt-get install -y postgresql\n\ncat <<EOF >/etc/postgresql/17/main/pg_hba.conf\n# PostgreSQL Client Authentication Configuration File\nlocal   all             postgres                                peer\n# TYPE  DATABASE        USER            ADDRESS                 METHOD\n# \"local\" is for Unix domain socket connections only\nlocal   all             all                                     peer\n# IPv4 local connections:\nhost    all             all             127.0.0.1/32            scram-sha-256\nhost    all             all             0.0.0.0/24              md5\n# IPv6 local connections:\nhost    all             all             ::1/128                 scram-sha-256\nhost    all             all             0.0.0.0/0               md5\n# Allow replication connections from localhost, by a user with the\n# replication privilege.\nlocal   replication     all                                     peer\nhost    replication     all             127.0.0.1/32            scram-sha-256\nhost    replication     all             ::1/128                 scram-sha-256\nEOF\n\ncat <<EOF >/etc/postgresql/17/main/postgresql.conf\n# -----------------------------\n# PostgreSQL configuration file\n# -----------------------------\n\n#------------------------------------------------------------------------------\n# FILE LOCATIONS\n#------------------------------------------------------------------------------\n\ndata_directory = '/var/lib/postgresql/17/main'       \nhba_file = '/etc/postgresql/17/main/pg_hba.conf'     \nident_file = '/etc/postgresql/17/main/pg_ident.conf'   \nexternal_pid_file = '/var/run/postgresql/17-main.pid'                   \n\n#------------------------------------------------------------------------------\n# CONNECTIONS AND AUTHENTICATION\n#------------------------------------------------------------------------------\n\n# - Connection Settings -\n\nlisten_addresses = '*'                 \nport = 5432                             \nmax_connections = 100                  \nunix_socket_directories = '/var/run/postgresql' \n\n# - SSL -\n\nssl = on\nssl_cert_file = '/etc/ssl/certs/ssl-cert-snakeoil.pem'\nssl_key_file = '/etc/ssl/private/ssl-cert-snakeoil.key'\n\n#------------------------------------------------------------------------------\n# RESOURCE USAGE (except WAL)\n#------------------------------------------------------------------------------\n\nshared_buffers = 128MB                \ndynamic_shared_memory_type = posix      \n\n#------------------------------------------------------------------------------\n# WRITE-AHEAD LOG\n#------------------------------------------------------------------------------\n\nmax_wal_size = 1GB\nmin_wal_size = 80MB\n\n#------------------------------------------------------------------------------\n# REPORTING AND LOGGING\n#------------------------------------------------------------------------------\n\n# - What to Log -\n\nlog_line_prefix = '%m [%p] %q%u@%d '           \nlog_timezone = 'Etc/UTC'\n\n#------------------------------------------------------------------------------\n# PROCESS TITLE\n#------------------------------------------------------------------------------\n\ncluster_name = '17/main'                \n\n#------------------------------------------------------------------------------\n# CLIENT CONNECTION DEFAULTS\n#------------------------------------------------------------------------------\n\n# - Locale and Formatting -\n\ndatestyle = 'iso, mdy'\ntimezone = 'Etc/UTC'\nlc_messages = 'C'                      \nlc_monetary = 'C'                       \nlc_numeric = 'C'                        \nlc_time = 'C'                           \ndefault_text_search_config = 'pg_catalog.english'\n\n#------------------------------------------------------------------------------\n# CONFIG FILE INCLUDES\n#------------------------------------------------------------------------------\n\ninclude_dir = 'conf.d'                  \nEOF\n\nsudo systemctl restart postgresql\nmsg_ok \"Installed PostgreSQL\"\n\nread -r -p \"Would you like to add Adminer? <y/N> \" prompt\nif [[ \"${prompt,,}\" =~ ^(y|yes)$ ]]; then\n  msg_info \"Installing Adminer\"\n  $STD apt install -y adminer\n  $STD a2enconf adminer\n  systemctl reload apache2\n  msg_ok \"Installed Adminer\"\nfi\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/prometheus-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Prometheus\"\nRELEASE=$(curl -s https://api.github.com/repos/prometheus/prometheus/releases/latest | grep \"tag_name\" | awk '{print substr($2, 3, length($2)-4) }')\nmkdir -p /etc/prometheus\nmkdir -p /var/lib/prometheus\nwget -q https://github.com/prometheus/prometheus/releases/download/v${RELEASE}/prometheus-${RELEASE}.linux-amd64.tar.gz\ntar -xf prometheus-${RELEASE}.linux-amd64.tar.gz\ncd prometheus-${RELEASE}.linux-amd64\nmv prometheus promtool /usr/local/bin/\nmv consoles/ console_libraries/ /etc/prometheus/\nmv prometheus.yml /etc/prometheus/prometheus.yml\necho \"${RELEASE}\" >/opt/${APPLICATION}_version.txt\nmsg_ok \"Installed Prometheus\"\n\nmsg_info \"Creating Service\"\nservice_path=\"/etc/systemd/system/prometheus.service\"\necho \"[Unit]\nDescription=Prometheus\nWants=network-online.target\nAfter=network-online.target\n\n[Service]\nUser=root\nRestart=always\nType=simple\nExecStart=/usr/local/bin/prometheus \\\n    --config.file=/etc/prometheus/prometheus.yml \\\n    --storage.tsdb.path=/var/lib/prometheus/ \\\n    --web.console.templates=/etc/prometheus/consoles \\\n    --web.console.libraries=/etc/prometheus/console_libraries \\\n    --web.listen-address=0.0.0.0:9090\n\n[Install]\nWantedBy=multi-user.target\" >$service_path\nsystemctl enable -q --now prometheus\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nrm -rf ../prometheus-${RELEASE}.linux-amd64 ../prometheus-${RELEASE}.linux-amd64.tar.gz\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/prowlarr-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y sqlite3\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Prowlarr\"\nmkdir -p /var/lib/prowlarr/\nchmod 775 /var/lib/prowlarr/\n$STD wget --content-disposition 'https://prowlarr.servarr.com/v1/update/master/updatefile?os=linux&runtime=netcore&arch=x64'\n$STD tar -xvzf Prowlarr.master.*.tar.gz\nmv Prowlarr /opt\nchmod 775 /opt/Prowlarr\nmsg_ok \"Installed Prowlarr\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/prowlarr.service\n[Unit]\nDescription=Prowlarr Daemon\nAfter=syslog.target network.target\n[Service]\nUMask=0002\nType=simple\nExecStart=/opt/Prowlarr/Prowlarr -nobrowser -data=/var/lib/prowlarr/\nTimeoutStopSec=20\nKillMode=process\nRestart=on-failure\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl -q daemon-reload\nsystemctl enable --now -q prowlarr\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\nrm -rf Prowlarr.master.*.tar.gz\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/qbittorrent-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing qbittorrent-nox\"\n$STD apt-get install -y qbittorrent-nox\nmkdir -p /.config/qBittorrent/\ncat <<EOF >/.config/qBittorrent/qBittorrent.conf\n[Preferences]\nWebUI\\Password_PBKDF2=\"@ByteArray(amjeuVrF3xRbgzqWQmes5A==:XK3/Ra9jUmqUc4RwzCtrhrkQIcYczBl90DJw2rT8DFVTss4nxpoRhvyxhCf87ahVE3SzD8K9lyPdpyUCfmVsUg==)\"\nWebUI\\Port=8090\nWebUI\\UseUPnP=false\nWebUI\\Username=admin\nEOF\nmsg_ok \"qbittorrent-nox\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/qbittorrent-nox.service\n[Unit]\nDescription=qBittorrent client\nAfter=network.target\n[Service]\nExecStart=/usr/bin/qbittorrent-nox --webui-port=8090\nRestart=always\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now qbittorrent-nox\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/rabbitmq-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck\n# Co-Author: MickLesk (Canbiz)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n# Source: https://www.rabbitmq.com/\n\nsource /dev/stdin <<<\"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y \\\n  sudo \\\n  lsb-release \\\n  curl \\\n  gnupg   \\\n  apt-transport-https \\\n  make \\\n  mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Adding RabbitMQ signing key\"\nwget -qO- \"https://keys.openpgp.org/vks/v1/by-fingerprint/0A9AF2115F4687BD29803A206B73A36E6026DFCA\" | gpg --dearmor >/usr/share/keyrings/com.rabbitmq.team.gpg\nwget -qO- \"https://github.com/rabbitmq/signing-keys/releases/download/3.0/cloudsmith.rabbitmq-erlang.E495BB49CC4BBE5B.key\" | gpg --dearmor >/usr/share/keyrings/rabbitmq.E495BB49CC4BBE5B.gpg\nwget -qO- \"https://github.com/rabbitmq/signing-keys/releases/download/3.0/cloudsmith.rabbitmq-server.9F4587F226208342.key\" | gpg --dearmor >/usr/share/keyrings/rabbitmq.9F4587F226208342.gpg\nmsg_ok \"Signing keys added\"\n\nmsg_info \"Adding RabbitMQ repository\"\ncat <<EOF >/etc/apt/sources.list.d/rabbitmq.list\n## Provides modern Erlang/OTP releases from a Cloudsmith mirror\ndeb [signed-by=/usr/share/keyrings/rabbitmq.E495BB49CC4BBE5B.gpg] https://dl.cloudsmith.io/public/rabbitmq/rabbitmq-erlang/deb/debian $(lsb_release -cs) main\ndeb-src [signed-by=/usr/share/keyrings/rabbitmq.E495BB49CC4BBE5B.gpg] https://dl.cloudsmith.io/public/rabbitmq/rabbitmq-erlang/deb/debian $(lsb_release -cs) main\n\n## Provides RabbitMQ from a Cloudsmith mirror\ndeb [signed-by=/usr/share/keyrings/rabbitmq.9F4587F226208342.gpg] https://dl.cloudsmith.io/public/rabbitmq/rabbitmq-server/deb/debian $(lsb_release -cs) main\ndeb-src [signed-by=/usr/share/keyrings/rabbitmq.9F4587F226208342.gpg] https://dl.cloudsmith.io/public/rabbitmq/rabbitmq-server/deb/debian $(lsb_release -cs) main\nEOF\nmsg_ok \"RabbitMQ repository added\"\n\nmsg_info \"Updating package list\"\n$STD apt-get update -y\nmsg_ok \"Package list updated\"\n\nmsg_info \"Installing Erlang & RabbitMQ server\"\n$STD apt-get install -y erlang-base \\\n  erlang-asn1 erlang-crypto erlang-eldap erlang-ftp erlang-inets \\\n  erlang-mnesia erlang-os-mon erlang-parsetools erlang-public-key \\\n  erlang-runtime-tools erlang-snmp erlang-ssl \\\n  erlang-syntax-tools erlang-tftp erlang-tools erlang-xmerl \\\n  rabbitmq-server\nmsg_ok \"RabbitMQ server installed\"\n\nmsg_info \"Starting RabbitMQ service\"\nsystemctl enable -q --now rabbitmq-server\nmsg_ok \"RabbitMQ service started\"\n\nmsg_info \"Enabling RabbitMQ management plugin\"\n$STD rabbitmq-plugins enable rabbitmq_management\n$STD rabbitmqctl enable_feature_flag all\nmsg_ok \"RabbitMQ management plugin enabled\"\n\nmsg_info \"Create User\"\n$STD rabbitmqctl add_user proxmox proxmox\n$STD rabbitmqctl set_user_tags proxmox administrator\n$STD rabbitmqctl set_permissions -p / proxmox \".*\" \".*\" \".*\"\nmsg_ok \"Created User\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/radarr-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y sqlite3\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Radarr\"\nmkdir -p /var/lib/radarr/\nchmod 775 /var/lib/radarr/\n$STD wget --content-disposition 'https://radarr.servarr.com/v1/update/master/updatefile?os=linux&runtime=netcore&arch=x64'\n$STD tar -xvzf Radarr.master.*.tar.gz\nmv Radarr /opt\nchmod 775 /opt/Radarr\nmsg_ok \"Installed Radarr\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/radarr.service\n[Unit]\nDescription=Radarr Daemon\nAfter=syslog.target network.target\n[Service]\nUMask=0002\nType=simple\nExecStart=/opt/Radarr/Radarr -nobrowser -data=/var/lib/radarr/\nTimeoutStopSec=20\nKillMode=process\nRestart=on-failure\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl -q daemon-reload\nsystemctl enable --now -q radarr\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\nrm -rf Radarr.master.*.tar.gz\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/rdtclient-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y unzip\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing ASP.NET Core Runtime\"\nwget -q https://packages.microsoft.com/config/debian/12/packages-microsoft-prod.deb\n$STD dpkg -i packages-microsoft-prod.deb\nrm packages-microsoft-prod.deb\n$STD apt-get update\n$STD apt-get install -y dotnet-sdk-8.0\nmsg_ok \"Installed ASP.NET Core Runtime\"\n\nmsg_info \"Installing rdtclient\"\nwget -q https://github.com/rogerfar/rdt-client/releases/latest/download/RealDebridClient.zip\nunzip -qq RealDebridClient.zip -d /opt/rdtc\nrm RealDebridClient.zip\ncd /opt/rdtc\nmkdir -p data/{db,downloads}\nsed -i 's#/data/db/#/opt/rdtc&#g' /opt/rdtc/appsettings.json\nmsg_ok \"Installed rdtclient\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/rdtc.service\n[Unit]\nDescription=RdtClient Service\n\n[Service]\nWorkingDirectory=/opt/rdtc\nExecStart=/usr/bin/dotnet RdtClient.Web.dll\nSyslogIdentifier=RdtClient\nUser=root\n\n[Install]\nWantedBy=multi-user.target\nEOF\n$STD systemctl enable -q --now rdtc\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/readarr-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y sqlite3\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Readarr\"\nmkdir -p /var/lib/readarr/\nchmod 775 /var/lib/readarr/\n$STD wget --content-disposition 'https://readarr.servarr.com/v1/update/develop/updatefile?os=linux&runtime=netcore&arch=x64'\n$STD tar -xvzf Readarr.develop.*.tar.gz\nmv Readarr /opt\nchmod 775 /opt/Readarr\nmsg_ok \"Installed Readarr\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/readarr.service\n[Unit]\nDescription=Readarr Daemon\nAfter=syslog.target network.target\n[Service]\nUMask=0002\nType=simple\nExecStart=/opt/Readarr/Readarr -nobrowser -data=/var/lib/readarr/\nTimeoutStopSec=20\nKillMode=process\nRestart=on-failure\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl -q daemon-reload\nsystemctl enable --now -q readarr\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\nrm -rf Readarr.develop.*.tar.gz\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/readeck-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Readeck\"\nLATEST=$(curl -s https://codeberg.org/readeck/readeck/releases/ | grep -oP '(?<=Version )\\d+\\.\\d+\\.\\d+' | head -1)\nmkdir -p /opt/readeck\ncd /opt/readeck\nwget -q -O readeck https://codeberg.org/readeck/readeck/releases/download/${LATEST}/readeck-${LATEST}-linux-amd64\nchmod a+x readeck\nmsg_ok \"Installed Readeck\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/readeck.service\n[Unit]\nDescription=Readeck Service\nAfter=network.target\n\n[Service]\nEnvironment=READECK_SERVER_HOST=0.0.0.0\nEnvironment=READECK_SERVER_PORT=8000\nExecStart=/opt/readeck/./readeck serve\nWorkingDirectory=/opt/readeck\nRestart=always\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now readeck.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/redis-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y apt-transport-https\n$STD apt-get install -y gpg\n$STD apt-get install -y lsb-release\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Redis\"\nwget -qO- https://packages.redis.io/gpg | gpg --dearmor >/usr/share/keyrings/redis-archive-keyring.gpg\necho \"deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main\" >/etc/apt/sources.list.d/redis.list\n$STD apt-get update\n$STD apt-get install -y redis\nsed -i 's/^bind .*/bind 0.0.0.0/' /etc/redis/redis.conf\nsystemctl enable -q --now redis-server.service\nmsg_ok \"Installed Redis\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/rtsptoweb-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y git\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Golang\"\n$STD wget https://golang.org/dl/go1.20.1.linux-amd64.tar.gz\n$STD tar -xzf go1.20.1.linux-amd64.tar.gz -C /usr/local\n$STD ln -s /usr/local/go/bin/go /usr/local/bin/go\nrm -rf go1.20.1.linux-amd64.tar.gz\nmsg_ok \"Installed Golang\"\n\nmsg_info \"Installing RTSPtoWeb\"\n$STD git clone https://github.com/deepch/RTSPtoWeb /opt/rtsptoweb\ncat <<EOF >>/opt/rtsptoweb/start\n#!/bin/bash\ncd /opt/rtsptoweb && GO111MODULE=on go run *.go\nEOF\nchmod +x /opt/rtsptoweb/start\nmsg_ok \"Installed RTSPtoWeb\"\n\nmsg_info \"Creating Service\"\nservice_path=\"/etc/systemd/system/rtsptoweb.service\"\necho \"[Unit]\nDescription=RTSP to Web Streaming Service\nAfter=network.target\n\n[Service]\nType=simple\nUser=root\nExecStart=/opt/rtsptoweb/start\n\n[Install]\nWantedBy=multi-user.target\" >$service_path\nsystemctl enable -q --now rtsptoweb\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/runtipi-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Runtipi (Patience)\"\nDOCKER_CONFIG_PATH='/etc/docker/daemon.json'\nmkdir -p \"$(dirname \"$DOCKER_CONFIG_PATH\")\"\necho -e '{\\n  \"log-driver\": \"journald\"\\n}' > \"$DOCKER_CONFIG_PATH\"\ncd /opt\nwget -q https://raw.githubusercontent.com/runtipi/runtipi/master/scripts/install.sh\nchmod +x install.sh\n$STD ./install.sh\nchmod 666 /opt/runtipi/state/settings.json\nmsg_ok \"Installed Runtipi\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\nrm /opt/install.sh\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/sabnzbd-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y par2\n$STD apt-get install -y p7zip-full\ncat <<EOF >/etc/apt/sources.list.d/non-free.list\ndeb http://deb.debian.org/debian bookworm main contrib non-free non-free-firmware\nEOF\n$STD apt-get update\n$STD apt-get install -y unrar\nrm /etc/apt/sources.list.d/non-free.list\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Updating Python3\"\n$STD apt-get install -y \\\n  python3-dev \\\n  python3-pip\n$STD apt-get install -y python3-setuptools\nrm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED\nmsg_ok \"Updated Python3\"\n\nmsg_info \"Installing SABnzbd\"\nRELEASE=$(curl -s https://api.github.com/repos/sabnzbd/sabnzbd/releases/latest | grep \"tag_name\" | awk '{print substr($2, 2, length($2)-3) }')\n$STD tar zxvf <(curl -fsSL https://github.com/sabnzbd/sabnzbd/releases/download/$RELEASE/SABnzbd-${RELEASE}-src.tar.gz)\nmv SABnzbd-${RELEASE} /opt/sabnzbd\ncd /opt/sabnzbd\n$STD python3 -m pip install -r requirements.txt\necho \"${RELEASE}\" >/opt/${APPLICATION}_version.txt\nmsg_ok \"Installed SABnzbd\"\n\nmsg_info \"Creating Service\"\nservice_path=\"/etc/systemd/system/sabnzbd.service\"\necho \"[Unit]\nDescription=SABnzbd\nAfter=network.target\n[Service]\nWorkingDirectory=/opt/sabnzbd\nExecStart=python3 SABnzbd.py -s 0.0.0.0:7777\nRestart=always\nUser=root\n[Install]\nWantedBy=multi-user.target\" >$service_path\nsystemctl enable --now -q sabnzbd.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/scrypted-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies (Patience)\"\n$STD apt-get -y install software-properties-common apt-utils\n$STD apt-get -y update\n$STD apt-get -y upgrade\n$STD apt-get install -y avahi-daemon\n$STD apt-get -y install \\\n    build-essential \\\n    gcc \\\n    gir1.2-gtk-3.0 \\\n    libcairo2-dev \\\n    libgirepository1.0-dev \\\n    libglib2.0-dev \\\n    libjpeg-dev \\\n    libgif-dev \\\n    libopenjp2-7 \\\n    libpango1.0-dev \\\n    librsvg2-dev \\\n    pkg-config \\\n    curl \\\n    sudo \\\n    mc \\\n    ca-certificates \\\n    gpg\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Setting Up Hardware Acceleration\"\n$STD apt-get -y install {va-driver-all,ocl-icd-libopencl1,intel-opencl-icd,vainfo,intel-gpu-tools}\nif [[ \"$CTTYPE\" == \"0\" ]]; then\n  chgrp video /dev/dri\n  chmod 755 /dev/dri\n  chmod 660 /dev/dri/*\n  $STD adduser $(id -u -n) video\n  $STD adduser $(id -u -n) render\nfi\nmsg_ok \"Set Up Hardware Acceleration\"\n\nmsg_info \"Installing GStreamer (Patience)\"\n$STD apt-get -y install \\\n    gstreamer1.0-tools \\\n    libgstreamer1.0-dev \\\n    libgstreamer-plugins-base1.0-dev \\\n    libgstreamer-plugins-bad1.0-dev \\\n    gstreamer1.0-plugins-base \\\n    gstreamer1.0-plugins-good \\\n    gstreamer1.0-plugins-bad \\\n    gstreamer1.0-plugins-ugly \\\n    gstreamer1.0-libav \\\n    gstreamer1.0-alsa\nmsg_ok \"Installed GStreamer\"\n\nmsg_info \"Setting up Node.js Repository\"\nmkdir -p /etc/apt/keyrings\ncurl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg\necho \"deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main\" >/etc/apt/sources.list.d/nodesource.list\nmsg_ok \"Set up Node.js Repository\"\n\nmsg_info \"Installing Node.js\"\n$STD apt-get update\n$STD apt-get install -y nodejs\nmsg_ok \"Installed Node.js\"\n\nmsg_info \"Updating Python3\"\n$STD apt-get install -y \\\n  python3 \\\n  python3-dev \\\n  python3-pip\nrm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED\nmsg_ok \"Updated Python3\"\n\nmsg_info \"Installing Python3 Dependencies\"\n$STD apt-get -y install \\\n    python3-gi \\\n    python3-gst-1.0 \\\n    python3-matplotlib \\\n    python3-numpy \\\n    python3-opencv \\\n    python3-pil \\\n    python3-setuptools \\\n    python3-skimage \\\n    python3-wheel\n$STD python3 -m pip install --upgrade pip\n$STD python3 -m pip install aiofiles debugpy typing_extensions typing\nmsg_ok \"Installed Python3 Dependencies\"\n\nmsg_info \"Installing Scrypted\"\n$STD npx -y scrypted@latest install-server\n\nif [[ \"$CTTYPE\" == \"0\" ]]; then\n  sed -i -e 's/^sgx:x:104:$/render:x:104:root/' -e 's/^render:x:106:root$/sgx:x:106:/' /etc/group\nelse\n  sed -i -e 's/^sgx:x:104:$/render:x:104:/' -e 's/^render:x:106:$/sgx:x:106:/' /etc/group\nfi\nmsg_ok \"Installed Scrypted\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/scrypted.service\n[Unit]\nDescription=Scrypted service\nAfter=network.target\n\n[Service]\nUser=root\nGroup=root\nType=simple\nExecStart=/usr/bin/npx -y scrypted serve\nRestart=on-failure\nRestartSec=3\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now scrypted.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/sftpgo-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y gpg\n$STD apt-get install -y sqlite3\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Golang\"\nset +o pipefail\nRELEASE=$(curl -s https://go.dev/dl/ | grep -o \"go.*\\linux-amd64.tar.gz\" | head -n 1)\nwget -q https://golang.org/dl/$RELEASE\ntar -xzf $RELEASE -C /usr/local\n$STD ln -s /usr/local/go/bin/go /usr/local/bin/go\nset -o pipefail\nmsg_ok \"Installed Golang\"\n\nmsg_info \"Installing SFTPGo\"\ncurl -sS https://ftp.osuosl.org/pub/sftpgo/apt/gpg.key | gpg --dearmor -o /usr/share/keyrings/sftpgo-archive-keyring.gpg\necho \"deb [signed-by=/usr/share/keyrings/sftpgo-archive-keyring.gpg] https://ftp.osuosl.org/pub/sftpgo/apt bookworm main\" >/etc/apt/sources.list.d/sftpgo.list\n$STD apt-get update\n$STD apt-get install -y sftpgo\nmsg_ok \"Installed SFTPGo\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\nrm -rf $RELEASE\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/shinobi-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl sudo git mc\n$STD apt-get install -y make zip net-tools\n$STD apt-get install -y gcc g++ cmake\n$STD apt-get install -y ca-certificates\n$STD apt-get install -y gnupg\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Setting up Node.js Repository\"\nmkdir -p /etc/apt/keyrings\ncurl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg\necho \"deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main\" >/etc/apt/sources.list.d/nodesource.list\nmsg_ok \"Set up Node.js Repository\"\n\nmsg_info \"Installing Node.js\"\n$STD apt-get update\n$STD apt-get install -y nodejs\nmsg_ok \"Installed Node.js\"\n\nmsg_info \"Installing FFMPEG\"\n$STD apt-get install -y ffmpeg\nmsg_ok \"Installed FFMPEG\"\n\nmsg_info \"Cloning Shinobi\"\ncd /opt\n$STD git clone https://gitlab.com/Shinobi-Systems/Shinobi.git -b master Shinobi\ncd Shinobi\ngitVersionNumber=$(git rev-parse HEAD)\ntheDateRightNow=$(date)\ntouch version.json\nchmod 777 version.json\necho '{\"Product\" : \"'\"Shinobi\"'\" , \"Branch\" : \"'\"master\"'\" , \"Version\" : \"'\"$gitVersionNumber\"'\" , \"Date\" : \"'\"$theDateRightNow\"'\" , \"Repository\" : \"'\"https://gitlab.com/Shinobi-Systems/Shinobi.git\"'\"}' > version.json\nmsg_ok \"Cloned Shinobi\"\n\nmsg_info \"Installing Database\"\nsqluser=\"root\"\nsqlpass=\"root\"\necho \"mariadb-server mariadb-server/root_password password $sqlpass\" | debconf-set-selections\necho \"mariadb-server mariadb-server/root_password_again password $sqlpass\" | debconf-set-selections\n$STD apt-get install -y mariadb-server\nservice mysql start\nmysql -u \"$sqluser\" -p\"$sqlpass\" -e \"source sql/user.sql\" || true\nmsg_ok \"Installed Database\"\n\nmsg_info \"Installing Shinobi\"\ncp conf.sample.json conf.json\ncronKey=$(head -c 1024 < /dev/urandom | sha256sum | awk '{print substr($1,1,29)}')\nsed -i -e 's/Shinobi/'\"$cronKey\"'/g' conf.json\ncp super.sample.json super.json\n$STD npm i npm -g\n$STD npm install --unsafe-perm\n$STD npm install pm2@latest -g\nchmod -R 755 .\ntouch INSTALL/installed.txt\nln -s /opt/Shinobi/INSTALL/shinobi /usr/bin/shinobi\nnode /opt/Shinobi/tools/modifyConfiguration.js addToConfig=\"{\\\"cron\\\":{\\\"key\\\":\\\"$(head -c 64 < /dev/urandom | sha256sum | awk '{print substr($1,1,60)}')\\\"}}\" &>/dev/null\n$STD pm2 start camera.js\n$STD pm2 start cron.js\n$STD pm2 startup\n$STD pm2 save\n$STD pm2 list\nmsg_ok \"Installed Shinobi\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/smokeping-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing SmokePing\"\n$STD apt-get install -y smokeping\ncat <<EOF >/etc/smokeping/config.d/Targets\n*** Targets ***\nprobe = FPing\nmenu = Top\ntitle = Network Latency Grapher\nremark = Welcome to SmokePing.\n+ Local\nmenu = Local\ntitle = Local Network (ICMP)\n++ LocalMachine\nmenu = Local Machine\ntitle = This host\nhost = localhost\n+ DNS\nmenu = DNS latency\ntitle = DNS latency (ICMP)\n++ Google\ntitle = Google\nhost = 8.8.8.8\n++ Cloudflare\ntitle = Cloudflare\nhost = 1.1.1.1\n++ Quad9  \ntitle = Quad9 \nhost = 9.9.9.9\n++ OpenDNS\ntitle = OpenDNS\nhost = 208.67.222.222\n+ HTTP\nmenu = HTTP latency\ntitle = HTTP latency (ICMP)\n++ Github\nhost = github.com\n++ Discord\nhost = discord.com\n++ Google\nhost = google.com\n++ Cloudflare\nhost = cloudflare.com\n++ Amazon\nhost = amazon.com\n++ Netflix\nhost = netflix.com\nEOF\nsystemctl restart smokeping\nmsg_ok \"Installed SmokePing\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/sonarr-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y sqlite3\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Sonarr v4\"\nmkdir -p /var/lib/sonarr/\nchmod 775 /var/lib/sonarr/\nwget -q -O SonarrV4.tar.gz 'https://services.sonarr.tv/v1/download/main/latest?version=4&os=linux&arch=x64'\ntar -xzf SonarrV4.tar.gz\nmv Sonarr /opt\nrm -rf SonarrV4.tar.gz\n\nmsg_ok \"Installed Sonarr v4\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/sonarr.service\n[Unit]\nDescription=Sonarr Daemon\nAfter=syslog.target network.target\n[Service]\nType=simple\nExecStart=/opt/Sonarr/Sonarr -nobrowser -data=/var/lib/sonarr/\nTimeoutStopSec=20\nKillMode=process\nRestart=on-failure\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now sonarr.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/spoolman-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck\n# Co-Author: MickLesk (Canbiz)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n# Source: https://github.com/Donkie/Spoolman\n\nsource /dev/stdin <<<\"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y \\\n  build-essential \\\n  curl \\\n  sudo \\\n  make \\\n  libpq-dev \\\n  gpg \\\n  ca-certificates \\\n  mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Python3\"\n$STD apt-get install -y \\\n  python3-dev \\\n  python3-setuptools \\\n  python3-wheel \\\n  python3-pip\nmsg_ok \"Installed Python3\"\n\nmsg_info \"Installing Spoolman\"\nRELEASE=$(wget -q https://github.com/Donkie/Spoolman/releases/latest -O - | grep \"title>Release\" | cut -d \" \" -f 4)\ncd /opt\nwget -q https://github.com/Donkie/Spoolman/releases/download/$RELEASE/spoolman.zip\nunzip -q spoolman.zip -d spoolman\nrm -rf spoolman.zip\ncd spoolman\n$STD pip3 install -r requirements.txt\nwget -q https://raw.githubusercontent.com/Donkie/Spoolman/master/.env.example -O .env\necho \"${RELEASE}\" >/opt/${APPLICATION}_version.txt\nmsg_ok \"Installed Spoolman\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/spoolman.service\n[Unit]\nDescription=Spoolman\nAfter=network.target\n[Service]\nType=simple\nWorkingDirectory=/opt/spoolman\nEnvironmentFile=/opt/spoolman/.env\nExecStart=uvicorn spoolman.main:app --host 0.0.0.0 --port 7912\nRestart=always\nUser=root\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now spoolman.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/stirling-pdf-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies (Patience)\"\n$STD apt-get install -y \\\n  curl \\\n  sudo \\\n  mc \\\n  git \\\n  automake \\\n  autoconf \\\n  libtool \\\n  libleptonica-dev \\\n  pkg-config \\\n  zlib1g-dev \\\n  make \\\n  g++ \\\n  unpaper \\\n  ocrmypdf \\\n  poppler-utils\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing LibreOffice Components\"\n$STD apt-get install -y \\\n  libreoffice-writer \\\n  libreoffice-calc \\\n  libreoffice-impress\nmsg_ok \"Installed LibreOffice Components\"\n\nmsg_info \"Installing Python Dependencies\"\n$STD apt-get install -y \\\n  python3 \\\n  python3-pip\nrm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED\n$STD pip3 install \\\n  uno \\\n  opencv-python-headless \\\n  unoconv \\\n  pngquant \\\n  WeasyPrint \nmsg_ok \"Installed Python Dependencies\"\n\nmsg_info \"Installing Azul Zulu\"\nwget -qO /etc/apt/trusted.gpg.d/zulu-repo.asc \"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xB1998361219BD9C9\"\nwget -q https://cdn.azul.com/zulu/bin/zulu-repo_1.0.0-3_all.deb\n$STD dpkg -i zulu-repo_1.0.0-3_all.deb\n$STD apt-get update\n$STD apt-get -y install zulu17-jdk\nmsg_ok \"Installed Azul Zulu\"\n\nmsg_info \"Installing JBIG2\"\n$STD git clone https://github.com/agl/jbig2enc /opt/jbig2enc\ncd /opt/jbig2enc\n$STD bash ./autogen.sh\n$STD bash ./configure\n$STD make\n$STD make install\nmsg_ok \"Installed JBIG2\"\n\nmsg_info \"Installing Language Packs (Patience)\"\n$STD apt-get install -y 'tesseract-ocr-*'\nmsg_ok \"Installed Language Packs\"\n\nmsg_info \"Installing Stirling-PDF (Additional Patience)\"\nRELEASE=$(curl -s https://api.github.com/repos/Stirling-Tools/Stirling-PDF/releases/latest | grep \"tag_name\" | awk '{print substr($2, 3, length($2)-4) }')\nwget -q https://github.com/Stirling-Tools/Stirling-PDF/archive/refs/tags/v$RELEASE.tar.gz\ntar -xzf v$RELEASE.tar.gz\ncd Stirling-PDF-$RELEASE\nchmod +x ./gradlew\n$STD ./gradlew build\nmkdir -p /opt/Stirling-PDF\ntouch /opt/Stirling-PDF/.env\nmv ./build/libs/Stirling-PDF-*.jar /opt/Stirling-PDF/\nmv scripts /opt/Stirling-PDF/\nln -s /opt/Stirling-PDF/Stirling-PDF-$RELEASE.jar /opt/Stirling-PDF/Stirling-PDF.jar\nln -s /usr/share/tesseract-ocr/5/tessdata/ /usr/share/tessdata\nmsg_ok \"Installed Stirling-PDF v$RELEASE\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/stirlingpdf.service\n[Unit]\nDescription=Stirling-PDF service\nAfter=syslog.target network.target\n\n[Service]\nSuccessExitStatus=143\n\nUser=root\nGroup=root\n\nType=simple\nEnvironmentFile=/opt/Stirling-PDF/.env\nWorkingDirectory=/opt/Stirling-PDF\nExecStart=/usr/bin/java -jar Stirling-PDF.jar\nExecStop=/bin/kill -15 %n\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now stirlingpdf.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\nrm -rf v$RELEASE.tar.gz /zulu-repo_1.0.0-3_all.deb\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/syncthing-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y gnupg\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Syncthing\"\ncurl -sL -o /usr/share/keyrings/syncthing-archive-keyring.gpg https://syncthing.net/release-key.gpg\nsh -c 'echo \"deb [signed-by=/usr/share/keyrings/syncthing-archive-keyring.gpg] https://apt.syncthing.net/ syncthing stable\" > /etc/apt/sources.list.d/syncthing.list'\n$STD apt-get update\n$STD apt-get install -y syncthing\n$STD systemctl enable syncthing@root.service\nsystemctl start syncthing@root.service\nsleep 5\nsed -i \"{s/127.0.0.1:8384/0.0.0.0:8384/g}\" /root/.local/state/syncthing/config.xml\nsystemctl restart syncthing@root.service\nmsg_ok \"Installed Syncthing\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/tandoor-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck\n# Co-Author: MickLesk (Canbiz)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies (Patience)\"\n$STD apt-get install -y --no-install-recommends \\\n  build-essential \\\n  libpq-dev \\\n  libmagic-dev \\\n  libzbar0 \\\n  nginx \\\n  libsasl2-dev \\\n  libldap2-dev \\\n  libssl-dev \\\n  gpg \\\n  curl \\\n  sudo \\\n  git \\\n  make \\\n  mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Updating Python3\"\n$STD apt-get install -y \\\n  python3 \\\n  python3-dev \\\n  python3-setuptools \\\n  python3-pip\nrm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED\nmsg_ok \"Updated Python3\"\n\nmsg_info \"Setting up Node.js Repository\"\nmkdir -p /etc/apt/keyrings\ncurl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg\necho \"deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main\" >/etc/apt/sources.list.d/nodesource.list\nmsg_ok \"Set up Node.js Repository\"\n\nmsg_info \"Installing Node.js\"\n$STD apt-get update\n$STD apt-get install -y nodejs\n$STD npm install -g yarn\nmsg_ok \"Installed Node.js\"\n\nmsg_info \"Installing Tandoor (Patience)\"\n$STD git clone https://github.com/vabene1111/recipes.git -b master /opt/tandoor\nmkdir -p /opt/tandoor/{config,api,mediafiles,staticfiles}\n$STD pip3 install -r /opt/tandoor/requirements.txt\ncd /opt/tandoor/vue\n$STD yarn install\n$STD yarn build\nwget -q https://raw.githubusercontent.com/vabene1111/recipes/develop/.env.template -O /opt/tandoor/.env\nDB_NAME=db_recipes\nDB_USER=tandoor\nDB_ENCODING=utf8\nDB_TIMEZONE=UTC\nsecret_key=$(openssl rand -base64 45 | sed 's/\\//\\\\\\//g')\nDB_PASS=\"$(openssl rand -base64 18 | cut -c1-13)\"\nsed -i -e \"s|SECRET_KEY=.*|SECRET_KEY=$secret_key|g\" \\\n       -e \"s|POSTGRES_HOST=.*|POSTGRES_HOST=localhost|g\" \\\n       -e \"s|POSTGRES_PASSWORD=.*|POSTGRES_PASSWORD=$DB_PASS|g\" \\\n       -e \"s|POSTGRES_DB=.*|POSTGRES_DB=$DB_NAME|g\" \\\n       -e \"s|POSTGRES_USER=.*|POSTGRES_USER=$DB_USER|g\" \\\n       -e \"\\$a\\STATIC_URL=/staticfiles/\" /opt/tandoor/.env\nmsg_ok \"Installed Tandoor\"\n\nmsg_info \"Install/Set up PostgreSQL Database\"\ncurl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc|gpg --dearmor -o /etc/apt/trusted.gpg.d/postgresql.gpg\necho \"deb https://apt.postgresql.org/pub/repos/apt bookworm-pgdg main\" >/etc/apt/sources.list.d/pgdg.list\n$STD apt-get update\n$STD apt-get install -y postgresql-16\n$STD sudo -u postgres psql -c \"CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';\"\n$STD sudo -u postgres psql -c \"CREATE DATABASE $DB_NAME WITH OWNER $DB_USER TEMPLATE template0;\"\n$STD sudo -u postgres psql -c \"ALTER ROLE $DB_USER SET client_encoding TO 'utf8';\"\n$STD sudo -u postgres psql -c \"ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';\"\n$STD sudo -u postgres psql -c \"ALTER ROLE $DB_USER SET timezone TO 'UTC'\"\necho \"\" >>~/tandoor.creds\necho -e \"Tandoor Database Name: \\e[32m$DB_NAME\\e[0m\" >>~/tandoor.creds\necho -e \"Tandoor Database User: \\e[32m$DB_USER\\e[0m\" >>~/tandoor.creds\necho -e \"Tandoor Database Password: \\e[32m$DB_PASS\\e[0m\" >>~/tandoor.creds\nexport $(cat /opt/tandoor/.env |grep \"^[^#]\" | xargs)\n/usr/bin/python3 /opt/tandoor/manage.py migrate >/dev/null 2>&1\n/usr/bin/python3 /opt/tandoor/manage.py collectstatic --no-input >/dev/null 2>&1\n/usr/bin/python3 /opt/tandoor/manage.py collectstatic_js_reverse >/dev/null 2>&1\nmsg_ok \"Set up PostgreSQL Database\"\n\nmsg_info \"Creating Services\"\ncat <<EOF >/etc/systemd/system/gunicorn_tandoor.service\n[Unit]\nDescription=gunicorn daemon for tandoor\nAfter=network.target\n\n[Service]\nType=simple\nRestart=always\nRestartSec=3\nWorkingDirectory=/opt/tandoor\nEnvironmentFile=/opt/tandoor/.env\nExecStart=/usr/local/bin/gunicorn --error-logfile /tmp/gunicorn_err.log --log-level debug --capture-output --bind unix:/opt/tandoor/tandoor.sock recipes.wsgi:application\n\n[Install]\nWantedBy=multi-user.target\nEOF\n\ncat << 'EOF' >/etc/nginx/conf.d/tandoor.conf\nserver {\n    listen 8002;\n    #access_log /var/log/nginx/access.log;\n    #error_log /var/log/nginx/error.log;\n    client_max_body_size 128M;\n    # serve media files\n    location /static/ {\n        alias /opt/tandoor/staticfiles/;\n    }\n\n    location /media/ {\n        alias /opt/tandoor/mediafiles/;\n    }\n\n    location / {\n        proxy_set_header Host $http_host;\n        proxy_pass http://unix:/opt/tandoor/tandoor.sock;\n    }\n}\nEOF\nsystemctl reload nginx\nsystemctl enable -q --now gunicorn_tandoor\nmsg_ok \"Created Services\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/tasmoadmin-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y apache2\n$STD apt-get install -y php8.2\n$STD apt-get install -y libapache2-mod-php\n$STD apt-get install -y php8.2-curl\n$STD apt-get install -y php8.2-zip\n$STD apt-get install -y php8.2-mbstring\n$STD apt-get install -y php8.2-xml\n$STD apt-get install -y git\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing TasmoAdmin\"\nwget -q https://github.com/TasmoAdmin/TasmoAdmin/releases/download/v3.1.1/tasmoadmin_v3.1.1.tar.gz\ntar -xzf tasmoadmin_v3.1.1.tar.gz -C /var/www/\nrm -rf tasmoadmin_v3.1.1.tar.gz /etc/php/8.2/apache2/conf.d/10-opcache.ini\nchown -R www-data:www-data /var/www/tasmoadmin\nchmod 777 /var/www/tasmoadmin/tmp /var/www/tasmoadmin/data\ncat <<EOF >/etc/apache2/sites-available/tasmoadmin.conf\n<VirtualHost *:9999>\n\tServerName tasmoadmin\n\tServerAdmin webmaster@localhost\n\tDocumentRoot /var/www/tasmoadmin\n\t<Directory /var/www/tasmoadmin>\n\tAllowOverride All\n\tOrder allow,deny\n\tallow from all\n\t</Directory>\n\tErrorLog /var/log/apache2/error.log\n\tLogLevel warn\n\tCustomLog /var/log/apache2/access.log combined\n\tServerSignature On\n</VirtualHost>\nEOF\nsed -i '6iListen 9999' /etc/apache2/ports.conf\n$STD a2ensite tasmoadmin\n$STD a2enmod rewrite\nsystemctl reload apache2\nsystemctl restart apache2\nmsg_ok \"Installed TasmoAdmin\"\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/tautulli-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y git\n$STD apt-get install -y pip\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Updating Python3\"\n$STD apt-get install -y \\\n  python3 \\\n  python3-dev \\\n  python3-pip\nrm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED\nmsg_ok \"Updated Python3\"\n\nmsg_info \"Installing Tautulli\"\ncd /opt\n$STD git clone https://github.com/Tautulli/Tautulli.git\n$STD pip install -q -r /opt/Tautulli/requirements.txt\n$STD pip install pyopenssl\nmsg_ok \"Installed Tautulli\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/tautulli.service\n[Unit]\nDescription=Tautulli\nAfter=syslog.target network.target\n\n[Service]\nWorkingDirectory=/opt/Tautulli/\nRestart=on-failure\nRestartSec=5\nType=simple\nExecStart=/usr/bin/python3 /opt/Tautulli/Tautulli.py\nKillSignal=SIGINT\nTimeoutStopSec=20\nSyslogIdentifier=tautulli\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now tautulli\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/tdarr-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y handbrake-cli\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Setting Up Hardware Acceleration\"\n$STD apt-get -y install {va-driver-all,ocl-icd-libopencl1,intel-opencl-icd,vainfo,intel-gpu-tools}\nif [[ \"$CTTYPE\" == \"0\" ]]; then\n  chgrp video /dev/dri\n  chmod 755 /dev/dri\n  chmod 660 /dev/dri/*\n  $STD adduser $(id -u -n) video\n  $STD adduser $(id -u -n) render\nfi\nmsg_ok \"Set Up Hardware Acceleration\"\n\nmsg_info \"Installing Tdarr\"\nmkdir -p /opt/tdarr\ncd /opt/tdarr\nRELEASE=$(curl -s https://f000.backblazeb2.com/file/tdarrs/versions.json | grep -oP '(?<=\"Tdarr_Updater\": \")[^\"]+' | grep linux_x64 | head -n 1)\nwget -q $RELEASE\n$STD unzip Tdarr_Updater.zip\nrm -rf Tdarr_Updater.zip\nchmod +x Tdarr_Updater\n./Tdarr_Updater &>/dev/null\nif [[ \"$CTTYPE\" == \"0\" ]]; then\n  sed -i -e 's/^sgx:x:104:$/render:x:104:root/' -e 's/^render:x:106:root$/sgx:x:106:/' /etc/group\nelse\n  sed -i -e 's/^sgx:x:104:$/render:x:104:/' -e 's/^render:x:106:$/sgx:x:106:/' /etc/group\nfi\n\nmsg_ok \"Installed Tdarr\"\n\nmsg_info \"Creating Service\"\nservice_path=\"/etc/systemd/system/tdarr-server.service\"\necho \"[Unit]\nDescription=Tdarr Server Daemon\nAfter=network.target\n# Enable if using ZFS, edit and enable if other FS mounting is required to access directory\n#Requires=zfs-mount.service\n\n[Service]\nUser=root\nGroup=root\n\nType=simple\nWorkingDirectory=/opt/tdarr/Tdarr_Server\nExecStartPre=/opt/tdarr/Tdarr_Updater                  \nExecStart=/opt/tdarr/Tdarr_Server/Tdarr_Server\nTimeoutStopSec=20\nKillMode=process\nRestart=on-failure\n\n[Install]\nWantedBy=multi-user.target\" >$service_path\n\nservice_path=\"/etc/systemd/system/tdarr-node.service\"\necho \"[Unit]\nDescription=Tdarr Node Daemon\nAfter=network.target\nRequires=tdarr-server.service\n\n[Service]\nUser=root\nGroup=root\n\nType=simple\nWorkingDirectory=/opt/tdarr/Tdarr_Node\nExecStart=/opt/tdarr/Tdarr_Node/Tdarr_Node\nTimeoutStopSec=20\nKillMode=process\nRestart=on-failure\n\n[Install]\nWantedBy=multi-user.target\" >$service_path\nsystemctl enable --now -q tdarr-server.service\nsystemctl enable --now -q tdarr-node.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\nrm -rf Tdarr_Updater.zip\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/technitiumdns-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing ASP.NET Core Runtime\"\nwget -q https://packages.microsoft.com/config/debian/12/packages-microsoft-prod.deb -O packages-microsoft-prod.deb\n$STD dpkg -i packages-microsoft-prod.deb\nrm -rf packages-microsoft-prod.deb\n$STD apt-get update\n$STD apt-get install -y aspnetcore-runtime-8.0\nmsg_ok \"Installed ASP.NET Core Runtime\"\n\nmsg_info \"Installing Technitium DNS\"\n$STD bash <(curl -fsSL https://download.technitium.com/dns/install.sh)\nmsg_ok \"Installed Technitium DNS\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/threadfin-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y curl\n$STD apt-get install -y ffmpeg\n$STD apt-get install -y vlc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Threadfin\"\nmkdir -p /opt/threadfin\nwget -q -O /opt/threadfin/threadfin 'https://github.com/Threadfin/Threadfin/releases/latest/download/Threadfin_linux_amd64'\nchmod +x /opt/threadfin/threadfin\n\nmsg_ok \"Installed Threadfin\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/threadfin.service\n[Unit]\nDescription=Threadfin: M3U Proxy for Plex DVR and Emby/Jellyfin Live TV\nAfter=syslog.target network.target\n[Service]\nType=simple\nWorkingDirectory=/opt/threadfin\nExecStart=/opt/threadfin/threadfin\nTimeoutStopSec=20\nKillMode=process\nRestart=on-failure\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now threadfin.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/tianji-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck\n# Co-Author: MickLesk (Canbiz)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n# Source: https://github.com/msgbyte/tianji\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y \\\n  postgresql \\\n  python3 \\\n  cmake \\\n  g++ \\\n  build-essential \\\n  curl \\\n  sudo \\\n  git \\\n  make \\\n  gnupg \\\n  ca-certificates \\\n  mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Node.js\"\nmkdir -p /etc/apt/keyrings\ncurl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg\necho \"deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main\" >/etc/apt/sources.list.d/nodesource.list\n$STD apt-get update\n$STD apt-get install -y nodejs\n$STD npm install -g pnpm@9.7.1\nexport NODE_OPTIONS=\"--max_old_space_size=4096\"\nmsg_ok \"Installed Node.js\"\n\nmsg_info \"Setting up PostgreSQL\"\nDB_NAME=tianji_db\nDB_USER=tianji\nDB_PASS=\"$(openssl rand -base64 18 | cut -c1-13)\"\nTIANJI_SECRET=\"$(openssl rand -base64 32 | cut -c1-24)\"\n$STD sudo -u postgres psql -c \"CREATE DATABASE $DB_NAME;\"\n$STD sudo -u postgres psql -c \"CREATE USER $DB_USER WITH PASSWORD '$DB_PASS';\"\n$STD sudo -u postgres psql -c \"GRANT ALL PRIVILEGES ON DATABASE $DB_NAME TO $DB_USER;\" \n$STD sudo -u postgres psql -c \"ALTER DATABASE $DB_NAME OWNER TO $DB_USER;\"\n$STD sudo -u postgres psql -c \"ALTER USER $DB_USER WITH SUPERUSER;\"\necho \"\" >>~/tianji.creds\necho -e \"Tianji Database User: $DB_USER\" >>~/tianji.creds\necho -e \"Tianji Database Password: $DB_PASS\" >>~/tianji.creds\necho -e \"Tianji Database Name: $DB_NAME\" >>~/tianji.creds\necho -e \"Tianji Secret: $TIANJI_SECRET\" >>~/tianji.creds\nmsg_ok \"Set up PostgreSQL\"\n\nmsg_info \"Installing Tianji (Extreme Patience)\"\ncd /opt\nRELEASE=$(curl -s https://api.github.com/repos/msgbyte/tianji/releases/latest | grep \"tag_name\" | awk '{print substr($2, 3, length($2)-4) }')\nwget -q \"https://github.com/msgbyte/tianji/archive/refs/tags/v${RELEASE}.zip\"\nunzip -q v${RELEASE}.zip\nmv tianji-${RELEASE} /opt/tianji\ncd tianji\n$STD pnpm install --filter @tianji/client... --config.dedupe-peer-dependents=false --frozen-lockfile\n$STD pnpm build:static\n$STD pnpm install --filter @tianji/server... --config.dedupe-peer-dependents=false\nmkdir -p ./src/server/public\ncp -r ./geo ./src/server/public\n$STD pnpm build:server\necho \"${RELEASE}\" >\"/opt/${APPLICATION}_version.txt\"\ncat <<EOF >/opt/tianji/src/server/.env\nDATABASE_URL=\"postgresql://$DB_USER:$DB_PASS@localhost:5432/$DB_NAME?schema=public\"\nJWT_SECRET=\"$TIANJI_SECRET\"\nEOF\ncd /opt/tianji/src/server\n$STD pnpm db:migrate:apply\nmsg_ok \"Installed Tianji\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/tianji.service\n[Unit]\nDescription=Tianji Server\nAfter=network.target\n\n[Service]\nExecStart=/usr/bin/node /opt/tianji/src/server/dist/src/server/main.js\nWorkingDirectory=/opt/tianji/src/server\nRestart=always\nRestartSec=10\n\nEnvironment=NODE_ENV=production\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now tianji.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\nrm -R /opt/v${RELEASE}.zip\nrm -rf /opt/tianji/src/client\nrm -rf /opt/tianji/website\nrm -rf /opt/tianji/reporter\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/traccar-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nRELEASE=$(curl -s https://api.github.com/repos/traccar/traccar/releases/latest | grep \"tag_name\" | awk '{print substr($2, 3, length($2)-4) }')\nmsg_info \"Installing Traccar v${RELEASE}\"\nwget -q https://github.com/traccar/traccar/releases/download/v${RELEASE}/traccar-linux-64-${RELEASE}.zip\n$STD unzip traccar-linux-64-${RELEASE}.zip\n$STD ./traccar.run\nsystemctl enable -q --now traccar\nrm -rf README.txt  traccar-linux-64-${RELEASE}.zip  traccar.run\nmsg_ok \"Installed Traccar v${RELEASE}\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/traefik-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y gpg\n$STD apt-get install -y apt-transport-https\nmsg_ok \"Installed Dependencies\"\n\nRELEASE=$(curl -s https://api.github.com/repos/traefik/traefik/releases | grep -oP '\"tag_name\":\\s*\"v\\K[\\d.]+?(?=\")' | sort -V | tail -n 1)\nmsg_info \"Installing Traefik v${RELEASE}\"\nmkdir -p /etc/traefik/{conf.d,ssl}\nwget -q https://github.com/traefik/traefik/releases/download/v${RELEASE}/traefik_v${RELEASE}_linux_amd64.tar.gz\ntar -C /tmp -xzf traefik*.tar.gz\nmv /tmp/traefik /usr/bin/\nrm -rf traefik*.tar.gz\necho \"${RELEASE}\" >/opt/${APPLICATION}_version.txt\nmsg_ok \"Installed Traefik v${RELEASE}\"\n\nmsg_info \"Creating Traefik configuration\"\ncat <<EOF >/etc/traefik/traefik.yaml\nproviders:\n  file:\n    directory: /etc/traefik/conf.d/\n\nentryPoints:\n  web:\n    address: ':80'\n    http:\n      redirections:\n        entryPoint:\n          to: websecure\n          scheme: https\n  websecure:\n    address: ':443'\n    http:\n      tls:\n        certResolver: letsencrypt\n  traefik:\n    address: ':8080'\n\ncertificatesResolvers:\n  letsencrypt:\n    acme:\n      email: \"foo@bar.com\"\n      storage: /etc/traefik/ssl/acme.json\n      tlsChallenge: {}\n\napi:\n  dashboard: true\n  insecure: true\n\nlog:\n  filePath: /var/log/traefik/traefik.log\n  format: json\n  level: INFO\n\naccessLog:\n  filePath: /var/log/traefik/traefik-access.log\n  format: json\n  filters:\n    statusCodes:\n      - \"200\"\n      - \"400-599\"\n    retryAttempts: true\n    minDuration: \"10ms\"\n  bufferingSize: 0\n  fields:\n    headers:\n      defaultMode: drop\n      names:\n        User-Agent: keep\nEOF\nmsg_ok \"Created Traefik configuration\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/traefik.service\n[Unit]\nDescription=Traefik is an open-source Edge Router that makes publishing your services a fun and easy experience\n\n[Service]\nType=notify\nExecStart=/usr/bin/traefik --configFile=/etc/traefik/traefik.yaml\nRestart=on-failure\nExecReload=/bin/kill -USR1 \\$MAINPID\n\n[Install]\nWantedBy=multi-user.target\nEOF\n\nsystemctl enable -q --now traefik.service\nmsg_ok \"Created Service\"\n\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/transmission-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\n\nmsg_info \"Installing Transmission\"\n$STD apt-get install -y transmission-daemon\nsystemctl stop transmission-daemon\nsed -i '{s/\"rpc-whitelist-enabled\": true/\"rpc-whitelist-enabled\": false/g; s/\"rpc-host-whitelist-enabled\": true,/\"rpc-host-whitelist-enabled\": false,/g}' /etc/transmission-daemon/settings.json\nsystemctl start transmission-daemon\nmsg_ok \"Installed Transmission\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/trilium-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nRELEASE=$(curl -s https://api.github.com/repos/TriliumNext/Notes/releases/latest | grep \"tag_name\" | awk '{print substr($2, 2, length($2)-3) }')\n\nmsg_info \"Installing TriliumNext\"\nwget -q https://github.com/TriliumNext/Notes/releases/download/${RELEASE}/TriliumNextNotes-${RELEASE}-server-linux-x64.tar.xz\ntar -xf TriliumNextNotes-${RELEASE}-server-linux-x64.tar.xz\nmv trilium-linux-x64-server /opt/trilium\nmsg_ok \"Installed TriliumNext\"\n\nmsg_info \"Creating Service\"\nservice_path=\"/etc/systemd/system/trilium.service\"\n\necho \"[Unit]\nDescription=Trilium Daemon\nAfter=syslog.target network.target\n\n[Service]\nUser=root\nType=simple\nExecStart=/opt/trilium/trilium.sh\nWorkingDirectory=/opt/trilium/\nTimeoutStopSec=20\nRestart=always\n\n[Install]\nWantedBy=multi-user.target\" >$service_path\nsystemctl enable --now -q trilium\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nrm -rf TriliumNextNotes-${RELEASE}-server-linux-x64.tar.xz\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/ubuntu-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/umami-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y git\n$STD apt-get install -y gpg\n$STD apt-get install -y postgresql\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Setting up Node.js Repository\"\nmkdir -p /etc/apt/keyrings\ncurl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg\necho \"deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main\" >/etc/apt/sources.list.d/nodesource.list\nmsg_ok \"Set up Node.js Repository\"\n\nmsg_info \"Installing Node.js\"\n$STD apt-get update\n$STD apt-get install -y nodejs\n$STD npm install -g yarn\nmsg_ok \"Installed Node.js\"\n\nmsg_info \"Setting up postgresql\"\nDB_NAME=umamidb\nDB_USER=umami\nDB_PASS=\"$(openssl rand -base64 18 | cut -c1-13)\"\nSECRET_KEY=\"$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32)\"\n$STD sudo -u postgres psql -c \"CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';\"\n$STD sudo -u postgres psql -c \"CREATE DATABASE $DB_NAME WITH OWNER $DB_USER ENCODING 'UTF8' TEMPLATE template0;\"\n$STD sudo -u postgres psql -c \"ALTER ROLE $DB_USER SET client_encoding TO 'utf8';\"\n$STD sudo -u postgres psql -c \"ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';\"\n$STD sudo -u postgres psql -c \"ALTER ROLE $DB_USER SET timezone TO 'UTC'\"\necho \"\" >~/umami.creds\necho \"Umami Database Credentials\" >>~/umami.creds\necho \"\" >>~/umami.creds\necho -e \"umami Database User: \\e[32m$DB_USER\\e[0m\" >>~/umami.creds\necho -e \"umami Database Password: \\e[32m$DB_PASS\\e[0m\" >>~/umami.creds\necho -e \"umami Database Name: \\e[32m$DB_NAME\\e[0m\" >>~/umami.creds\nmsg_ok \"Set up postgresql\"\n\nmsg_info \"Installing Umami (Patience)\"\ngit clone -q https://github.com/umami-software/umami.git /opt/umami\ncd /opt/umami\n$STD yarn install\necho -e \"DATABASE_URL=postgresql://$DB_USER:$DB_PASS@localhost:5432/$DB_NAME\" >>/opt/umami/.env\n$STD yarn run build\nmsg_ok \"Installed Umami\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/umami.service\necho \"[Unit]\nDescription=umami\n\n[Service]\nType=simple\nRestart=always\nUser=root\nWorkingDirectory=/opt/umami\nExecStart=/usr/bin/yarn run start\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now umami.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/umbrel-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Umbrel (Patience)\"\nDOCKER_CONFIG_PATH='/etc/docker/daemon.json'\nmkdir -p $(dirname $DOCKER_CONFIG_PATH)\necho -e '{\\n  \"log-driver\": \"journald\"\\n}' > /etc/docker/daemon.json\n$STD bash <(curl -fsSL https://umbrel.sh)\nsystemctl daemon-reload\n$STD systemctl enable --now umbrel-startup.service\nmsg_ok \"Installed Umbrel\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n#$STD apt-get autoremove\n#$STD apt-get autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/unifi-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y apt-transport-https\n$STD apt-get install -y gnupg\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Eclipse Temurin JRE\"\nwget -qO- https://packages.adoptium.net/artifactory/api/gpg/key/public | gpg --dearmor >/etc/apt/trusted.gpg.d/adoptium.gpg\necho \"deb [arch=amd64 signed-by=/etc/apt/trusted.gpg.d/adoptium.gpg] https://packages.adoptium.net/artifactory/deb bookworm main\" >/etc/apt/sources.list.d/adoptium.list\n$STD apt-get update\n$STD apt-get install -y temurin-17-jre\nmsg_ok \"Installed Eclipse Temurin JRE\"\n\nmsg_info \"Installing MongoDB\"\nwget -qO- https://www.mongodb.org/static/pgp/server-7.0.asc | gpg --dearmor >/usr/share/keyrings/mongodb-server-7.0.gpg\necho \"deb [ signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] http://repo.mongodb.org/apt/debian bookworm/mongodb-org/7.0 main\" >/etc/apt/sources.list.d/mongodb-org-7.0.list\n$STD apt-get update\n$STD apt-get install -y mongodb-org\nmsg_ok \"Installed MongoDB\"\n\nmsg_info \"Installing UniFi Network Server\"\nwget -qO /etc/apt/trusted.gpg.d/unifi-repo.gpg https://dl.ui.com/unifi/unifi-repo.gpg\necho \"deb [ arch=amd64 signed-by=/etc/apt/trusted.gpg.d/unifi-repo.gpg] https://www.ui.com/downloads/unifi/debian stable ubiquiti\" >/etc/apt/sources.list.d/100-ubnt-unifi.list\n$STD apt-get update\n$STD apt-get install -y unifi\nmsg_ok \"Installed UniFi Network Server\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/unmanic-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies (Patience)\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y ffmpeg\n$STD apt-get install -y python3-pip\nmsg_ok \"Installed Dependencies\"\n\nif [[ \"$CTTYPE\" == \"0\" ]]; then\n  msg_info \"Setting Up Hardware Acceleration\"\n  $STD apt-get -y install \\\n    va-driver-all \\\n    ocl-icd-libopencl1 \\\n    intel-opencl-icd\n  chgrp video /dev/dri\n  chmod 755 /dev/dri\n  chmod 660 /dev/dri/*\n  $STD adduser $(id -u -n) video\n  $STD adduser $(id -u -n) render\n  msg_ok \"Set Up Hardware Acceleration\"\nfi\n\nmsg_info \"Installing Unmanic\"\n$STD pip3 install unmanic\nsed -i -e 's/^sgx:x:104:$/render:x:104:root/' -e 's/^render:x:106:root$/sgx:x:106:/' /etc/group\nmsg_ok \"Installed Unmanic\"\n\nmsg_info \"Creating Service\"\ncat << EOF >/etc/systemd/system/unmanic.service\n[Unit]\nDescription=Unmanic - Library Optimiser\nAfter=network-online.target\nStartLimitInterval=200\nStartLimitBurst=3\n\n[Service]\nType=simple\nExecStart=/usr/local/bin/unmanic\nRestart=always\nRestartSec=30\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable --now -q unmanic.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/uptimekuma-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y git\n$STD apt-get install -y ca-certificates\n$STD apt-get install -y gnupg\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Setting up Node.js Repository\"\nmkdir -p /etc/apt/keyrings\ncurl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg\necho \"deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main\" >/etc/apt/sources.list.d/nodesource.list\nmsg_ok \"Set up Node.js Repository\"\n\nmsg_info \"Installing Node.js\"\n$STD apt-get update\n$STD apt-get install -y nodejs\nmsg_ok \"Installed Node.js\"\n\nmsg_info \"Installing Uptime Kuma\"\n$STD git clone https://github.com/louislam/uptime-kuma.git\nmv uptime-kuma /opt/uptime-kuma\ncd /opt/uptime-kuma\n$STD npm run setup\nmsg_ok \"Installed Uptime Kuma\"\n\nmsg_info \"Creating Service\"\nservice_path=\"/etc/systemd/system/uptime-kuma.service\"\necho \"[Unit]\nDescription=uptime-kuma\n\n[Service]\nType=simple\nRestart=always\nUser=root\nWorkingDirectory=/opt/uptime-kuma\nExecStart=/usr/bin/npm start\n\n[Install]\nWantedBy=multi-user.target\" >$service_path\n$STD systemctl enable --now uptime-kuma.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/vaultwarden-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<<\"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get update\n$STD apt-get -qqy install \\\n  git \\\n  build-essential \\\n  pkgconf \\\n  libssl-dev \\\n  libmariadb-dev-compat \\\n  libpq-dev \\\n  curl \\\n  sudo \\\n  argon2 \\\n  mc\nmsg_ok \"Installed Dependencies\"\n\nWEBVAULT=$(curl -s https://api.github.com/repos/dani-garcia/bw_web_builds/releases/latest |\n  grep \"tag_name\" |\n  awk '{print substr($2, 2, length($2)-3) }')\n\nVAULT=$(curl -s https://api.github.com/repos/dani-garcia/vaultwarden/releases/latest |\n  grep \"tag_name\" |\n  awk '{print substr($2, 2, length($2)-3) }')\n\nmsg_info \"Installing Rust\"\nwget -qL https://sh.rustup.rs\n$STD bash index.html -y --profile minimal\necho 'export PATH=~/.cargo/bin:$PATH' >>~/.bashrc\nexport PATH=~/.cargo/bin:$PATH\nrm index.html\nmsg_ok \"Installed Rust\"\n\nmsg_info \"Building Vaultwarden ${VAULT} (Patience)\"\n$STD git clone https://github.com/dani-garcia/vaultwarden\ncd vaultwarden\n$STD cargo build --features \"sqlite,mysql,postgresql\" --release\nmsg_ok \"Built Vaultwarden ${VAULT}\"\n\n$STD addgroup --system vaultwarden\n$STD adduser --system --home /opt/vaultwarden --shell /usr/sbin/nologin --no-create-home --gecos 'vaultwarden' --ingroup vaultwarden --disabled-login --disabled-password vaultwarden\nmkdir -p /opt/vaultwarden/bin\nmkdir -p /opt/vaultwarden/data\ncp target/release/vaultwarden /opt/vaultwarden/bin/\n\nmsg_info \"Downloading Web-Vault ${WEBVAULT}\"\n$STD curl -fsSLO https://github.com/dani-garcia/bw_web_builds/releases/download/$WEBVAULT/bw_web_$WEBVAULT.tar.gz\n$STD tar -xzf bw_web_$WEBVAULT.tar.gz -C /opt/vaultwarden/\nmsg_ok \"Downloaded Web-Vault ${WEBVAULT}\"\n\ncat <<EOF >/opt/vaultwarden/.env\nADMIN_TOKEN=''\nROCKET_ADDRESS=0.0.0.0\nDATA_FOLDER=/opt/vaultwarden/data\nDATABASE_MAX_CONNS=10\nWEB_VAULT_FOLDER=/opt/vaultwarden/web-vault\nWEB_VAULT_ENABLED=true\nEOF\n\nmsg_info \"Creating Service\"\nchown -R vaultwarden:vaultwarden /opt/vaultwarden/\nchown root:root /opt/vaultwarden/bin/vaultwarden\nchmod +x /opt/vaultwarden/bin/vaultwarden\nchown -R root:root /opt/vaultwarden/web-vault/\nchmod +r /opt/vaultwarden/.env\n\nservice_path=\"/etc/systemd/system/vaultwarden.service\"\necho \"[Unit]\nDescription=Bitwarden Server (Powered by Vaultwarden)\nDocumentation=https://github.com/dani-garcia/vaultwarden\nAfter=network.target\n[Service]\nUser=vaultwarden\nGroup=vaultwarden\nEnvironmentFile=-/opt/vaultwarden/.env\nExecStart=/opt/vaultwarden/bin/vaultwarden\nLimitNOFILE=65535\nLimitNPROC=4096\nPrivateTmp=true\nPrivateDevices=true\nProtectHome=true\nProtectSystem=strict\nDevicePolicy=closed\nProtectControlGroups=yes\nProtectKernelModules=yes\nProtectKernelTunables=yes\nRestrictNamespaces=yes\nRestrictRealtime=yes\nMemoryDenyWriteExecute=yes\nLockPersonality=yes\nWorkingDirectory=/opt/vaultwarden\nReadWriteDirectories=/opt/vaultwarden/data\nAmbientCapabilities=CAP_NET_BIND_SERVICE\n[Install]\nWantedBy=multi-user.target\" >$service_path\nsystemctl daemon-reload\n$STD systemctl enable --now vaultwarden.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/wallos-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck\n# Co-Author: MickLesk (Canbiz)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n# Source: https://github.com/ellite/wallos\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y \\\n  curl \\\n  sudo \\\n  mc \\\n  apache2 \\\n  libapache2-mod-php \\\n  php8.2-{mbstring,gd,curl,intl,imagick,bz2,sqlite3,zip,xml} \nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Wallos (Patience)\"\ncd /opt\nRELEASE=$(curl -s https://api.github.com/repos/ellite/Wallos/releases/latest | grep \"tag_name\" | awk '{print substr($2, 3, length($2)-4) }')\nwget -q \"https://github.com/ellite/Wallos/archive/refs/tags/v${RELEASE}.zip\"\nunzip -q v${RELEASE}.zip\nmv Wallos-${RELEASE} /opt/wallos\ncd /opt/wallos\nmv /opt/wallos/db/wallos.empty.db /opt/wallos/db/wallos.db\nchown -R www-data:www-data /opt/wallos\nchmod -R 755 /opt/wallos\necho \"${RELEASE}\" >\"/opt/${APPLICATION}_version.txt\"\n\ncat <<EOF >/etc/apache2/sites-available/wallos.conf\n<VirtualHost *:80>\n    ServerAdmin webmaster@localhost\n    DocumentRoot /opt/wallos\n\n    <Directory /opt/wallos>\n        Options Indexes FollowSymLinks\n        AllowOverride All\n        Require all granted\n    </Directory>\n\n    ErrorLog \\${APACHE_LOG_DIR}/wallos_error.log\n    CustomLog \\${APACHE_LOG_DIR}/wallos_access.log combined\n</VirtualHost>\nEOF\n$STD a2ensite wallos.conf\n$STD a2dissite 000-default.conf  \n$STD systemctl reload apache2\n$STD curl http://localhost/endpoints/db/migrate.php\nmsg_ok \"Installed Wallos\"\n\nmsg_info \"Setting up Crontabs\" \ncat <<EOF > /opt/wallos.cron\n0 1 * * * php /opt/wallos/endpoints/cronjobs/updatenextpayment.php >> /var/log/cron/updatenextpayment.log 2>&1\n0 2 * * * php /opt/wallos/endpoints/cronjobs/updateexchange.php >> /var/log/cron/updateexchange.log 2>&1\n0 8 * * * php /opt/wallos/endpoints/cronjobs/sendcancellationnotifications.php >> /var/log/cron/sendcancellationnotifications.log 2>&1\n0 9 * * * php /opt/wallos/endpoints/cronjobs/sendnotifications.php >> /var/log/cron/sendnotifications.log 2>&1\n*/2 * * * * php /opt/wallos/endpoints/cronjobs/sendverificationemails.php >> /var/log/cron/sendverificationemail.log 2>&1\n*/2 * * * * php /opt/wallos/endpoints/cronjobs/sendresetpasswordemails.php >> /var/log/cron/sendresetpasswordemails.log 2>&1\n0 */6 * * * php /opt/wallos/endpoints/cronjobs/checkforupdates.php >> /var/log/cron/checkforupdates.log 2>&1\nEOF\ncrontab /opt/wallos.cron\nmsg_ok \"Crontabs setup\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\nrm -rf /opt/v${RELEASE}.zip\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\""
  },
  {
    "path": "install/wastebin-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck\n# Co-Author: MickLesk (Canbiz)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n# Source: https://github.com/matze/wastebin\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Wastebin\"\nRELEASE=$(curl -s https://api.github.com/repos/matze/wastebin/releases/latest | grep \"tag_name\" | awk '{print substr($2, 2, length($2)-3) }')\nwget -q https://github.com/matze/wastebin/releases/download/${RELEASE}/wastebin_${RELEASE}_x86_64-unknown-linux-musl.tar.zst\ntar -xf wastebin_${RELEASE}_x86_64-unknown-linux-musl.tar.zst\nrm -rf wastebin_${RELEASE}_x86_64-unknown-linux-musl.tar.zst\nmkdir -p /opt/wastebin\nmv wastebin /opt/wastebin/\nchmod +x /opt/wastebin/wastebin\nmsg_ok \"Installed Wastebin\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/wastebin.service\n[Unit]\nDescription=Start Wastebin Service\nAfter=network.target\n\n[Service]\nWorkingDirectory=/opt/wastebin\nExecStart=/opt/wastebin/wastebin\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now wastebin.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/watchyourlan-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y {curl,sudo,mc,gpg,arp-scan,ieee-data,libwww-perl}\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing WatchYourLAN\"\nRELEASE=$(curl -s https://api.github.com/repos/aceberg/WatchYourLAN/releases/latest | grep -o '\"tag_name\": *\"[^\"]*\"' | cut -d '\"' -f 4)\nwget -q https://github.com/aceberg/WatchYourLAN/releases/download/$RELEASE/watchyourlan_${RELEASE}_linux_amd64.deb\n$STD dpkg -i watchyourlan_${RELEASE}_linux_amd64.deb\nrm watchyourlan_${RELEASE}_linux_amd64.deb\nmkdir /data\ncat <<EOF >/data/config.yaml\narp_timeout: \"500\"\nauth: false\nauth_expire: 7d\nauth_password: \"\"\nauth_user: \"\"\ncolor: dark\ndbpath: /data/db.sqlite\nguiip: 0.0.0.0\nguiport: \"8840\"\nhistory_days: \"30\"\niface: eth0\nignoreip: \"no\"\nloglevel: verbose\nshoutrrr_url: \"\"\ntheme: solar\ntimeout: 60\nEOF\nmsg_ok \"Installed WatchYourLAN\"\n\nmsg_info \"Creating Service\"\nsed -i 's|/etc/watchyourlan/config.yaml|/data/config.yaml|' /lib/systemd/system/watchyourlan.service\nsystemctl enable -q --now watchyourlan.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/whisparr-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y sqlite3 \nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Whisparr\"\nmkdir -p /var/lib/whisparr/\nchmod 775 /var/lib/whisparr/\n$STD wget --content-disposition 'https://whisparr.servarr.com/v1/update/nightly/updatefile?os=linux&runtime=netcore&arch=x64'\n$STD tar -xvzf Whisparr.develop.*.tar.gz\nmv Whisparr /opt\nchmod 775 /opt/Whisparr\nmsg_ok \"Installed Whisparr\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/whisparr.service\n[Unit]\nDescription=whisparr Daemon\nAfter=syslog.target network.target\n[Service]\nUMask=0002\nType=simple\nExecStart=/opt/Whisparr/Whisparr -nobrowser -data=/var/lib/whisparr/\nTimeoutStopSec=20\nKillMode=process\nRestart=on-failure\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl -q daemon-reload\nsystemctl enable --now -q whisparr\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\nrm -rf Whisparr.develop.*.tar.gz\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/whoogle-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Updating Python3\"\n$STD apt-get install -y \\\n  python3 \\\n  python3-dev \\\n  python3-pip\nrm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED\nmsg_ok \"Updated Python3\"\n\nmsg_info \"Installing Whoogle\"\n$STD pip install brotli\n$STD pip install whoogle-search\n\nservice_path=\"/etc/systemd/system/whoogle.service\"\necho \"[Unit]\nDescription=Whoogle-Search\nAfter=network.target\n[Service]\nExecStart=/usr/local/bin/whoogle-search --host 0.0.0.0\nRestart=always\nUser=root\n[Install]\nWantedBy=multi-user.target\" >$service_path\n\n$STD systemctl enable --now whoogle.service\nmsg_ok \"Installed Whoogle\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/wikijs-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y git\n$STD apt-get install -y ca-certificates\n$STD apt-get install -y gnupg\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Setting up Node.js Repository\"\nmkdir -p /etc/apt/keyrings\ncurl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg\necho \"deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main\" >/etc/apt/sources.list.d/nodesource.list\nmsg_ok \"Set up Node.js Repository\"\n\nmsg_info \"Installing Node.js\"\n$STD apt-get update\n$STD apt-get install -y nodejs\nmsg_ok \"Installed Node.js\"\n\nmsg_info \"Installing Wiki.js\"\nmkdir -p /opt/wikijs\ncd /opt/wikijs\n$STD wget https://github.com/Requarks/wiki/releases/latest/download/wiki-js.tar.gz\ntar xzf wiki-js.tar.gz\nrm wiki-js.tar.gz\n\ncat <<EOF >/opt/wikijs/config.yml\nbindIP: 0.0.0.0\nport: 3000\ndb:\n  type: sqlite\n  storage: /opt/wikijs/db.sqlite\nlogLevel: info\nlogFormat: default\ndataPath: /opt/wikijs/data\nbodyParserLimit: 5mb\nEOF\n$STD npm rebuild sqlite3\nmsg_ok \"Installed Wiki.js\"\n\nmsg_info \"Creating Service\"\nservice_path=\"/etc/systemd/system/wikijs.service\"\n\necho \"[Unit]\nDescription=Wiki.js\nAfter=network.target\n\n[Service]\nType=simple\nExecStart=/usr/bin/node server\nRestart=always\nUser=root\nEnvironment=NODE_ENV=production\nWorkingDirectory=/opt/wikijs\n\n[Install]\nWantedBy=multi-user.target\" >$service_path\n$STD systemctl enable --now wikijs\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/wireguard-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y git\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing WireGuard\"\n$STD apt-get install -y wireguard wireguard-tools net-tools iptables\niptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE\nDEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::=\"--force-confnew\" install -y iptables-persistent &>/dev/null\n$STD netfilter-persistent reload\nmsg_ok \"Installed WireGuard\"\n\nmsg_info \"Installing WGDashboard\"\ngit clone -q https://github.com/donaldzou/WGDashboard.git /etc/wgdashboard\ncd /etc/wgdashboard/src\nchmod u+x wgd.sh\n$STD ./wgd.sh install\necho \"net.ipv4.ip_forward=1\" >>/etc/sysctl.conf\n$STD sysctl -p /etc/sysctl.conf\nmsg_ok \"Installed WGDashboard\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/wg-dashboard.service\n[Unit]\nAfter=syslog.target network-online.target\nWants=wg-quick.target\nConditionPathIsDirectory=/etc/wireguard\n\n[Service]\nType=forking\nPIDFile=/etc/wgdashboard/src/gunicorn.pid\nWorkingDirectory=/etc/wgdashboard/src\nExecStart=/etc/wgdashboard/src/wgd.sh start\nExecStop=/etc/wgdashboard/src/wgd.sh stop\nExecReload=/etc/wgdashboard/src/wgd.sh restart\nTimeoutSec=120\nPrivateTmp=yes\nRestart=always\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now wg-dashboard.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/yunohost-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y gnupg\n$STD apt-get install -y apt-transport-https\n$STD apt-get install -y lsb-release\n$STD apt-get install -y ca-certificates\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing YunoHost (Patience)\"\ntouch /etc/.pve-ignore.resolv.conf\ncurl -sSLo /usr/share/keyrings/deb.sury.org-php.gpg https://packages.sury.org/php/apt.gpg\n$STD bash <(curl -fsSL https://install.yunohost.org) -a\nmsg_ok \"Installed YunoHost\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/zabbix-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Zabbix\"\nwget -q https://repo.zabbix.com/zabbix/7.0/debian/pool/main/z/zabbix-release/zabbix-release_7.0-1+debian12_all.deb\n$STD dpkg -i zabbix-release_7.0-1+debian12_all.deb\nrm zabbix-release_7.0-1+debian12_all.deb\n$STD apt-get update\n$STD apt-get install -y zabbix-server-pgsql zabbix-frontend-php php8.2-pgsql zabbix-apache-conf zabbix-sql-scripts zabbix-agent\nmsg_ok \"Installed Zabbix\"\n\nmsg_info \"Setting up PostgreSQL\"\n$STD apt-get install -y postgresql\nDB_NAME=zabbixdb\nDB_USER=zabbix\nDB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13)\n$STD sudo -u postgres psql -c \"CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';\"\n$STD sudo -u postgres psql -c \"CREATE DATABASE $DB_NAME WITH OWNER $DB_USER ENCODING 'UTF8' TEMPLATE template0;\"\n$STD sudo -u postgres psql -c \"ALTER ROLE $DB_USER SET client_encoding TO 'utf8';\"\n$STD sudo -u postgres psql -c \"ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';\"\n$STD sudo -u postgres psql -c \"ALTER ROLE $DB_USER SET timezone TO 'UTC'\"\nzcat /usr/share/zabbix-sql-scripts/postgresql/server.sql.gz | sudo -u $DB_USER psql $DB_NAME &>/dev/null\nsed -i \"s/^DBName=.*/DBName=$DB_NAME/\" /etc/zabbix/zabbix_server.conf\nsed -i \"s/^DBUser=.*/DBUser=$DB_USER/\" /etc/zabbix/zabbix_server.conf\nsed -i \"s/^# DBPassword=.*/DBPassword=$DB_PASS/\" /etc/zabbix/zabbix_server.conf\necho \"\" >~/zabbix.creds\necho \"zabbix Database Credentials\" >>~/zabbix.creds\necho \"\" >>~/zabbix.creds\necho -e \"zabbix Database User: \\e[32m$DB_USER\\e[0m\" >>~/zabbix.creds\necho -e \"zabbix Database Password: \\e[32m$DB_PASS\\e[0m\" >>~/zabbix.creds\necho -e \"zabbix Database Name: \\e[32m$DB_NAME\\e[0m\" >>~/zabbix.creds\nmsg_ok \"Set up PostgreSQL\"\n\nmsg_info \"Starting Services\"\nsystemctl restart zabbix-server zabbix-agent apache2\nsystemctl enable -q zabbix-server zabbix-agent apache2\nmsg_ok \"Started Services\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/zigbee2mqtt-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\n$STD apt-get install -y git\n$STD apt-get install -y make\n$STD apt-get install -y g++\n$STD apt-get install -y gcc\n$STD apt-get install -y ca-certificates\n$STD apt-get install -y gnupg\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Setting up Node.js Repository\"\nmkdir -p /etc/apt/keyrings\ncurl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg\necho \"deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main\" >/etc/apt/sources.list.d/nodesource.list\nmsg_ok \"Set up Node.js Repository\"\n\nmsg_info \"Installing Node.js\"\n$STD apt-get update\n$STD apt-get install -y nodejs\nmsg_ok \"Installed Node.js\"\n\nmsg_info \"Setting up Zigbee2MQTT Repository\"\n$STD git clone --depth 1 https://github.com/Koenkk/zigbee2mqtt.git /opt/zigbee2mqtt\nmsg_ok \"Set up Zigbee2MQTT Repository\"\n\nread -r -p \"Switch to Edge/dev branch? (y/N) \" prompt\nif [[ $prompt == \"y\" ]]; then\n  DEV=\"y\"\nelse\n  DEV=\"n\"\nfi\n\nmsg_info \"Installing Zigbee2MQTT\"\ncd /opt/zigbee2mqtt\nif [[ $DEV == \"y\" ]]; then\n$STD git fetch origin dev:dev\n$STD git checkout dev\n$STD git pull\nfi\n$STD npm ci\nmsg_ok \"Installed Zigbee2MQTT\"\n\nmsg_info \"Creating Service\"\nservice_path=\"/etc/systemd/system/zigbee2mqtt.service\"\necho \"[Unit]\nDescription=zigbee2mqtt\nAfter=network.target\n[Service]\nEnvironment=NODE_ENV=production\nExecStart=/usr/bin/npm start\nWorkingDirectory=/opt/zigbee2mqtt\nStandardOutput=inherit\nStandardError=inherit\nRestart=always\nUser=root\n[Install]\nWantedBy=multi-user.target\" >$service_path\n$STD systemctl enable zigbee2mqtt.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/zipline-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck\n# Co-Author: MickLesk (Canbiz)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n# Source: https://github.com/diced/zipline\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y \\\n  postgresql \\\n  gpg \\\n  curl \\\n  sudo \\\n  mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Setting up Node.js Repository\"\nmkdir -p /etc/apt/keyrings\ncurl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg\necho \"deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main\" >/etc/apt/sources.list.d/nodesource.list\nmsg_ok \"Set up Node.js Repository\"\n\nmsg_info \"Installing Node.js\"\n$STD apt-get update\n$STD apt-get install -y nodejs\n$STD npm install -g yarn\nmsg_ok \"Installed Node.js\"\n\nmsg_info \"Setting up PostgreSQL\"\nDB_NAME=ziplinedb\nDB_USER=zipline\nDB_PASS=\"$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13)\"\nSECRET_KEY=\"$(openssl rand -base64 32 | tr -dc 'a-zA-Z0-9' | cut -c1-13)\"\n$STD sudo -u postgres psql -c \"CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';\"\n$STD sudo -u postgres psql -c \"CREATE DATABASE $DB_NAME WITH OWNER $DB_USER ENCODING 'UTF8' TEMPLATE template0;\"\n$STD sudo -u postgres psql -c \"ALTER ROLE $DB_USER SET client_encoding TO 'utf8';\"\n$STD sudo -u postgres psql -c \"ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';\"\n$STD sudo -u postgres psql -c \"ALTER ROLE $DB_USER SET timezone TO 'UTC'\"\necho \"\" >>~/zipline.creds\necho -e \"Zipline Database User: $DB_USER\" >>~/zipline.creds\necho -e \"Zipline Database Password: $DB_PASS\" >>~/zipline.creds\necho -e \"Zipline Database Name: $DB_NAME\" >>~/zipline.creds\necho -e \"Zipline Secret: $SECRET_KEY\" >>~/zipline.creds\nmsg_ok \"Set up PostgreSQL\"\n\nmsg_info \"Installing Zipline (Patience)\"\ncd /opt\nRELEASE=$(curl -s https://api.github.com/repos/diced/zipline/releases/latest | grep \"tag_name\" | awk '{print substr($2, 3, length($2)-4) }')\nwget -q \"https://github.com/diced/zipline/archive/refs/tags/v${RELEASE}.zip\"\nunzip -q v${RELEASE}.zip\nmv zipline-${RELEASE} /opt/zipline\ncd /opt/zipline\nmv .env.local.example .env\nsudo sed -i \"s|CORE_SECRET=.*|CORE_SECRET=\\\"$SECRET_KEY\\\"|\" /opt/zipline/.env\nsudo sed -i \"s|CORE_RETURN_HTTPS=.*|CORE_RETURN_HTTPS=false|\" /opt/zipline/.env\nsudo sed -i \"s|CORE_DATABASE_URL=.*|CORE_DATABASE_URL=\\\"postgres://$DB_USER:$DB_PASS@localhost:5432/$DB_NAME\\\"|\" /opt/zipline/.env\nCORE_RETURN_HTTPS=false\n$STD yarn install\n$STD yarn build\necho \"${RELEASE}\" >\"/opt/${APPLICATION}_version.txt\"\nmsg_ok \"Installed Zipline\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/zipline.service\n[Unit]\nDescription=Zipline Service\nAfter=network.target\n\n[Service]\nWorkingDirectory=/opt/zipline\nExecStart=/usr/bin/yarn start\nRestart=on-failure\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now zipline.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\""
  },
  {
    "path": "install/zoraxy-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Zoraxy (Patience)\"\nRELEASE=$(curl -s https://api.github.com/repos/tobychui/zoraxy/releases/latest  | grep \"tag_name\" | awk '{print substr($2, 2, length($2)-3) }')\nwget -q \"https://github.com/tobychui/zoraxy/releases/download/${RELEASE}/zoraxy_linux_amd64\"\nmkdir -p /opt/zoraxy\nmv zoraxy_linux_amd64 /opt/zoraxy/zoraxy\nchmod +x /opt/zoraxy/zoraxy\nln -s /opt/zoraxy/zoraxy /usr/local/bin/zoraxy\necho \"${RELEASE}\" >/opt/${APPLICATION}_version.txt\nmsg_ok \"Installed Zoraxy\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/zoraxy.service\n[Unit]\nDescription=General purpose request proxy and forwarding tool\nAfter=syslog.target network-online.target\n\n[Service]\nExecStart=/opt/zoraxy/./zoraxy\nWorkingDirectory=/opt/zoraxy/\nRestart=always\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable -q --now zoraxy.service\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "install/zwave-js-ui-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /dev/stdin <<< \"$FUNCTIONS_FILE_PATH\"\ncolor\nverb_ip6\ncatch_errors\nsetting_up_container\nnetwork_check\nupdate_os\n\nmsg_info \"Installing Dependencies\"\n$STD apt-get install -y curl\n$STD apt-get install -y sudo\n$STD apt-get install -y mc\nmsg_ok \"Installed Dependencies\"\n\nmsg_info \"Installing Z-Wave JS UI\"\nmkdir /opt/zwave-js-ui\ncd /opt/zwave-js-ui\nRELEASE=$(curl -s https://api.github.com/repos/zwave-js/zwave-js-ui/releases/latest | grep \"tag_name\" | awk '{print substr($2, 2, length($2)-3) }')\n$STD wget https://github.com/zwave-js/zwave-js-ui/releases/download/${RELEASE}/zwave-js-ui-${RELEASE}-linux.zip\n$STD unzip zwave-js-ui-${RELEASE}-linux.zip\nmsg_ok \"Installed Z-Wave JS UI\"\n\nmsg_info \"Creating Service\"\nservice_path=\"/etc/systemd/system/zwave-js-ui.service\"\necho \"[Unit]\nDescription=zwave-js-ui\nWants=network-online.target\nAfter=network-online.target\n[Service]\nUser=root\nWorkingDirectory=/opt/zwave-js-ui\nExecStart=/opt/zwave-js-ui/zwave-js-ui-linux\n[Install]\nWantedBy=multi-user.target\" >$service_path\nsystemctl start zwave-js-ui\n$STD systemctl enable zwave-js-ui\nmsg_ok \"Created Service\"\n\nmotd_ssh\ncustomize\n\nmsg_info \"Cleaning up\"\nrm zwave-js-ui-${RELEASE}-linux.zip\n$STD apt-get -y autoremove\n$STD apt-get -y autoclean\nmsg_ok \"Cleaned\"\n"
  },
  {
    "path": "misc/add-netbird-lxc.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n    _   __     __  ____  _          __\n   / | / /__  / /_/ __ )(_)________/ /\n  /  |/ / _ \\/ __/ __  / / ___/ __  /\n / /|  /  __/ /_/ /_/ / / /  / /_/ /\n/_/ |_/\\___/\\__/_____/_/_/   \\__,_/\n\nEOF\n}\nheader_info\nset -e\nwhile true; do\n  read -p \"This will add NetBird to an existing LXC Container ONLY. Proceed(y/n)?\" yn\n  case $yn in\n  [Yy]*) break ;;\n  [Nn]*) exit ;;\n  *) echo \"Please answer yes or no.\" ;;\n  esac\ndone\nheader_info\necho \"Loading...\"\nfunction msg() {\n  local TEXT=\"$1\"\n  echo -e \"$TEXT\"\n}\n\nNODE=$(hostname)\nMSG_MAX_LENGTH=0\nwhile read -r line; do\n  TAG=$(echo \"$line\" | awk '{print $1}')\n  ITEM=$(echo \"$line\" | awk '{print substr($0,36)}')\n  OFFSET=2\n  if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then\n    MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET))\n  fi\n  CTID_MENU+=(\"$TAG\" \"$ITEM \" \"OFF\")\ndone < <(pct list | awk 'NR>1')\n\nwhile [ -z \"${CTID:+x}\" ]; do\n  CTID=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"Containers on $NODE\" --radiolist \\\n    \"\\nSelect a container to add NetBird to:\\n\" \\\n    16 $(($MSG_MAX_LENGTH + 23)) 6 \\\n    \"${CTID_MENU[@]}\" 3>&1 1>&2 2>&3) || exit\ndone\n\nCTID_CONFIG_PATH=/etc/pve/lxc/${CTID}.conf\ncat <<EOF >>$CTID_CONFIG_PATH\nlxc.cgroup2.devices.allow: c 10:200 rwm\nlxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file\nEOF\nheader_info\nmsg \"Installing NetBird...\"\npct exec \"$CTID\" -- bash -c '\napt install -y ca-certificates gpg &>/dev/null\nwget -qO- https://pkgs.netbird.io/debian/public.key | gpg --dearmor >/usr/share/keyrings/netbird-archive-keyring.gpg\necho \"deb [signed-by=/usr/share/keyrings/netbird-archive-keyring.gpg] https://pkgs.netbird.io/debian stable main\" >/etc/apt/sources.list.d/netbird.list\napt-get update &>/dev/null\napt-get install -y netbird-ui &>/dev/null\n' || exit\nmsg \"\\e[1;32m ✔ Installed NetBird.\\e[0m\"\nsleep 2\nmsg \"\\e[1;31m Reboot ${CTID} LXC to apply the changes, then run netbird up in the LXC console\\e[0m\"\n"
  },
  {
    "path": "misc/add-tailscale-lxc.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n  ______      _ __                __\n /_  __/___ _(_) /_____________ _/ /__\n  / / / __ `/ / / ___/ ___/ __ `/ / _ \\\n / / / /_/ / / (__  ) /__/ /_/ / /  __/\n/_/  \\__,_/_/_/____/\\___/\\__,_/_/\\___/\n\nEOF\n}\nheader_info\nset -e\nwhile true; do\n  read -p \"This will add Tailscale to an existing LXC Container ONLY. Proceed(y/n)?\" yn\n  case $yn in\n  [Yy]*) break ;;\n  [Nn]*) exit ;;\n  *) echo \"Please answer yes or no.\" ;;\n  esac\ndone\nheader_info\necho \"Loading...\"\nfunction msg() {\n  local TEXT=\"$1\"\n  echo -e \"$TEXT\"\n}\n\nNODE=$(hostname)\nMSG_MAX_LENGTH=0\nwhile read -r line; do\n  TAG=$(echo \"$line\" | awk '{print $1}')\n  ITEM=$(echo \"$line\" | awk '{print substr($0,36)}')\n  OFFSET=2\n  if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then\n    MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET))\n  fi\n  CTID_MENU+=(\"$TAG\" \"$ITEM \" \"OFF\")\ndone < <(pct list | awk 'NR>1')\n\nwhile [ -z \"${CTID:+x}\" ]; do\n  CTID=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"Containers on $NODE\" --radiolist \\\n    \"\\nSelect a container to add Tailscale to:\\n\" \\\n    16 $(($MSG_MAX_LENGTH + 23)) 6 \\\n    \"${CTID_MENU[@]}\" 3>&1 1>&2 2>&3) || exit\ndone\n\nCTID_CONFIG_PATH=/etc/pve/lxc/${CTID}.conf\ncat <<EOF >>$CTID_CONFIG_PATH\nlxc.cgroup2.devices.allow: c 10:200 rwm\nlxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file\nEOF\nheader_info\nmsg \"Installing Tailscale...\"\npct exec \"$CTID\" -- bash -c '\nID=$(grep \"^ID=\" /etc/os-release | cut -d\"=\" -f2)\nVER=$(grep \"^VERSION_CODENAME=\" /etc/os-release | cut -d\"=\" -f2)\nwget -qO- https://pkgs.tailscale.com/stable/$ID/$VER.noarmor.gpg >/usr/share/keyrings/tailscale-archive-keyring.gpg\necho \"deb [signed-by=/usr/share/keyrings/tailscale-archive-keyring.gpg] https://pkgs.tailscale.com/stable/$ID $VER main\" >/etc/apt/sources.list.d/tailscale.list\napt-get update &>/dev/null\napt-get install -y tailscale &>/dev/null\n' || exit\nmsg \"\\e[1;32m ✔ Installed Tailscale\\e[0m\"\n\nmsg \"\\e[1;31m Reboot ${CTID} LXC to apply the changes, then run tailscale up in the LXC console\\e[0m\"\n"
  },
  {
    "path": "misc/all-templates.sh",
    "content": "#!/usr/bin/env bash\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\n  clear\n  cat <<\"EOF\"\n   ___   ____  ______               __     __\n  / _ | / / / /_  __/__ __ _  ___  / /__ _/ /____ ___\n / __ |/ / /   / / / -_)  ' \\/ _ \\/ / _ `/ __/ -_|_-<\n/_/ |_/_/_/   /_/  \\__/_/_/_/ .__/_/\\_,_/\\__/\\__/___/\n                           /_/\nEOF\n}\n\nset -eEuo pipefail\nshopt -s expand_aliases\nalias die='EXIT=$? LINE=$LINENO error_exit'\ntrap die ERR\nfunction error_exit() {\n  trap - ERR\n  local DEFAULT='Unknown failure occured.'\n  local REASON=\"\\e[97m${1:-$DEFAULT}\\e[39m\"\n  local FLAG=\"\\e[91m[ERROR] \\e[93m$EXIT@$LINE\"\n  msg \"$FLAG $REASON\" 1>&2\n  [ ! -z ${CTID-} ] && cleanup_ctid\n  exit $EXIT\n}\nfunction warn() {\n  local REASON=\"\\e[97m$1\\e[39m\"\n  local FLAG=\"\\e[93m[WARNING]\\e[39m\"\n  msg \"$FLAG $REASON\"\n}\nfunction info() {\n  local REASON=\"$1\"\n  local FLAG=\"\\e[36m[INFO]\\e[39m\"\n  msg \"$FLAG $REASON\"\n}\nfunction msg() {\n  local TEXT=\"$1\"\n  echo -e \"$TEXT\"\n}\nfunction cleanup_ctid() {\n  if pct status $CTID &>/dev/null; then\n    if [ \"$(pct status $CTID | awk '{print $2}')\" == \"running\" ]; then\n      pct stop $CTID\n    fi\n    pct destroy $CTID\n  fi\n}\n\n# Stop Proxmox VE Monitor-All if running\nif systemctl is-active -q ping-instances.service; then\n  systemctl stop ping-instances.service\nfi\nheader_info\necho \"Loading...\"\npveam update >/dev/null 2>&1\nwhiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"All Templates\" --yesno \"This will allow for the creation of one of the many Template LXC Containers. Proceed?\" 10 68 || exit\nTEMPLATE_MENU=()\nMSG_MAX_LENGTH=0\nwhile read -r TAG ITEM; do\n  OFFSET=2\n  ((${#ITEM} + OFFSET > MSG_MAX_LENGTH)) && MSG_MAX_LENGTH=${#ITEM}+OFFSET\n  TEMPLATE_MENU+=(\"$ITEM\" \"$TAG \" \"OFF\")\ndone < <(pveam available)\nTEMPLATE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"All Template LXCs\" --radiolist \"\\nSelect a Template LXC to create:\\n\" 16 $((MSG_MAX_LENGTH + 58)) 10 \"${TEMPLATE_MENU[@]}\" 3>&1 1>&2 2>&3 | tr -d '\"') || exit\n[ -z \"$TEMPLATE\" ] && {\n  whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"No Template LXC Selected\" --msgbox \"It appears that no Template LXC container was selected\" 10 68\n  msg \"Done\"\n  exit\n}\n\n# Setup script environment\nNAME=$(echo \"$TEMPLATE\" | grep -oE '^[^-]+-[^-]+')\nPASS=\"$(openssl rand -base64 8)\"\nCTID=$(pvesh get /cluster/nextid)\nPCT_OPTIONS=\"\n    -features keyctl=1,nesting=1\n    -hostname $NAME\n    -tags proxmox-helper-scripts\n    -onboot 0\n    -cores 2\n    -memory 2048\n    -password $PASS\n    -net0 name=eth0,bridge=vmbr0,ip=dhcp\n    -unprivileged 1\n  \"\nDEFAULT_PCT_OPTIONS=(\n  -arch $(dpkg --print-architecture)\n)\n\n# Set the CONTENT and CONTENT_LABEL variables\nfunction select_storage() {\n  local CLASS=$1\n  local CONTENT\n  local CONTENT_LABEL\n  case $CLASS in\n  container)\n    CONTENT='rootdir'\n    CONTENT_LABEL='Container'\n    ;;\n  template)\n    CONTENT='vztmpl'\n    CONTENT_LABEL='Container template'\n    ;;\n  *) false || die \"Invalid storage class.\" ;;\n  esac\n\n  # Query all storage locations\n  local -a MENU\n  while read -r line; do\n    local TAG=$(echo $line | awk '{print $1}')\n    local TYPE=$(echo $line | awk '{printf \"%-10s\", $2}')\n    local FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( \"%9sB\", $6)}')\n    local ITEM=\"  Type: $TYPE Free: $FREE \"\n    local OFFSET=2\n    if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then\n      local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET))\n    fi\n    MENU+=(\"$TAG\" \"$ITEM\" \"OFF\")\n  done < <(pvesm status -content $CONTENT | awk 'NR>1')\n\n  # Select storage location\n  if [ $((${#MENU[@]} / 3)) -eq 0 ]; then\n    warn \"'$CONTENT_LABEL' needs to be selected for at least one storage location.\"\n    die \"Unable to detect valid storage location.\"\n  elif [ $((${#MENU[@]} / 3)) -eq 1 ]; then\n    printf ${MENU[0]}\n  else\n    local STORAGE\n    while [ -z \"${STORAGE:+x}\" ]; do\n      STORAGE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"Storage Pools\" --radiolist \\\n        \"Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\\n\\n\" \\\n        16 $(($MSG_MAX_LENGTH + 23)) 6 \\\n        \"${MENU[@]}\" 3>&1 1>&2 2>&3) || die \"Menu aborted.\"\n    done\n    printf $STORAGE\n  fi\n}\nheader_info\n# Get template storage\nTEMPLATE_STORAGE=$(select_storage template) || exit\ninfo \"Using '$TEMPLATE_STORAGE' for template storage.\"\n\n# Get container storage\nCONTAINER_STORAGE=$(select_storage container) || exit\ninfo \"Using '$CONTAINER_STORAGE' for container storage.\"\n\n# Download template\nmsg \"Downloading LXC template (Patience)...\"\npveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || die \"A problem occured while downloading the LXC template.\"\n\n# Create variable for 'pct' options\nPCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}})\n[[ \" ${PCT_OPTIONS[@]} \" =~ \" -rootfs \" ]] || PCT_OPTIONS+=(-rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8})\n\n# Create LXC\nmsg \"Creating LXC container...\"\npct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null ||\n  die \"A problem occured while trying to create container.\"\n\n# Save password\necho \"$NAME password: ${PASS}\" >>~/$NAME.creds # file is located in the Proxmox root directory\n\n# Start container\nmsg \"Starting LXC Container...\"\npct start \"$CTID\"\nsleep 5\n\n# Get container IP\nset +eEuo pipefail\nmax_attempts=5\nattempt=1\nIP=\"\"\nwhile [[ $attempt -le $max_attempts ]]; do\n  IP=$(pct exec $CTID ip a show dev eth0 | grep -oP 'inet \\K[^/]+')\n  if [[ -n $IP ]]; then\n    break\n  else\n    warn \"Attempt $attempt: IP address not found. Pausing for 5 seconds...\"\n    sleep 5\n    ((attempt++))\n  fi\ndone\n\nif [[ -z $IP ]]; then\n  warn \"Maximum number of attempts reached. IP address not found.\"\n  IP=\"NOT FOUND\"\nfi\n\nset -eEuo pipefail\n# Start Proxmox VE Monitor-All if available\nif [[ -f /etc/systemd/system/ping-instances.service ]]; then\n  systemctl start ping-instances.service\nfi\n\n# Success message\nheader_info\necho\ninfo \"LXC container '$CTID' was successfully created, and its IP address is ${IP}.\"\necho\ninfo \"Proceed to the LXC console to complete the setup.\"\necho\ninfo \"login: root\"\ninfo \"password: $PASS\"\necho\n"
  },
  {
    "path": "misc/alpine-install.func",
    "content": "color() {\n  YW=$(echo \"\\033[33m\")\n  BL=$(echo \"\\033[36m\")\n  RD=$(echo \"\\033[01;31m\")\n  BGN=$(echo \"\\033[4;92m\")\n  GN=$(echo \"\\033[1;92m\")\n  DGN=$(echo \"\\033[32m\")\n  CL=$(echo \"\\033[m\")\n  RETRY_NUM=10\n  RETRY_EVERY=3\n  i=$RETRY_NUM\n  CM=\"${GN}✓${CL}\"\n  CROSS=\"${RD}✗${CL}\"\n  BFR=\"\\\\r\\\\033[K\"\n  HOLD=\"-\"\n}\n\nverb_ip6() {\n  if [ \"$VERBOSE\" = \"yes\" ]; then\n    STD=\"\"\n  else STD=\"silent\"; fi\n  silent() { \"$@\" >/dev/null 2>&1; }\n  if [ \"$DISABLEIPV6\" == \"yes\" ]; then\n    $STD sysctl -w net.ipv6.conf.all.disable_ipv6=1\n    echo \"net.ipv6.conf.all.disable_ipv6 = 1\" >>/etc/sysctl.conf\n    $STD rc-update add sysctl default\n  fi\n}\n\ncatch_errors() {\n  set -Eeuo pipefail\n  trap 'error_handler $LINENO \"$BASH_COMMAND\"' ERR\n}\n\nerror_handler() {\n  local exit_code=\"$?\"\n  local line_number=\"$1\"\n  local command=\"$2\"\n  local error_message=\"${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}\"\n  echo -e \"\\n$error_message\\n\"\n}\n\nmsg_info() {\n  local msg=\"$1\"\n  echo -ne \" ${HOLD} ${YW}${msg}...\"\n}\n\nmsg_ok() {\n  local msg=\"$1\"\n  echo -e \"${BFR} ${CM} ${GN}${msg}${CL}\"\n}\n\nmsg_error() {\n  local msg=\"$1\"\n  echo -e \"${BFR} ${CROSS} ${RD}${msg}${CL}\"\n}\n\nsetting_up_container() {\n  msg_info \"Setting up Container OS\"\n  while [ $i -gt 0 ]; do\n    if [ \"$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d'/' -f1)\" != \"\" ]; then\n      break\n    fi\n    echo 1>&2 -en \"${CROSS}${RD} No Network! \"\n    sleep $RETRY_EVERY\n    i=$((i - 1))\n  done\n\n  if [ \"$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d'/' -f1)\" = \"\" ]; then\n    echo 1>&2 -e \"\\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}\"\n    echo -e \" 🖧  Check Network Settings\"\n    exit 1\n  fi\n  msg_ok \"Set up Container OS\"\n  msg_ok \"Network Connected: ${BL}$(ip addr show | grep 'inet ' | awk '{print $2}' | cut -d'/' -f1 | tail -n1)${CL}\"\n}\n\nnetwork_check() {\n  set +e\n  trap - ERR\n  if ping -c 1 -W 1 1.1.1.1 &>/dev/null; then msg_ok \"Internet Connected\"; else\n    msg_error \"Internet NOT Connected\"\n    read -r -p \"Would you like to continue anyway? <y/N> \" prompt\n    if [[ \"${prompt,,}\" =~ ^(y|yes)$ ]]; then\n      echo -e \" ⚠️  ${RD}Expect Issues Without Internet${CL}\"\n    else\n      echo -e \" 🖧  Check Network Settings\"\n      exit 1\n    fi\n  fi\n  RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }')\n  if [[ -z \"$RESOLVEDIP\" ]]; then msg_error \"DNS Lookup Failure\"; else msg_ok \"DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}\"; fi\n  set -e\n  trap 'error_handler $LINENO \"$BASH_COMMAND\"' ERR\n}\n\nupdate_os() {\n  msg_info \"Updating Container OS\"\n  $STD apk update\n  $STD apk upgrade\n  msg_ok \"Updated Container OS\"\n}\n\nmotd_ssh() {\n  echo \"export TERM='xterm-256color'\" >>/root/.bashrc\n  echo -e \"$APPLICATION LXC provided by https://tteck.github.io/Proxmox/\\n\" >/etc/motd\n  if [[ \"${SSH_ROOT}\" == \"yes\" ]]; then\n    $STD rc-update add sshd\n    sed -i \"s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g\" /etc/ssh/sshd_config\n    $STD /etc/init.d/sshd start\n  fi\n}\n\ncustomize() {\n  if [[ \"$PASSWORD\" == \"\" ]]; then\n  msg_info \"Customizing Container\"\n  bash -c \"passwd -d root\" >/dev/null 2>&1\n  msg_ok \"Customized Container\"\n  fi\n}\n"
  },
  {
    "path": "misc/build.func",
    "content": "variables() {\n  NSAPP=$(echo ${APP,,} | tr -d ' ') # This function sets the NSAPP variable by converting the value of the APP variable to lowercase and removing any spaces.\n  var_install=\"${NSAPP}-install\"     # sets the var_install variable by appending \"-install\" to the value of NSAPP.\n  INTEGER='^[0-9]+([.][0-9]+)?$'     # it defines the INTEGER regular expression pattern.\n}\n\n# This function sets various color variables using ANSI escape codes for formatting text in the terminal.\ncolor() {\n  YW=$(echo \"\\033[33m\")\n  BL=$(echo \"\\033[36m\")\n  RD=$(echo \"\\033[01;31m\")\n  BGN=$(echo \"\\033[4;92m\")\n  GN=$(echo \"\\033[1;92m\")\n  DGN=$(echo \"\\033[32m\")\n  CL=$(echo \"\\033[m\")\n  CM=\"${GN}✓${CL}\"\n  CROSS=\"${RD}✗${CL}\"\n  BFR=\"\\\\r\\\\033[K\"\n  HOLD=\" \"\n}\n\n# This function enables error handling in the script by setting options and defining a trap for the ERR signal.\ncatch_errors() {\n  set -Eeuo pipefail\n  trap 'error_handler $LINENO \"$BASH_COMMAND\"' ERR\n}\n\n# This function is called when an error occurs. It receives the exit code, line number, and command that caused the error, and displays an error message.\nerror_handler() {\n  if [ -n \"$SPINNER_PID\" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi\n  printf \"\\e[?25h\"\n  local exit_code=\"$?\"\n  local line_number=\"$1\"\n  local command=\"$2\"\n  local error_message=\"${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}\"\n  echo -e \"\\n$error_message\\n\"\n}\n\n# This function displays a spinner.\nspinner() {\n    local chars=\"/-\\|\"\n    local spin_i=0\n    printf \"\\e[?25l\"\n    while true; do\n        printf \"\\r \\e[36m%s\\e[0m\" \"${chars:spin_i++%${#chars}:1}\"\n        sleep 0.1\n    done\n}\n\n# This function displays an informational message with a yellow color.\nmsg_info() {\n  local msg=\"$1\"\n  echo -ne \" ${HOLD} ${YW}${msg}   \"\n  spinner &\n  SPINNER_PID=$!\n}\n\n# This function displays a success message with a green color.\nmsg_ok() {\n  if [ -n \"$SPINNER_PID\" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi\n  printf \"\\e[?25h\"\n  local msg=\"$1\"\n  echo -e \"${BFR} ${CM} ${GN}${msg}${CL}\"\n}\n\n# This function displays a error message with a red color.\nmsg_error() {\n  if [ -n \"$SPINNER_PID\" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi\n  printf \"\\e[?25h\"\n  local msg=\"$1\"\n  echo -e \"${BFR} ${CROSS} ${RD}${msg}${CL}\"\n}\n\n# Check if the shell is using bash\nshell_check() {\n  if [[ \"$(basename \"$SHELL\")\" != \"bash\" ]]; then\n    clear\n    msg_error \"Your default shell is currently not set to Bash. To use these scripts, please switch to the Bash shell.\"\n    echo -e \"\\nExiting...\"\n    sleep 2\n    exit\n  fi\n}\n\n# Run as root only\nroot_check() {\n  if [[ \"$(id -u)\" -ne 0 || $(ps -o comm= -p $PPID) == \"sudo\" ]]; then\n    clear\n    msg_error \"Please run this script as root.\"\n    echo -e \"\\nExiting...\"\n    sleep 2\n    exit\n  fi\n}\n\n# This function checks the version of Proxmox Virtual Environment (PVE) and exits if the version is not supported.\npve_check() {\n  if ! pveversion | grep -Eq \"pve-manager/8.[1-3]\"; then\n    msg_error \"This version of Proxmox Virtual Environment is not supported\"\n    echo -e \"Requires Proxmox Virtual Environment Version 8.1 or later.\"\n    echo -e \"Exiting...\"\n    sleep 2\n    exit\nfi\n}\n\n# This function checks the system architecture and exits if it's not \"amd64\".\narch_check() {\n  if [ \"$(dpkg --print-architecture)\" != \"amd64\" ]; then\n    echo -e \"\\n ${CROSS} This script will not work with PiMox! \\n\"\n    echo -e \"\\n Visit https://github.com/asylumexp/Proxmox for ARM64 support. \\n\"\n    echo -e \"Exiting...\"\n    sleep 2\n    exit\n  fi\n}\n\n# This function checks if the script is running through SSH and prompts the user to confirm if they want to proceed or exit.\nssh_check() {\n  if command -v pveversion >/dev/null 2>&1 && [ -n \"${SSH_CLIENT:+x}\" ]; then\n    if whiptail --backtitle \"Proxmox VE Helper Scripts\" --defaultno --title \"SSH DETECTED\" --yesno \"It's advisable to utilize the Proxmox shell rather than SSH, as there may be potential complications with variable retrieval. Proceed using SSH?\" 10 72; then\n      whiptail --backtitle \"Proxmox VE Helper Scripts\" --msgbox --title \"Proceed using SSH\" \"You've chosen to proceed using SSH. If any issues arise, please run the script in the Proxmox shell before creating a repository issue.\" 10 72\n    else\n      clear\n      echo \"Exiting due to SSH usage. Please consider using the Proxmox shell.\"\n      exit\n    fi\n  fi\n}\n\n# This function displays the default values for various settings.\necho_default() {\n  echo -e \"${DGN}Using Distribution: ${BGN}$var_os${CL}\"\n  echo -e \"${DGN}Using $var_os Version: ${BGN}$var_version${CL}\"\n  echo -e \"${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}\"\n  echo -e \"${DGN}Using Root Password: ${BGN}Automatic Login${CL}\"\n  echo -e \"${DGN}Using Container ID: ${BGN}$NEXTID${CL}\"\n  echo -e \"${DGN}Using Hostname: ${BGN}$NSAPP${CL}\"\n  echo -e \"${DGN}Using Disk Size: ${BGN}$var_disk${CL}${DGN}GB${CL}\"\n  echo -e \"${DGN}Allocated Cores ${BGN}$var_cpu${CL}\"\n  echo -e \"${DGN}Allocated Ram ${BGN}$var_ram${CL}\"\n  echo -e \"${DGN}Using Bridge: ${BGN}vmbr0${CL}\"\n  echo -e \"${DGN}Using Static IP Address: ${BGN}dhcp${CL}\"\n  echo -e \"${DGN}Using Gateway IP Address: ${BGN}Default${CL}\"\n  echo -e \"${DGN}Using Apt-Cacher IP Address: ${BGN}Default${CL}\"\n  echo -e \"${DGN}Disable IPv6: ${BGN}No${CL}\"\n  echo -e \"${DGN}Using Interface MTU Size: ${BGN}Default${CL}\"\n  echo -e \"${DGN}Using DNS Search Domain: ${BGN}Host${CL}\"\n  echo -e \"${DGN}Using DNS Server Address: ${BGN}Host${CL}\"\n  echo -e \"${DGN}Using MAC Address: ${BGN}Default${CL}\"\n  echo -e \"${DGN}Using VLAN Tag: ${BGN}Default${CL}\"\n  echo -e \"${DGN}Enable Root SSH Access: ${BGN}No${CL}\"\n  echo -e \"${DGN}Enable Verbose Mode: ${BGN}No${CL}\"\n  echo -e \"${BL}Creating a ${APP} LXC using the above default settings${CL}\"\n}\n\n# This function is called when the user decides to exit the script. It clears the screen and displays an exit message.\nexit-script() {\n  clear\n  echo -e \"⚠  User exited script \\n\"\n  exit\n}\n\n# This function allows the user to configure advanced settings for the script.\nadvanced_settings() {\n  whiptail --backtitle \"Proxmox VE Helper Scripts\" --msgbox --title \"Here is an instructional tip:\" \"To make a selection, use the Spacebar.\" 8 58\n  whiptail --backtitle \"Proxmox VE Helper Scripts\" --msgbox --title \"Default distribution for $APP\" \"${var_os} ${var_version} \\n \\nIf the default Linux distribution is not adhered to, script support will be discontinued. \\n\" 10 58\n  if [ \"$var_os\" != \"alpine\" ]; then\n    var_os=\"\"\n    while [ -z \"$var_os\" ]; do\n      if var_os=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"DISTRIBUTION\" --radiolist \"Choose Distribution:\" 10 58 2 \\\n        \"debian\" \"\" OFF \\\n        \"ubuntu\" \"\" OFF \\\n        3>&1 1>&2 2>&3); then\n        if [ -n \"$var_os\" ]; then\n          echo -e \"${DGN}Using Distribution: ${BGN}$var_os${CL}\"\n        fi\n      else\n        exit-script\n      fi\n    done\n  fi\n\n  if [ \"$var_os\" == \"debian\" ]; then\n    var_version=\"\"\n    while [ -z \"$var_version\" ]; do\n      if var_version=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"DEBIAN VERSION\" --radiolist \"Choose Version\" 10 58 2 \\\n        \"11\" \"Bullseye\" OFF \\\n        \"12\" \"Bookworm\" OFF \\\n        3>&1 1>&2 2>&3); then\n        if [ -n \"$var_version\" ]; then\n          echo -e \"${DGN}Using $var_os Version: ${BGN}$var_version${CL}\"\n        fi\n      else\n        exit-script\n      fi\n    done\n  fi\n\n  if [ \"$var_os\" == \"ubuntu\" ]; then\n    var_version=\"\"\n    while [ -z \"$var_version\" ]; do\n      if var_version=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"UBUNTU VERSION\" --radiolist \"Choose Version\" 10 58 3 \\\n        \"20.04\" \"Focal\" OFF \\\n        \"22.04\" \"Jammy\" OFF \\\n        \"24.04\" \"Noble\" OFF \\\n        3>&1 1>&2 2>&3); then\n        if [ -n \"$var_version\" ]; then\n          echo -e \"${DGN}Using $var_os Version: ${BGN}$var_version${CL}\"\n        fi\n      else\n        exit-script\n      fi\n    done\n  fi\n\n  CT_TYPE=\"\"\n  while [ -z \"$CT_TYPE\" ]; do\n    if CT_TYPE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"CONTAINER TYPE\" --radiolist \"Choose Type\" 10 58 2 \\\n      \"1\" \"Unprivileged\" OFF \\\n      \"0\" \"Privileged\" OFF \\\n      3>&1 1>&2 2>&3); then\n      if [ -n \"$CT_TYPE\" ]; then\n        echo -e \"${DGN}Using Container Type: ${BGN}$CT_TYPE${CL}\"\n      fi\n    else\n      exit-script\n    fi\n  done\n\n  while true; do\n    if PW1=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --passwordbox \"\\nSet Root Password (needed for root ssh access)\" 9 58 --title \"PASSWORD (leave blank for automatic login)\" 3>&1 1>&2 2>&3); then\n      if [[ ! -z \"$PW1\" ]]; then\n        if [[ \"$PW1\" == *\" \"* ]]; then\n          whiptail --msgbox \"Password cannot contain spaces. Please try again.\" 8 58\n        elif [ ${#PW1} -lt 5 ]; then\n          whiptail --msgbox \"Password must be at least 5 characters long. Please try again.\" 8 58\n        else\n          if PW2=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --passwordbox \"\\nVerify Root Password\" 9 58 --title \"PASSWORD VERIFICATION\" 3>&1 1>&2 2>&3); then\n            if [[ \"$PW1\" == \"$PW2\" ]]; then\n              PW=\"-password $PW1\"\n              echo -e \"${DGN}Using Root Password: ${BGN}********${CL}\"\n              break\n            else\n              whiptail --msgbox \"Passwords do not match. Please try again.\" 8 58\n            fi\n          else\n            exit-script\n          fi\n        fi\n      else\n        PW1=\"Automatic Login\"\n        PW=\"\"\n        echo -e \"${DGN}Using Root Password: ${BGN}$PW1${CL}\"\n        break\n      fi\n    else\n      exit-script\n    fi\n  done\n\n\n  if CT_ID=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set Container ID\" 8 58 $NEXTID --title \"CONTAINER ID\" 3>&1 1>&2 2>&3); then\n    if [ -z \"$CT_ID\" ]; then\n      CT_ID=\"$NEXTID\"\n      echo -e \"${DGN}Using Container ID: ${BGN}$CT_ID${CL}\"\n    else\n      echo -e \"${DGN}Container ID: ${BGN}$CT_ID${CL}\"\n    fi\n  else\n    exit\n  fi\n\n  if CT_NAME=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set Hostname\" 8 58 $NSAPP --title \"HOSTNAME\" 3>&1 1>&2 2>&3); then\n    if [ -z \"$CT_NAME\" ]; then\n      HN=\"$NSAPP\"\n    else\n      HN=$(echo ${CT_NAME,,} | tr -d ' ')\n    fi\n    echo -e \"${DGN}Using Hostname: ${BGN}$HN${CL}\"\n  else\n    exit-script\n  fi\n\n  if DISK_SIZE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set Disk Size in GB\" 8 58 $var_disk --title \"DISK SIZE\" 3>&1 1>&2 2>&3); then\n    if [ -z \"$DISK_SIZE\" ]; then\n      DISK_SIZE=\"$var_disk\"\n      echo -e \"${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}\"\n    else\n      if ! [[ $DISK_SIZE =~ $INTEGER ]]; then\n        echo -e \"${RD}⚠ DISK SIZE MUST BE AN INTEGER NUMBER!${CL}\"\n        advanced_settings\n      fi\n      echo -e \"${DGN}Using Disk Size: ${BGN}$DISK_SIZE${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  if CORE_COUNT=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Allocate CPU Cores\" 8 58 $var_cpu --title \"CORE COUNT\" 3>&1 1>&2 2>&3); then\n    if [ -z \"$CORE_COUNT\" ]; then\n      CORE_COUNT=\"$var_cpu\"\n      echo -e \"${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}\"\n    else\n      echo -e \"${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  if RAM_SIZE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Allocate RAM in MiB\" 8 58 $var_ram --title \"RAM\" 3>&1 1>&2 2>&3); then\n    if [ -z \"$RAM_SIZE\" ]; then\n      RAM_SIZE=\"$var_ram\"\n      echo -e \"${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}\"\n    else\n      echo -e \"${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  if BRG=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set a Bridge\" 8 58 vmbr0 --title \"BRIDGE\" 3>&1 1>&2 2>&3); then\n    if [ -z \"$BRG\" ]; then\n      BRG=\"vmbr0\"\n      echo -e \"${DGN}Using Bridge: ${BGN}$BRG${CL}\"\n    else\n      echo -e \"${DGN}Using Bridge: ${BGN}$BRG${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  while true; do\n    NET=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set a Static IPv4 CIDR Address (/24)\" 8 58 dhcp --title \"IP ADDRESS\" 3>&1 1>&2 2>&3)\n    exit_status=$?\n    if [ $exit_status -eq 0 ]; then\n      if [ \"$NET\" = \"dhcp\" ]; then\n        echo -e \"${DGN}Using IP Address: ${BGN}$NET${CL}\"\n        break\n      else\n        if [[ \"$NET\" =~ ^([0-9]{1,3}\\.){3}[0-9]{1,3}/([0-9]|[1-2][0-9]|3[0-2])$ ]]; then\n          echo -e \"${DGN}Using IP Address: ${BGN}$NET${CL}\"\n          break\n        else\n          whiptail --backtitle \"Proxmox VE Helper Scripts\" --msgbox \"$NET is an invalid IPv4 CIDR address. Please enter a valid IPv4 CIDR address or 'dhcp'\" 8 58\n        fi\n      fi\n    else\n      exit-script\n    fi\n  done\n\n  if [ \"$NET\" != \"dhcp\" ]; then\n    while true; do\n      GATE1=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Enter gateway IP address\" 8 58 --title \"Gateway IP\" 3>&1 1>&2 2>&3)\n      if [ -z \"$GATE1\" ]; then\n        whiptail --backtitle \"Proxmox VE Helper Scripts\" --msgbox \"Gateway IP address cannot be empty\" 8 58\n      elif [[ ! \"$GATE1\" =~ ^([0-9]{1,3}\\.){3}[0-9]{1,3}$ ]]; then\n        whiptail --backtitle \"Proxmox VE Helper Scripts\" --msgbox \"Invalid IP address format\" 8 58\n      else\n        GATE=\",gw=$GATE1\"\n        echo -e \"${DGN}Using Gateway IP Address: ${BGN}$GATE1${CL}\"\n        break\n      fi\n    done\n  else\n    GATE=\"\"\n    echo -e \"${DGN}Using Gateway IP Address: ${BGN}Default${CL}\"\n  fi\n\n  if [ \"$var_os\" == \"alpine\" ]; then\n    APT_CACHER=\"\"\n    APT_CACHER_IP=\"\"\n  else\n    if APT_CACHER_IP=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set APT-Cacher IP (leave blank for default)\" 8 58 --title \"APT-Cacher IP\" 3>&1 1>&2 2>&3); then\n      APT_CACHER=\"${APT_CACHER_IP:+yes}\"\n      echo -e \"${DGN}Using APT-Cacher IP Address: ${BGN}${APT_CACHER_IP:-Default}${CL}\"\n    else\n      exit-script\n    fi\n  fi\n\n  if (whiptail --backtitle \"Proxmox VE Helper Scripts\" --defaultno --title \"IPv6\" --yesno \"Disable IPv6?\" 10 58); then\n    DISABLEIP6=\"yes\"\n  else\n    DISABLEIP6=\"no\"\n  fi\n  echo -e \"${DGN}Disable IPv6: ${BGN}$DISABLEIP6${CL}\"\n\n  if MTU1=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set Interface MTU Size (leave blank for default)\" 8 58 --title \"MTU SIZE\" 3>&1 1>&2 2>&3); then\n    if [ -z $MTU1 ]; then\n      MTU1=\"Default\"\n      MTU=\"\"\n    else\n      MTU=\",mtu=$MTU1\"\n    fi\n    echo -e \"${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}\"\n  else\n    exit-script\n  fi\n\n  if SD=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set a DNS Search Domain (leave blank for HOST)\" 8 58 --title \"DNS Search Domain\" 3>&1 1>&2 2>&3); then\n    if [ -z $SD ]; then\n      SX=Host\n      SD=\"\"\n    else\n      SX=$SD\n      SD=\"-searchdomain=$SD\"\n    fi\n    echo -e \"${DGN}Using DNS Search Domain: ${BGN}$SX${CL}\"\n  else\n    exit-script\n  fi\n\n  if NX=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set a DNS Server IP (leave blank for HOST)\" 8 58 --title \"DNS SERVER IP\" 3>&1 1>&2 2>&3); then\n    if [ -z $NX ]; then\n      NX=Host\n      NS=\"\"\n    else\n      NS=\"-nameserver=$NX\"\n    fi\n    echo -e \"${DGN}Using DNS Server IP Address: ${BGN}$NX${CL}\"\n  else\n    exit-script\n  fi\n\n  if MAC1=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set a MAC Address(leave blank for default)\" 8 58 --title \"MAC ADDRESS\" 3>&1 1>&2 2>&3); then\n    if [ -z $MAC1 ]; then\n      MAC1=\"Default\"\n      MAC=\"\"\n    else\n      MAC=\",hwaddr=$MAC1\"\n      echo -e \"${DGN}Using MAC Address: ${BGN}$MAC1${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  if VLAN1=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set a Vlan(leave blank for default)\" 8 58 --title \"VLAN\" 3>&1 1>&2 2>&3); then\n    if [ -z $VLAN1 ]; then\n      VLAN1=\"Default\"\n      VLAN=\"\"\n    else\n      VLAN=\",tag=$VLAN1\"\n    fi\n    echo -e \"${DGN}Using Vlan: ${BGN}$VLAN1${CL}\"\n  else\n    exit-script\n  fi\n\n  if [[ \"$PW\" == -password* ]]; then\n    if (whiptail --backtitle \"Proxmox VE Helper Scripts\" --defaultno --title \"SSH ACCESS\" --yesno \"Enable Root SSH Access?\" 10 58); then\n      SSH=\"yes\"\n    else\n      SSH=\"no\"\n    fi\n    echo -e \"${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}\"\n  else\n    SSH=\"no\"\n    echo -e \"${DGN}Enable Root SSH Access: ${BGN}$SSH${CL}\"\n  fi\n\n  if (whiptail --backtitle \"Proxmox VE Helper Scripts\" --defaultno --title \"VERBOSE MODE\" --yesno \"Enable Verbose Mode?\" 10 58); then\n    VERB=\"yes\"\n  else\n    VERB=\"no\"\n  fi\n  echo -e \"${DGN}Enable Verbose Mode: ${BGN}$VERB${CL}\"\n\n  if (whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"ADVANCED SETTINGS COMPLETE\" --yesno \"Ready to create ${APP} LXC?\" 10 58); then\n    echo -e \"${RD}Creating a ${APP} LXC using the above advanced settings${CL}\"\n  else\n    clear\n    header_info\n    echo -e \"${RD}Using Advanced Settings${CL}\"\n    advanced_settings\n  fi\n}\n\ninstall_script() {\n  pve_check\n  shell_check\n  root_check\n  arch_check\n  ssh_check\n\n  if systemctl is-active -q ping-instances.service; then\n    systemctl -q stop ping-instances.service\n  fi\n  NEXTID=$(pvesh get /cluster/nextid)\n  timezone=$(cat /etc/timezone)\n  header_info\n  if (whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"SETTINGS\" --yesno \"Use Default Settings?\" --no-button Advanced 10 58); then\n    header_info\n    echo -e \"${BL}Using Default Settings${CL}\"\n    default_settings\n  else\n    header_info\n    echo -e \"${RD}Using Advanced Settings${CL}\"\n    advanced_settings\n  fi\n}\n\nstart() {\n  if command -v pveversion >/dev/null 2>&1; then\n    if ! (whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"${APP} LXC\" --yesno \"This will create a New ${APP} LXC. Proceed?\" 10 58); then\n      clear\n      echo -e \"⚠  User exited script \\n\"\n      exit\n    fi\n    SPINNER_PID=\"\"\n    install_script\n  fi\n\n  if ! command -v pveversion >/dev/null 2>&1; then\n    if ! (whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"${APP} LXC UPDATE\" --yesno \"Support/Update functions for ${APP} LXC.  Proceed?\" 10 58); then\n      clear\n      echo -e \"⚠  User exited script \\n\"\n      exit\n    fi\n    SPINNER_PID=\"\"\n    update_script\n  fi\n}\n\n# This function collects user settings and integrates all the collected information.\nbuild_container() {\n#  if [ \"$VERB\" == \"yes\" ]; then set -x; fi\n\n  if [ \"$CT_TYPE\" == \"1\" ]; then\n    FEATURES=\"keyctl=1,nesting=1\"\n  else\n    FEATURES=\"nesting=1\"\n  fi\n\n\n  TEMP_DIR=$(mktemp -d)\n  pushd $TEMP_DIR >/dev/null\n  if [ \"$var_os\" == \"alpine\" ]; then\n    export FUNCTIONS_FILE_PATH=\"$(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/alpine-install.func)\"\n  else\n    export FUNCTIONS_FILE_PATH=\"$(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/install.func)\"\n  fi\n  export CACHER=\"$APT_CACHER\"\n  export CACHER_IP=\"$APT_CACHER_IP\"\n  export tz=\"$timezone\"\n  export DISABLEIPV6=\"$DISABLEIP6\"\n  export APPLICATION=\"$APP\"\n  export app=\"$NSAPP\"\n  export PASSWORD=\"$PW\"\n  export VERBOSE=\"$VERB\"\n  export SSH_ROOT=\"${SSH}\"\n  export CTID=\"$CT_ID\"\n  export CTTYPE=\"$CT_TYPE\"\n  export PCT_OSTYPE=\"$var_os\"\n  export PCT_OSVERSION=\"$var_version\"\n  export PCT_DISK_SIZE=\"$DISK_SIZE\"\n  export PCT_OPTIONS=\"\n    -features $FEATURES\n    -hostname $HN\n    -tags proxmox-helper-scripts\n    $SD\n    $NS\n    -net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU\n    -onboot 1\n    -cores $CORE_COUNT\n    -memory $RAM_SIZE\n    -unprivileged $CT_TYPE\n    $PW\n  \"\n  # This executes create_lxc.sh and creates the container and .conf file\n  bash -c \"$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/ct/create_lxc.sh)\" || exit\n\n  LXC_CONFIG=/etc/pve/lxc/${CTID}.conf\n  if [ \"$CT_TYPE\" == \"0\" ]; then\n    cat <<EOF >>$LXC_CONFIG\n# USB passthrough\nlxc.cgroup2.devices.allow: a\nlxc.cap.drop:\nlxc.cgroup2.devices.allow: c 188:* rwm\nlxc.cgroup2.devices.allow: c 189:* rwm\nlxc.mount.entry: /dev/serial/by-id  dev/serial/by-id  none bind,optional,create=dir\nlxc.mount.entry: /dev/ttyUSB0       dev/ttyUSB0       none bind,optional,create=file\nlxc.mount.entry: /dev/ttyUSB1       dev/ttyUSB1       none bind,optional,create=file\nlxc.mount.entry: /dev/ttyACM0       dev/ttyACM0       none bind,optional,create=file\nlxc.mount.entry: /dev/ttyACM1       dev/ttyACM1       none bind,optional,create=file\nEOF\n  fi\n\n  if [ \"$CT_TYPE\" == \"0\" ]; then\n    if [[ \"$APP\" == \"Channels\" || \"$APP\" == \"Emby\" || \"$APP\" == \"ErsatzTV\" || \"$APP\" == \"Frigate\" || \"$APP\" == \"Jellyfin\" || \"$APP\" == \"Plex\" || \"$APP\" == \"Scrypted\" || \"$APP\" == \"Tdarr\" || \"$APP\" == \"Unmanic\" || \"$APP\" == \"Ollama\" ]]; then\n      cat <<EOF >>$LXC_CONFIG\n# VAAPI hardware transcoding\nlxc.cgroup2.devices.allow: c 226:0 rwm\nlxc.cgroup2.devices.allow: c 226:128 rwm\nlxc.cgroup2.devices.allow: c 29:0 rwm\nlxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file\nlxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir\nlxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file\nEOF\n    fi\n  else\n    if [[ \"$APP\" == \"Channels\" || \"$APP\" == \"Emby\" || \"$APP\" == \"ErsatzTV\" || \"$APP\" == \"Frigate\" || \"$APP\" == \"Jellyfin\" || \"$APP\" == \"Plex\" || \"$APP\" == \"Scrypted\" || \"$APP\" == \"Tdarr\" || \"$APP\" == \"Unmanic\" || \"$APP\" == \"Ollama\" ]]; then\n      if [[ -e \"/dev/dri/renderD128\" ]]; then\n        if [[ -e \"/dev/dri/card0\" ]]; then\n          cat <<EOF >>$LXC_CONFIG\n# VAAPI hardware transcoding\ndev0: /dev/dri/card0,gid=44\ndev1: /dev/dri/renderD128,gid=104\nEOF\n        else\n          cat <<EOF >>$LXC_CONFIG\n# VAAPI hardware transcoding\ndev0: /dev/dri/card1,gid=44\ndev1: /dev/dri/renderD128,gid=104\nEOF\n        fi\n      fi\n    fi\n  fi\n\n  # This starts the container and executes <app>-install.sh\n  msg_info \"Starting LXC Container\"\n  pct start \"$CTID\"\n  msg_ok \"Started LXC Container\"\n  if [ \"$var_os\" == \"alpine\" ]; then\n    sleep 3\n        pct exec \"$CTID\" -- /bin/sh -c 'cat <<EOF >/etc/apk/repositories\nhttp://dl-cdn.alpinelinux.org/alpine/latest-stable/main\nhttp://dl-cdn.alpinelinux.org/alpine/latest-stable/community\n#http://dl-cdn.alpinelinux.org/alpine/v3.19/main\n#http://dl-cdn.alpinelinux.org/alpine/v3.19/community\nEOF'\n    pct exec \"$CTID\" -- ash -c \"apk add bash >/dev/null\"\n  fi\n  lxc-attach -n \"$CTID\" -- bash -c \"$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/install/$var_install.sh)\" || exit\n\n}\n\n# This function sets the description of the container.\ndescription() {\n  IP=$(pct exec \"$CTID\" ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1)\n  pct set \"$CTID\" -description \"<div align='center'><a href='https://Helper-Scripts.com' target='_blank' rel='noopener noreferrer'><img src='https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/logo-81x112.png'/></a>\n\n  # ${APP} LXC\n\n  <a href='https://ko-fi.com/proxmoxhelperscripts'><img src='https://img.shields.io/badge/&#x2615;-Buy me a coffee-blue' /></a>\n  </div>\"\n  if [[ -f /etc/systemd/system/ping-instances.service ]]; then\n    systemctl start ping-instances.service\n  fi\n}\n"
  },
  {
    "path": "misc/clean-lxcs.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info() {\n  clear\n  cat <<\"EOF\"\n   ________                    __   _  ________\n  / ____/ /__  ____ _____     / /  | |/ / ____/\n / /   / / _ \\/ __ `/ __ \\   / /   |   / /\n/ /___/ /  __/ /_/ / / / /  / /___/   / /___\n\\____/_/\\___/\\__,_/_/ /_/  /_____/_/|_\\____/\n\nEOF\n}\nBL=$(echo \"\\033[36m\")\nRD=$(echo \"\\033[01;31m\")\nCM='\\xE2\\x9C\\x94\\033'\nGN=$(echo \"\\033[1;92m\")\nCL=$(echo \"\\033[m\")\nheader_info\necho \"Loading...\"\nwhiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"Proxmox VE LXC Updater\" --yesno \"This Will Clean logs, cache and update apt lists on selected LXC Containers. Proceed?\" 10 58 || exit\nNODE=$(hostname)\nEXCLUDE_MENU=()\nMSG_MAX_LENGTH=0\nwhile read -r TAG ITEM; do\n  OFFSET=2\n  ((${#ITEM} + OFFSET > MSG_MAX_LENGTH)) && MSG_MAX_LENGTH=${#ITEM}+OFFSET\n  EXCLUDE_MENU+=(\"$TAG\" \"$ITEM \" \"OFF\")\ndone < <(pct list | awk 'NR>1')\nexcluded_containers=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"Containers on $NODE\" --checklist \"\\nSelect containers to skip from cleaning:\\n\" \\\n  16 $((MSG_MAX_LENGTH + 23)) 6 \"${EXCLUDE_MENU[@]}\" 3>&1 1>&2 2>&3 | tr -d '\"') || exit  \n\nfunction clean_container() {\n  container=$1\n  header_info\n  name=$(pct exec \"$container\" hostname)\n  echo -e \"${BL}[Info]${GN} Cleaning ${name} ${CL} \\n\"\n  pct exec $container -- bash -c \"apt-get -y --purge autoremove && apt-get -y autoclean && bash <(curl -fsSL https://github.com/tteck/Proxmox/raw/main/misc/clean.sh) && rm -rf /var/lib/apt/lists/* && apt-get update\"\n}\nfor container in $(pct list | awk '{if(NR>1) print $1}'); do\n  if [[ \" ${excluded_containers[@]} \" =~ \" $container \" ]]; then\n    header_info\n    echo -e \"${BL}[Info]${GN} Skipping ${BL}$container${CL}\"\n    sleep 1\n  else\n    os=$(pct config \"$container\" | awk '/^ostype/ {print $2}')\n    if [ \"$os\" != \"debian\" ] && [ \"$os\" != \"ubuntu\" ]; then\n      header_info\n      echo -e \"${BL}[Info]${GN} Skipping ${name} ${RD}$container is not Debian or Ubuntu ${CL} \\n\"\n      sleep 1\n      continue\n    fi\n\n    status=$(pct status $container)\n    template=$(pct config $container | grep -q \"template:\" && echo \"true\" || echo \"false\")\n    if [ \"$template\" == \"false\" ] && [ \"$status\" == \"status: stopped\" ]; then\n      echo -e \"${BL}[Info]${GN} Starting${BL} $container ${CL} \\n\"\n      pct start $container\n      echo -e \"${BL}[Info]${GN} Waiting For${BL} $container${CL}${GN} To Start ${CL} \\n\"\n      sleep 5\n      clean_container $container\n      echo -e \"${BL}[Info]${GN} Shutting down${BL} $container ${CL} \\n\"\n      pct shutdown $container &\n    elif [ \"$status\" == \"status: running\" ]; then\n      clean_container $container\n    fi\n  fi\ndone\n\nwait\nheader_info\necho -e \"${GN} Finished, Selected Containers Cleaned. ${CL} \\n\"\n"
  },
  {
    "path": "misc/clean.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info() {\n  clear\n  cat <<\"EOF\"\n   ________                    __   _  ________\n  / ____/ /__  ____ _____     / /  | |/ / ____/\n / /   / / _ \\/ __ `/ __ \\   / /   |   / /\n/ /___/ /  __/ /_/ / / / /  / /___/   / /___\n\\____/_/\\___/\\__,_/_/ /_/  /_____/_/|_\\____/\n\nEOF\n}\nBL=$(echo \"\\033[36m\")\nGN=$(echo \"\\033[1;92m\")\nCL=$(echo \"\\033[m\")\nname=$(hostname)\nheader_info\necho -e \"${BL}[Info]${GN} Cleaning $name${CL} \\n\"\ncache=$(find /var/cache/ -type f)\nif [[ -z \"$cache\" ]]; then\n  echo -e \"It appears there are no cached files on your system. \\n\"\n  sleep 2\nelse\n  find /var/cache -type f -delete\n  echo \"Successfully Removed Cache\"\n  sleep 2\nfi\nheader_info\necho -e \"${BL}[Info]${GN} Cleaning $name${CL} \\n\"\nlogs=$(find /var/log/ -type f)\nif [[ -z \"$logs\" ]]; then\n  echo -e \"It appears there are no logs on your system. \\n\"\n  sleep 2\nelse\n  find /var/log -type f -delete\n  echo \"Successfully Removed Logs\"\n  sleep 2\nfi\nheader_info\necho -e \"${BL}[Info]${GN} Cleaning $name${CL} \\n\"\necho -e \"${GN}Populating apt lists${CL} \\n\"\n"
  },
  {
    "path": "misc/code-server.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\n    cat <<\"EOF\"\n   ______          __        _____                          \n  / ____/___  ____/ /__     / ___/___  ______   _____  _____\n / /   / __ \\/ __  / _ \\    \\__ \\/ _ \\/ ___/ | / / _ \\/ ___/\n/ /___/ /_/ / /_/ /  __/   ___/ /  __/ /   | |/ /  __/ /    \n\\____/\\____/\\__,_/\\___/   /____/\\___/_/    |___/\\___/_/     \n \nEOF\n}\nIP=$(hostname -I | awk '{print $1}')\nYW=$(echo \"\\033[33m\")\nBL=$(echo \"\\033[36m\")\nRD=$(echo \"\\033[01;31m\")\nBGN=$(echo \"\\033[4;92m\")\nGN=$(echo \"\\033[1;92m\")\nDGN=$(echo \"\\033[32m\")\nCL=$(echo \"\\033[m\")\nBFR=\"\\\\r\\\\033[K\"\nHOLD=\"-\"\nCM=\"${GN}✓${CL}\"\nAPP=\"Code Server\"\nhostname=\"$(hostname)\"\nset -o errexit\nset -o errtrace\nset -o nounset\nset -o pipefail\nshopt -s expand_aliases\nalias die='EXIT=$? LINE=$LINENO error_exit'\ntrap die ERR\n\nfunction error_exit() {\n    trap - ERR\n    local reason=\"Unknown failure occured.\"\n    local msg=\"${1:-$reason}\"\n    local flag=\"${RD}‼ ERROR ${CL}$EXIT@$LINE\"\n    echo -e \"$flag $msg\" 1>&2\n    exit $EXIT\n}\nclear\nheader_info\nif command -v pveversion >/dev/null 2>&1; then echo -e \"⚠️  Can't Install on Proxmox \"; exit; fi\nif [ -e /etc/alpine-release ]; then echo -e \"⚠️  Can't Install on Alpine\"; exit; fi\nwhile true; do\n    read -p \"This will Install ${APP} on $hostname. Proceed(y/n)?\" yn\n    case $yn in\n    [Yy]*) break ;;\n    [Nn]*) exit ;;\n    *) echo \"Please answer yes or no.\" ;;\n    esac\ndone\n\nfunction msg_info() {\n    local msg=\"$1\"\n    echo -ne \" ${HOLD} ${YW}${msg}...\"\n}\n\nfunction msg_ok() {\n    local msg=\"$1\"\n    echo -e \"${BFR} ${CM} ${GN}${msg}${CL}\"\n}\n\nmsg_info \"Installing Dependencies\"\napt-get update &>/dev/null\napt-get install -y curl &>/dev/null\napt-get install -y git &>/dev/null\nmsg_ok \"Installed Dependencies\"\n\nVERSION=$(curl -s https://api.github.com/repos/coder/code-server/releases/latest |\n    grep \"tag_name\" |\n    awk '{print substr($2, 3, length($2)-4) }')\n\nmsg_info \"Installing Code-Server v${VERSION}\"\ncurl -fOL https://github.com/coder/code-server/releases/download/v$VERSION/code-server_${VERSION}_amd64.deb &>/dev/null\ndpkg -i code-server_${VERSION}_amd64.deb &>/dev/null\nrm -rf code-server_${VERSION}_amd64.deb\nmkdir -p ~/.config/code-server/\nsystemctl enable -q --now code-server@$USER\ncat <<EOF >~/.config/code-server/config.yaml\nbind-addr: 0.0.0.0:8680\nauth: none\npassword: \ncert: false\nEOF\nsystemctl restart code-server@$USER\nmsg_ok \"Installed Code-Server v${VERSION} on $hostname\"\n\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://$IP:8680${CL} \\n\"\n"
  },
  {
    "path": "misc/container-restore-from-backup.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nclear\nif command -v pveversion >/dev/null 2>&1; then echo -e \"⚠️  Can't Run from the Proxmox Shell\"; exit; fi\nYW=$(echo \"\\033[33m\")\nBL=$(echo \"\\033[36m\")\nRD=$(echo \"\\033[01;31m\")\nBGN=$(echo \"\\033[4;92m\")\nGN=$(echo \"\\033[1;92m\")\nDGN=$(echo \"\\033[32m\")\nCL=$(echo \"\\033[m\")\nBFR=\"\\\\r\\\\033[K\"\nHOLD=\"-\"\nCM=\"${GN}✓${CL}\"\nCROSS=\"${RD}✗${CL}\"\nAPP=\"Home Assistant Container\"\nwhile true; do\n    read -p \"This will restore ${APP} from a backup. Proceed(y/n)?\" yn\n    case $yn in\n    [Yy]*) break ;;\n    [Nn]*) exit ;;\n    *) echo \"Please answer yes or no.\" ;;\n    esac\ndone\nclear\nfunction header_info {\n    cat <<\"EOF\"\n    __  __                        ___              _      __              __              \n   / / / /___  ____ ___  ___     /   |  __________(_)____/ /_____ _____  / /_   \n  / /_/ / __ \\/ __ `__ \\/ _ \\   / /| | / ___/ ___/ / ___/ __/ __ `/ __ \\/ __/  \n / __  / /_/ / / / / / /  __/  / ___ |(__  |__  ) (__  ) /_/ /_/ / / / / /_   \n/_/ /_/\\____/_/ /_/ /_/\\___/  /_/  |_/____/____/_/____/\\__/\\__,_/_/ /_/\\__/   \n                        RESTORE FROM BACKUP                                \nEOF\n}\n\nheader_info\n\nfunction msg_info() {\n    local msg=\"$1\"\n    echo -ne \" ${HOLD} ${YW}${msg}...\"\n}\nfunction msg_ok() {\n    local msg=\"$1\"\n    echo -e \"${BFR} ${CM} ${GN}${msg}${CL}\"\n}\nfunction msg_error() {\n    local msg=\"$1\"\n    echo -e \"${BFR} ${CROSS} ${RD}${msg}${CL}\"\n}\nif [ -z \"$(ls -A /var/lib/docker/volumes/hass_config/_data/backups/)\" ]; then\n    msg_error \"No backups found! \\n\"\n    exit 1\nfi\nDIR=/var/lib/docker/volumes/hass_config/_data/restore\nif [ -d \"$DIR\" ]; then\n    msg_ok \"Restore Directory Exists.\"\nelse\n    mkdir -p /var/lib/docker/volumes/hass_config/_data/restore\n    msg_ok \"Created Restore Directory.\"\nfi\ncd /var/lib/docker/volumes/hass_config/_data/backups/\nPS3=\"Please enter your choice: \"\nfiles=\"$(ls -A .)\"\nselect filename in ${files}; do\n    msg_ok \"You selected ${BL}${filename}${CL}\"\n    break\ndone\nmsg_info \"Stopping Home Assistant\"\ndocker stop homeassistant &>/dev/null\nmsg_ok \"Stopped Home Assistant\"\nmsg_info \"Restoring Home Assistant using ${filename}\"\ntar xvf ${filename} -C /var/lib/docker/volumes/hass_config/_data/restore &>/dev/null\ncd /var/lib/docker/volumes/hass_config/_data/restore\ntar -xvf homeassistant.tar.gz &>/dev/null\nif ! command -v rsync >/dev/null 2>&1; then apt-get install -y rsync &>/dev/null; fi\nrsync -a /var/lib/docker/volumes/hass_config/_data/restore/data/ /var/lib/docker/volumes/hass_config/_data\nrm -rf /var/lib/docker/volumes/hass_config/_data/restore/*\nmsg_ok \"Restore Complete\"\nmsg_ok \"Starting Home Assistant \\n\"\ndocker start homeassistant\n"
  },
  {
    "path": "misc/copy-data/README.md",
    "content": "<h2><p align=\"center\">Copy data to another LXC (run in the Proxmox Shell)</p></h2>\n<div align=\"center\"> To copy data from Home Assistant Container to Home Assistant Container </div>\n\n```\nbash -c \"$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/copy-data/home-assistant-container-copy-data-home-assistant-container.sh)\"\n```\n<div align=\"center\"> To copy data from Home Assistant Container to Home Assistant Core </div>\n\n```\nbash -c \"$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/copy-data/home-assistant-container-copy-data-home-assistant-core.sh)\"\n```\n<div align=\"center\"> To copy data from Home Assistant Container to Podman Home Assistant </div>\n\n```\nbash -c \"$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/copy-data/home-assistant-container-copy-data-podman-home-assistant.sh)\"\n```\n<div align=\"center\"> To copy data from Podman Home Assistant to Home Assistant Container </div>\n\n```\nbash -c \"$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/copy-data/podman-home-assistant-copy-data-home-assistant-container.sh)\"\n```\n<div align=\"center\"> To copy data from Home Assistant Core to Home Assistant Container </div>\n\n```\nbash -c \"$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/copy-data/home-assistant-core-copy-data-home-assistant-container.sh)\"\n```\n<div align=\"center\"> To copy data from Home Assistant Core to Home Assistant Core </div>\n\n```\nbash -c \"$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/copy-data/home-assistant-core-copy-data-home-assistant-core.sh)\"\n```\n<div align=\"center\"> To copy data from Plex to Plex </div>\n\n```\nbash -c \"$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/copy-data/plex-copy-data-plex.sh)\"\n```\n<div align=\"center\"> To copy data from Zigbee2MQTT to Zigbee2MQTT </div>\n\n```\nbash -c \"$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/copy-data/z2m-copy-data-z2m.sh)\"\n```\n<div align=\"center\"> To copy data from Zwavejs2MQTT to Zwave JS UI </div>\n\n```\nbash -c \"$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/copy-data/zwavejs2mqtt-copy-data-zwavejsui.sh)\"\n```\n"
  },
  {
    "path": "misc/copy-data/home-assistant-container-copy-data-home-assistant-container.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\n# Use to copy all data from one Home Assistant LXC to another\n# run from the Proxmox Shell\nclear\nif ! command -v pveversion >/dev/null 2>&1; then echo -e \"⚠️  Run from the Proxmox Shell\"; exit; fi\nwhile true; do\n  read -p \"Use to copy all data from one Home Assistant LXC to another. Proceed(y/n)?\" yn\n  case $yn in\n  [Yy]*) break ;;\n  [Nn]*) exit ;;\n  *) echo \"Please answer yes or no.\" ;;\n  esac\ndone\nset -o errexit\nset -o errtrace\nset -o nounset\nset -o pipefail\nshopt -s expand_aliases\nalias die='EXIT=$? LINE=$LINENO error_exit'\ntrap die ERR\ntrap cleanup EXIT\n\nfunction error_exit() {\n  trap - ERR\n  local DEFAULT='Unknown failure occured.'\n  local REASON=\"\\e[97m${1:-$DEFAULT}\\e[39m\"\n  local FLAG=\"\\e[91m[ERROR] \\e[93m$EXIT@$LINE\"\n  msg \"$FLAG $REASON\"\n  exit $EXIT\n}\nfunction warn() {\n  local REASON=\"\\e[97m$1\\e[39m\"\n  local FLAG=\"\\e[93m[WARNING]\\e[39m\"\n  msg \"$FLAG $REASON\"\n}\nfunction info() {\n  local REASON=\"$1\"\n  local FLAG=\"\\e[36m[INFO]\\e[39m\"\n  msg \"$FLAG $REASON\"\n}\nfunction msg() {\n  local TEXT=\"$1\"\n  echo -e \"$TEXT\"\n}\nfunction cleanup() {\n  [ -d \"${CTID_FROM_PATH:-}\" ] && pct unmount $CTID_FROM\n  [ -d \"${CTID_TO_PATH:-}\" ] && pct unmount $CTID_TO\n  popd >/dev/null\n  rm -rf $TEMP_DIR\n}\nTEMP_DIR=$(mktemp -d)\npushd $TEMP_DIR >/dev/null\n\nTITLE=\"Home Assistant LXC Data Copy\"\nwhile read -r line; do\n  TAG=$(echo \"$line\" | awk '{print $1}')\n  ITEM=$(echo \"$line\" | awk '{print substr($0,36)}')\n  OFFSET=2\n  if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then\n    MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET))\n  fi\n  CTID_MENU+=(\"$TAG\" \"$ITEM \" \"OFF\")\ndone < <(pct list | awk 'NR>1')\nwhile [ -z \"${CTID_FROM:+x}\" ]; do\n  CTID_FROM=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"$TITLE\" --radiolist \\\n    \"\\nWhich HA LXC would you like to copy FROM?\\n\" \\\n    16 $(($MSG_MAX_LENGTH + 23)) 6 \\\n    \"${CTID_MENU[@]}\" 3>&1 1>&2 2>&3) || exit\ndone\nwhile [ -z \"${CTID_TO:+x}\" ]; do\n  CTID_TO=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"$TITLE\" --radiolist \\\n    \"\\nWhich HA LXC would you like to copy TO?\\n\" \\\n    16 $(($MSG_MAX_LENGTH + 23)) 6 \\\n    \"${CTID_MENU[@]}\" 3>&1 1>&2 2>&3) || exit\ndone\nfor i in ${!CTID_MENU[@]}; do\n  [ \"${CTID_MENU[$i]}\" == \"$CTID_FROM\" ] &&\n    CTID_FROM_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]})\n  [ \"${CTID_MENU[$i]}\" == \"$CTID_TO\" ] &&\n    CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]})\ndone\nwhiptail --backtitle \"Proxmox VE Helper Scripts\" --defaultno --title \"$TITLE\" --yesno \\\n  \"Are you sure you want to copy data between the following LXCs?\n$CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME})\nVersion: 2022.01.23\" 13 50 || exit\ninfo \"Home Assistant Data from '$CTID_FROM' to '$CTID_TO'\"\nif [ $(pct status $CTID_TO | sed 's/.* //') == 'running' ]; then\n  msg \"Stopping '$CTID_TO'...\"\n  pct stop $CTID_TO\nfi\nmsg \"Mounting Container Disks...\"\nDOCKER_PATH=/var/lib/docker/volumes/hass_config/\nCTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n \"s/.*'\\(.*\\)'/\\1/p\") ||\n  die \"There was a problem mounting the root disk of LXC '${CTID_FROM}'.\"\n[ -d \"${CTID_FROM_PATH}${DOCKER_PATH}\" ] ||\n  die \"Home Assistant directories in '$CTID_FROM' not found.\"\nCTID_TO_PATH=$(pct mount $CTID_TO | sed -n \"s/.*'\\(.*\\)'/\\1/p\") ||\n  die \"There was a problem mounting the root disk of LXC '${CTID_TO}'.\"\n[ -d \"${CTID_TO_PATH}${DOCKER_PATH}\" ] ||\n  die \"Home Assistant directories in '$CTID_TO' not found.\"\n\nrm -rf ${CTID_TO_PATH}${DOCKER_PATH}\nmkdir ${CTID_TO_PATH}${DOCKER_PATH}\n\nmsg \"Copying Data Between Containers...\"\nRSYNC_OPTIONS=(\n  --archive\n  --hard-links\n  --sparse\n  --xattrs\n  --no-inc-recursive\n  --info=progress2\n)\nmsg \"<======== Docker Data ========>\"\nrsync ${RSYNC_OPTIONS[*]} ${CTID_FROM_PATH}${DOCKER_PATH} ${CTID_TO_PATH}${DOCKER_PATH}\necho -en \"\\e[1A\\e[0K\\e[1A\\e[0K\"\n\ninfo \"Successfully Transferred Data.\"\n\n# Use to copy all data from one Home Assistant LXC to another\n# run from the Proxmox Shell\n# bash -c \"$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/copy-data/home-assistant-container-copy-data-home-assistant-container.sh)\"\n"
  },
  {
    "path": "misc/copy-data/home-assistant-container-copy-data-home-assistant-core.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nclear\nif ! command -v pveversion >/dev/null 2>&1; then echo -e \"⚠️  Run from the Proxmox Shell\"; exit; fi\nwhile true; do\n  read -p \"Use to copy all data from a Home Assistant Container LXC to a Home Assistant Core LXC. Proceed(y/n)?\" yn\n  case $yn in\n  [Yy]*) break ;;\n  [Nn]*) exit ;;\n  *) echo \"Please answer yes or no.\" ;;\n  esac\ndone\nset -o errexit\nset -o errtrace\nset -o nounset\nset -o pipefail\nshopt -s expand_aliases\nalias die='EXIT=$? LINE=$LINENO error_exit'\ntrap die ERR\ntrap cleanup EXIT\n\nfunction error_exit() {\n  trap - ERR\n  local DEFAULT='Unknown failure occured.'\n  local REASON=\"\\e[97m${1:-$DEFAULT}\\e[39m\"\n  local FLAG=\"\\e[91m[ERROR] \\e[93m$EXIT@$LINE\"\n  msg \"$FLAG $REASON\"\n  exit $EXIT\n}\nfunction warn() {\n  local REASON=\"\\e[97m$1\\e[39m\"\n  local FLAG=\"\\e[93m[WARNING]\\e[39m\"\n  msg \"$FLAG $REASON\"\n}\nfunction info() {\n  local REASON=\"$1\"\n  local FLAG=\"\\e[36m[INFO]\\e[39m\"\n  msg \"$FLAG $REASON\"\n}\nfunction msg() {\n  local TEXT=\"$1\"\n  echo -e \"$TEXT\"\n}\nfunction cleanup() {\n  [ -d \"${CTID_FROM_PATH:-}\" ] && pct unmount $CTID_FROM\n  [ -d \"${CTID_TO_PATH:-}\" ] && pct unmount $CTID_TO\n  popd >/dev/null\n  rm -rf $TEMP_DIR\n}\nTEMP_DIR=$(mktemp -d)\npushd $TEMP_DIR >/dev/null\n\nTITLE=\"Home Assistant LXC Data Copy\"\nwhile read -r line; do\n  TAG=$(echo \"$line\" | awk '{print $1}')\n  ITEM=$(echo \"$line\" | awk '{print substr($0,36)}')\n  OFFSET=2\n  if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then\n    MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET))\n  fi\n  CTID_MENU+=(\"$TAG\" \"$ITEM \" \"OFF\")\ndone < <(pct list | awk 'NR>1')\nwhile [ -z \"${CTID_FROM:+x}\" ]; do\n  CTID_FROM=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"$TITLE\" --radiolist \\\n    \"\\nWhich HA Container LXC would you like to copy FROM?\\n\" \\\n    16 $(($MSG_MAX_LENGTH + 23)) 6 \\\n    \"${CTID_MENU[@]}\" 3>&1 1>&2 2>&3) || exit\ndone\nwhile [ -z \"${CTID_TO:+x}\" ]; do\n  CTID_TO=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"$TITLE\" --radiolist \\\n    \"\\nWhich HA Core LXC would you like to copy TO?\\n\" \\\n    16 $(($MSG_MAX_LENGTH + 23)) 6 \\\n    \"${CTID_MENU[@]}\" 3>&1 1>&2 2>&3) || exit\ndone\nfor i in ${!CTID_MENU[@]}; do\n  [ \"${CTID_MENU[$i]}\" == \"$CTID_FROM\" ] &&\n    CTID_FROM_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]})\n  [ \"${CTID_MENU[$i]}\" == \"$CTID_TO\" ] &&\n    CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]})\ndone\nwhiptail --backtitle \"Proxmox VE Helper Scripts\" --defaultno --title \"$TITLE\" --yesno \\\n  \"Are you sure you want to copy data between the following LXCs?\n$CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME})\nVersion: 2022.10.02\" 13 50 || exit\ninfo \"Home Assistant Data from '$CTID_FROM' to '$CTID_TO'\"\nif [ $(pct status $CTID_TO | sed 's/.* //') == 'running' ]; then\n  msg \"Stopping '$CTID_TO'...\"\n  pct stop $CTID_TO\nfi\nmsg \"Mounting Container Disks...\"\nDOCKER_PATH=/var/lib/docker/volumes/hass_config/_data\nCORE_PATH=/root/.homeassistant\nCTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n \"s/.*'\\(.*\\)'/\\1/p\") ||\n  die \"There was a problem mounting the root disk of LXC '${CTID_FROM}'.\"\n[ -d \"${CTID_FROM_PATH}${DOCKER_PATH}\" ] ||\n  die \"Home Assistant directories in '$CTID_FROM' not found.\"\nCTID_TO_PATH=$(pct mount $CTID_TO | sed -n \"s/.*'\\(.*\\)'/\\1/p\") ||\n  die \"There was a problem mounting the root disk of LXC '${CTID_TO}'.\"\n[ -d \"${CTID_TO_PATH}${CORE_PATH}\" ] ||\n  die \"Home Assistant directories in '$CTID_TO' not found.\"\n\nmsg \"Copying Data...\"\nRSYNC_OPTIONS=(\n  --archive\n  --hard-links\n  --sparse\n  --xattrs\n  --no-inc-recursive\n  --info=progress2\n)\nmsg \"<======== Docker Data ========>\"\nrsync ${RSYNC_OPTIONS[*]} ${CTID_FROM_PATH}${DOCKER_PATH} ${CTID_TO_PATH}${CORE_PATH}\necho -en \"\\e[1A\\e[0K\\e[1A\\e[0K\"\n\ninfo \"Successfully Transferred Data.\"\n\n# Use to copy all data from a Home Assistant Container LXC to a Home Assistant Core LXC\n# run from the Proxmox Shell\n# bash -c \"$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/copy-data/home-assistant-container-copy-data-home-assistant-core.sh)\"\n"
  },
  {
    "path": "misc/copy-data/home-assistant-container-copy-data-podman-home-assistant.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\n# Use to copy all data from a Home Assistant LXC to a Podman Home Assistant LXC.\n# run from the Proxmox Shell\nclear\nif ! command -v pveversion >/dev/null 2>&1; then echo -e \"⚠️  Run from the Proxmox Shell\"; exit; fi\nwhile true; do\n  read -p \"Use to copy all data from a Home Assistant LXC to a Podman Home Assistant LXC. Proceed(y/n)?\" yn\n  case $yn in\n  [Yy]*) break ;;\n  [Nn]*) exit ;;\n  *) echo \"Please answer yes or no.\" ;;\n  esac\ndone\nset -o errexit\nset -o errtrace\nset -o nounset\nset -o pipefail\nshopt -s expand_aliases\nalias die='EXIT=$? LINE=$LINENO error_exit'\ntrap die ERR\ntrap cleanup EXIT\n\nfunction error_exit() {\n  trap - ERR\n  local DEFAULT='Unknown failure occured.'\n  local REASON=\"\\e[97m${1:-$DEFAULT}\\e[39m\"\n  local FLAG=\"\\e[91m[ERROR] \\e[93m$EXIT@$LINE\"\n  msg \"$FLAG $REASON\"\n  exit $EXIT\n}\nfunction warn() {\n  local REASON=\"\\e[97m$1\\e[39m\"\n  local FLAG=\"\\e[93m[WARNING]\\e[39m\"\n  msg \"$FLAG $REASON\"\n}\nfunction info() {\n  local REASON=\"$1\"\n  local FLAG=\"\\e[36m[INFO]\\e[39m\"\n  msg \"$FLAG $REASON\"\n}\nfunction msg() {\n  local TEXT=\"$1\"\n  echo -e \"$TEXT\"\n}\nfunction cleanup() {\n  [ -d \"${CTID_FROM_PATH:-}\" ] && pct unmount $CTID_FROM\n  [ -d \"${CTID_TO_PATH:-}\" ] && pct unmount $CTID_TO\n  popd >/dev/null\n  rm -rf $TEMP_DIR\n}\nTEMP_DIR=$(mktemp -d)\npushd $TEMP_DIR >/dev/null\n\nTITLE=\"Home Assistant LXC Data Copy\"\nwhile read -r line; do\n  TAG=$(echo \"$line\" | awk '{print $1}')\n  ITEM=$(echo \"$line\" | awk '{print substr($0,36)}')\n  OFFSET=2\n  if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then\n    MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET))\n  fi\n  CTID_MENU+=(\"$TAG\" \"$ITEM \" \"OFF\")\ndone < <(pct list | awk 'NR>1')\nwhile [ -z \"${CTID_FROM:+x}\" ]; do\n  CTID_FROM=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"$TITLE\" --radiolist \\\n    \"\\nWhich HA LXC would you like to copy FROM?\\n\" \\\n    16 $(($MSG_MAX_LENGTH + 23)) 6 \\\n    \"${CTID_MENU[@]}\" 3>&1 1>&2 2>&3) || exit\ndone\nwhile [ -z \"${CTID_TO:+x}\" ]; do\n  CTID_TO=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"$TITLE\" --radiolist \\\n    \"\\nWhich HA Podman LXC would you like to copy TO?\\n\" \\\n    16 $(($MSG_MAX_LENGTH + 23)) 6 \\\n    \"${CTID_MENU[@]}\" 3>&1 1>&2 2>&3) || exit\ndone\nfor i in ${!CTID_MENU[@]}; do\n  [ \"${CTID_MENU[$i]}\" == \"$CTID_FROM\" ] &&\n    CTID_FROM_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]})\n  [ \"${CTID_MENU[$i]}\" == \"$CTID_TO\" ] &&\n    CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]})\ndone\nwhiptail --backtitle \"Proxmox VE Helper Scripts\" --defaultno --title \"$TITLE\" --yesno \\\n  \"Are you sure you want to copy data between the following LXCs?\n$CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME})\nVersion: 2022.02.12\" 13 50 || exit\ninfo \"Home Assistant Data from '$CTID_FROM' to '$CTID_TO'\"\nif [ $(pct status $CTID_TO | sed 's/.* //') == 'running' ]; then\n  msg \"Stopping '$CTID_TO'...\"\n  pct stop $CTID_TO\nfi\nmsg \"Mounting Container Disks...\"\nDOCKER_PATH=/var/lib/docker/volumes/hass_config/\nPODMAN_PATH=/var/lib/containers/storage/volumes/hass_config/\nCTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n \"s/.*'\\(.*\\)'/\\1/p\") ||\n  die \"There was a problem mounting the root disk of LXC '${CTID_FROM}'.\"\n[ -d \"${CTID_FROM_PATH}${DOCKER_PATH}\" ] ||\n  die \"Home Assistant directories in '$CTID_FROM' not found.\"\nCTID_TO_PATH=$(pct mount $CTID_TO | sed -n \"s/.*'\\(.*\\)'/\\1/p\") ||\n  die \"There was a problem mounting the root disk of LXC '${CTID_TO}'.\"\n[ -d \"${CTID_TO_PATH}${PODMAN_PATH}\" ] ||\n  die \"Home Assistant directories in '$CTID_TO' not found.\"\n\nrm -rf ${CTID_TO_PATH}${PODMAN_PATH}\nmkdir ${CTID_TO_PATH}${PODMAN_PATH}\n\nmsg \"Copying Data Between Containers...\"\nRSYNC_OPTIONS=(\n  --archive\n  --hard-links\n  --sparse\n  --xattrs\n  --no-inc-recursive\n  --info=progress2\n)\nmsg \"<======== Docker Data ========>\"\nrsync ${RSYNC_OPTIONS[*]} ${CTID_FROM_PATH}${DOCKER_PATH} ${CTID_TO_PATH}${PODMAN_PATH}\necho -en \"\\e[1A\\e[0K\\e[1A\\e[0K\"\n\ninfo \"Successfully Transferred Data.\"\n\n# Use to copy all data from a Home Assistant LXC to a Podman Home Assistant LXC\n# run from the Proxmox Shell\n# bash -c \"$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/copy-data/home-assistant-container-copy-data-podman-home-assistant.sh)\"\n"
  },
  {
    "path": "misc/copy-data/home-assistant-core-copy-data-home-assistant-container.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nclear\nif ! command -v pveversion >/dev/null 2>&1; then echo -e \"⚠️  Run from the Proxmox Shell\"; exit; fi\nwhile true; do\n  read -p \"Use to copy all data from a Home Assistant Core LXC to a Home Assistant Container LXC. Proceed(y/n)?\" yn\n  case $yn in\n  [Yy]*) break ;;\n  [Nn]*) exit ;;\n  *) echo \"Please answer yes or no.\" ;;\n  esac\ndone\nset -o errexit\nset -o errtrace\nset -o nounset\nset -o pipefail\nshopt -s expand_aliases\nalias die='EXIT=$? LINE=$LINENO error_exit'\ntrap die ERR\ntrap cleanup EXIT\n\nfunction error_exit() {\n  trap - ERR\n  local DEFAULT='Unknown failure occured.'\n  local REASON=\"\\e[97m${1:-$DEFAULT}\\e[39m\"\n  local FLAG=\"\\e[91m[ERROR] \\e[93m$EXIT@$LINE\"\n  msg \"$FLAG $REASON\"\n  exit $EXIT\n}\nfunction warn() {\n  local REASON=\"\\e[97m$1\\e[39m\"\n  local FLAG=\"\\e[93m[WARNING]\\e[39m\"\n  msg \"$FLAG $REASON\"\n}\nfunction info() {\n  local REASON=\"$1\"\n  local FLAG=\"\\e[36m[INFO]\\e[39m\"\n  msg \"$FLAG $REASON\"\n}\nfunction msg() {\n  local TEXT=\"$1\"\n  echo -e \"$TEXT\"\n}\nfunction cleanup() {\n  [ -d \"${CTID_FROM_PATH:-}\" ] && pct unmount $CTID_FROM\n  [ -d \"${CTID_TO_PATH:-}\" ] && pct unmount $CTID_TO\n  popd >/dev/null\n  rm -rf $TEMP_DIR\n}\nTEMP_DIR=$(mktemp -d)\npushd $TEMP_DIR >/dev/null\n\nTITLE=\"Home Assistant LXC Data Copy\"\nwhile read -r line; do\n  TAG=$(echo \"$line\" | awk '{print $1}')\n  ITEM=$(echo \"$line\" | awk '{print substr($0,36)}')\n  OFFSET=2\n  if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then\n    MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET))\n  fi\n  CTID_MENU+=(\"$TAG\" \"$ITEM \" \"OFF\")\ndone < <(pct list | awk 'NR>1')\nwhile [ -z \"${CTID_FROM:+x}\" ]; do\n  CTID_FROM=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"$TITLE\" --radiolist \\\n    \"\\nWhich HA Core LXC would you like to copy FROM?\\n\" \\\n    16 $(($MSG_MAX_LENGTH + 23)) 6 \\\n    \"${CTID_MENU[@]}\" 3>&1 1>&2 2>&3) || exit\ndone\nwhile [ -z \"${CTID_TO:+x}\" ]; do\n  CTID_TO=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"$TITLE\" --radiolist \\\n    \"\\nWhich HA Container LXC would you like to copy TO?\\n\" \\\n    16 $(($MSG_MAX_LENGTH + 23)) 6 \\\n    \"${CTID_MENU[@]}\" 3>&1 1>&2 2>&3) || exit\ndone\nfor i in ${!CTID_MENU[@]}; do\n  [ \"${CTID_MENU[$i]}\" == \"$CTID_FROM\" ] &&\n    CTID_FROM_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]})\n  [ \"${CTID_MENU[$i]}\" == \"$CTID_TO\" ] &&\n    CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]})\ndone\nwhiptail --backtitle \"Proxmox VE Helper Scripts\" --defaultno --title \"$TITLE\" --yesno \\\n  \"Are you sure you want to copy data between the following LXCs?\n$CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME})\nVersion: 2022.10.02\" 13 50 || exit\ninfo \"Home Assistant Data from '$CTID_FROM' to '$CTID_TO'\"\nif [ $(pct status $CTID_TO | sed 's/.* //') == 'running' ]; then\n  msg \"Stopping '$CTID_TO'...\"\n  pct stop $CTID_TO\nfi\nmsg \"Mounting Container Disks...\"\nDOCKER_PATH=/var/lib/docker/volumes/hass_config/_data\nCORE_PATH=/root/.homeassistant\nCTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n \"s/.*'\\(.*\\)'/\\1/p\") ||\n  die \"There was a problem mounting the root disk of LXC '${CTID_FROM}'.\"\n[ -d \"${CTID_FROM_PATH}${CORE_PATH}\" ] ||\n  die \"Home Assistant directories in '$CTID_FROM' not found.\"\nCTID_TO_PATH=$(pct mount $CTID_TO | sed -n \"s/.*'\\(.*\\)'/\\1/p\") ||\n  die \"There was a problem mounting the root disk of LXC '${CTID_TO}'.\"\n[ -d \"${CTID_TO_PATH}${DOCKER_PATH}\" ] ||\n  die \"Home Assistant directories in '$CTID_TO' not found.\"\n\nmsg \"Copying Data...\"\nRSYNC_OPTIONS=(\n  --archive\n  --hard-links\n  --sparse\n  --xattrs\n  --no-inc-recursive\n  --info=progress2\n)\nmsg \"<======== Docker Data ========>\"\nrsync ${RSYNC_OPTIONS[*]} ${CTID_FROM_PATH}${CORE_PATH} ${CTID_TO_PATH}${DOCKER_PATH}\necho -en \"\\e[1A\\e[0K\\e[1A\\e[0K\"\n\ninfo \"Successfully Transferred Data.\"\n\n# Use to copy all data from a Home Assistant Core LXC to a Home Assistant Container LXC\n# run from the Proxmox Shell\n# bash -c \"$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/copy-data/home-assistant-core-copy-data-home-assistant-container.sh)\"\n"
  },
  {
    "path": "misc/copy-data/home-assistant-core-copy-data-home-assistant-core.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nclear\nif ! command -v pveversion >/dev/null 2>&1; then echo -e \"⚠️  Run from the Proxmox Shell\"; exit; fi\nwhile true; do\n  read -p \"Use to copy all data from a Home Assistant Core LXC to a Home Assistant Core LXC. Proceed(y/n)?\" yn\n  case $yn in\n  [Yy]*) break ;;\n  [Nn]*) exit ;;\n  *) echo \"Please answer yes or no.\" ;;\n  esac\ndone\nset -o errexit\nset -o errtrace\nset -o nounset\nset -o pipefail\nshopt -s expand_aliases\nalias die='EXIT=$? LINE=$LINENO error_exit'\ntrap die ERR\ntrap cleanup EXIT\n\nfunction error_exit() {\n  trap - ERR\n  local DEFAULT='Unknown failure occured.'\n  local REASON=\"\\e[97m${1:-$DEFAULT}\\e[39m\"\n  local FLAG=\"\\e[91m[ERROR] \\e[93m$EXIT@$LINE\"\n  msg \"$FLAG $REASON\"\n  exit $EXIT\n}\nfunction info() {\n  local REASON=\"$1\"\n  local FLAG=\"\\e[36m[INFO]\\e[39m\"\n  msg \"$FLAG $REASON\"\n}\nfunction msg() {\n  local TEXT=\"$1\"\n  echo -e \"$TEXT\"\n}\nfunction cleanup() {\n  [ -d \"${CTID_FROM_PATH:-}\" ] && pct unmount $CTID_FROM\n  [ -d \"${CTID_TO_PATH:-}\" ] && pct unmount $CTID_TO\n  popd >/dev/null\n  rm -rf $TEMP_DIR\n}\nTEMP_DIR=$(mktemp -d)\npushd $TEMP_DIR >/dev/null\n\nTITLE=\"Home Assistant LXC Data Copy\"\nwhile read -r line; do\n  TAG=$(echo \"$line\" | awk '{print $1}')\n  ITEM=$(echo \"$line\" | awk '{print substr($0,36)}')\n  OFFSET=2\n  if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then\n    MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET))\n  fi\n  CTID_MENU+=(\"$TAG\" \"$ITEM \" \"OFF\")\ndone < <(pct list | awk 'NR>1')\nwhile [ -z \"${CTID_FROM:+x}\" ]; do\n  CTID_FROM=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"$TITLE\" --radiolist \\\n    \"\\nWhich HA Core LXC would you like to copy FROM?\\n\" \\\n    16 $(($MSG_MAX_LENGTH + 23)) 6 \\\n    \"${CTID_MENU[@]}\" 3>&1 1>&2 2>&3) || exit\ndone\nwhile [ -z \"${CTID_TO:+x}\" ]; do\n  CTID_TO=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"$TITLE\" --radiolist \\\n    \"\\nWhich HA Core LXC would you like to copy TO?\\n\" \\\n    16 $(($MSG_MAX_LENGTH + 23)) 6 \\\n    \"${CTID_MENU[@]}\" 3>&1 1>&2 2>&3) || exit\ndone\nfor i in ${!CTID_MENU[@]}; do\n  [ \"${CTID_MENU[$i]}\" == \"$CTID_FROM\" ] &&\n    CTID_FROM_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]})\n  [ \"${CTID_MENU[$i]}\" == \"$CTID_TO\" ] &&\n    CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]})\ndone\nwhiptail --backtitle \"Proxmox VE Helper Scripts\" --defaultno --title \"$TITLE\" --yesno \\\n  \"Are you sure you want to copy data between the following LXCs?\n$CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME})\nVersion: 2022.10.03\" 13 50 || exit\ninfo \"Home Assistant Data from '$CTID_FROM' to '$CTID_TO'\"\nif [ $(pct status $CTID_FROM | sed 's/.* //') == 'running' ]; then\n  msg \"Stopping '$CTID_FROM'...\"\n  pct stop $CTID_FROM\nfi\nif [ $(pct status $CTID_TO | sed 's/.* //') == 'running' ]; then\n  msg \"Stopping '$CTID_TO'...\"\n  pct stop $CTID_TO\nfi\nmsg \"Mounting Container Disks...\"\nCORE_PATH=/root/.homeassistant\nCORE_PATH2=/root/\nCTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n \"s/.*'\\(.*\\)'/\\1/p\") ||\n  die \"There was a problem mounting the root disk of LXC '${CTID_FROM}'.\"\n[ -d \"${CTID_FROM_PATH}${CORE_PATH}\" ] ||\n  die \"Home Assistant directories in '$CTID_FROM' not found.\"\nCTID_TO_PATH=$(pct mount $CTID_TO | sed -n \"s/.*'\\(.*\\)'/\\1/p\") ||\n  die \"There was a problem mounting the root disk of LXC '${CTID_TO}'.\"\n[ -d \"${CTID_TO_PATH}${CORE_PATH2}\" ] ||\n  die \"Home Assistant directories in '$CTID_TO' not found.\"\n\nmsg \"Copying Data...\"\nRSYNC_OPTIONS=(\n  --archive\n  --hard-links\n  --sparse\n  --xattrs\n  --no-inc-recursive\n  --info=progress2\n)\nmsg \"<======== Docker Data ========>\"\nrsync ${RSYNC_OPTIONS[*]} ${CTID_FROM_PATH}${CORE_PATH} ${CTID_TO_PATH}${CORE_PATH2}\necho -en \"\\e[1A\\e[0K\\e[1A\\e[0K\"\n\ninfo \"Successfully Transferred Data.\"\n\n# Use to copy all data from a Home Assistant Core LXC to a Home Assistant Container LXC\n# run from the Proxmox Shell\n# bash -c \"$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/copy-data/home-assistant-core-copy-data-home-assistant-core.sh)\"\n"
  },
  {
    "path": "misc/copy-data/plex-copy-data-plex.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\n# Use to copy all data from one Plex Media Server LXC to another\n# run from the Proxmox Shell\nclear\nif ! command -v pveversion >/dev/null 2>&1; then echo -e \"⚠️  Run from the Proxmox Shell\"; exit; fi\nwhile true; do\n  read -p \"Use to copy all data from one Plex Media Server LXC to another. Proceed(y/n)?\" yn\n  case $yn in\n  [Yy]*) break ;;\n  [Nn]*) exit ;;\n  *) echo \"Please answer yes or no.\" ;;\n  esac\ndone\nset -o errexit\nset -o errtrace\nset -o nounset\nset -o pipefail\nshopt -s expand_aliases\nalias die='EXIT=$? LINE=$LINENO error_exit'\ntrap die ERR\ntrap cleanup EXIT\n\nfunction error_exit() {\n  trap - ERR\n  local DEFAULT='Unknown failure occured.'\n  local REASON=\"\\e[97m${1:-$DEFAULT}\\e[39m\"\n  local FLAG=\"\\e[91m[ERROR] \\e[93m$EXIT@$LINE\"\n  msg \"$FLAG $REASON\"\n  exit $EXIT\n}\nfunction warn() {\n  local REASON=\"\\e[97m$1\\e[39m\"\n  local FLAG=\"\\e[93m[WARNING]\\e[39m\"\n  msg \"$FLAG $REASON\"\n}\nfunction info() {\n  local REASON=\"$1\"\n  local FLAG=\"\\e[36m[INFO]\\e[39m\"\n  msg \"$FLAG $REASON\"\n}\nfunction msg() {\n  local TEXT=\"$1\"\n  echo -e \"$TEXT\"\n}\nfunction cleanup() {\n  [ -d \"${CTID_FROM_PATH:-}\" ] && pct unmount $CTID_FROM\n  [ -d \"${CTID_TO_PATH:-}\" ] && pct unmount $CTID_TO\n  popd >/dev/null\n  rm -rf $TEMP_DIR\n}\nTEMP_DIR=$(mktemp -d)\npushd $TEMP_DIR >/dev/null\n\nTITLE=\"Plex Media Server LXC Data Copy\"\nwhile read -r line; do\n  TAG=$(echo \"$line\" | awk '{print $1}')\n  ITEM=$(echo \"$line\" | awk '{print substr($0,36)}')\n  OFFSET=2\n  if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then\n    MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET))\n  fi\n  CTID_MENU+=(\"$TAG\" \"$ITEM \" \"OFF\")\ndone < <(pct list | awk 'NR>1')\nwhile [ -z \"${CTID_FROM:+x}\" ]; do\n  CTID_FROM=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"$TITLE\" --radiolist \\\n    \"\\nWhich Plex Media Server LXC would you like to copy FROM?\\n\" \\\n    16 $(($MSG_MAX_LENGTH + 23)) 6 \\\n    \"${CTID_MENU[@]}\" 3>&1 1>&2 2>&3) || exit\ndone\nwhile [ -z \"${CTID_TO:+x}\" ]; do\n  CTID_TO=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"$TITLE\" --radiolist \\\n    \"\\nWhich Plex Media Server LXC would you like to copy TO?\\n\" \\\n    16 $(($MSG_MAX_LENGTH + 23)) 6 \\\n    \"${CTID_MENU[@]}\" 3>&1 1>&2 2>&3) || exit\ndone\nfor i in ${!CTID_MENU[@]}; do\n  [ \"${CTID_MENU[$i]}\" == \"$CTID_FROM\" ] &&\n    CTID_FROM_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]})\n  [ \"${CTID_MENU[$i]}\" == \"$CTID_TO\" ] &&\n    CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]})\ndone\nwhiptail --backtitle \"Proxmox VE Helper Scripts\" --defaultno --title \"$TITLE\" --yesno \\\n  \"Are you sure you want to copy data between the following LXCs?\n$CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME})\nVersion: 2022.01.24\" 13 50 || exit\ninfo \"Plex Media Server Data from '$CTID_FROM' to '$CTID_TO'\"\nif [ $(pct status $CTID_TO | sed 's/.* //') == 'running' ]; then\n  msg \"Stopping '$CTID_TO'...\"\n  pct stop $CTID_TO\nfi\nmsg \"Mounting Container Disks...\"\nDATA_PATH=/var/lib/plexmediaserver/Library/\nCTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n \"s/.*'\\(.*\\)'/\\1/p\") ||\n  die \"There was a problem mounting the root disk of LXC '${CTID_FROM}'.\"\n[ -d \"${CTID_FROM_PATH}${DATA_PATH}\" ] ||\n  die \"Plex Media Server directories in '$CTID_FROM' not found.\"\nCTID_TO_PATH=$(pct mount $CTID_TO | sed -n \"s/.*'\\(.*\\)'/\\1/p\") ||\n  die \"There was a problem mounting the root disk of LXC '${CTID_TO}'.\"\n[ -d \"${CTID_TO_PATH}${DATA_PATH}\" ] ||\n  die \"Plex Media Server directories in '$CTID_TO' not found.\"\n\n#rm -rf ${CTID_TO_PATH}${DATA_PATH}\n#mkdir ${CTID_TO_PATH}${DATA_PATH}\n\nmsg \"Copying Data Between Containers...\"\nRSYNC_OPTIONS=(\n  --archive\n  --hard-links\n  --sparse\n  --xattrs\n  --no-inc-recursive\n  --info=progress2\n)\nmsg \"<======== Plex Media Server Data ========>\"\nrsync ${RSYNC_OPTIONS[*]} ${CTID_FROM_PATH}${DATA_PATH} ${CTID_TO_PATH}${DATA_PATH}\necho -en \"\\e[1A\\e[0K\\e[1A\\e[0K\"\n\ninfo \"Successfully Transferred Data.\"\n\n# Use to copy all data from one Plex Media Server LXC to another\n# run from the Proxmox Shell\n# bash -c \"$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/copy-data/plex-copy-data-plex.sh)\"\n"
  },
  {
    "path": "misc/copy-data/podman-home-assistant-copy-data-home-assistant-container.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\n# Use to copy all data from a Podman Home Assistant LXC to a Docker Home Assistant LXC.\n# run from the Proxmox Shell\nclear\nif ! command -v pveversion >/dev/null 2>&1; then echo -e \"⚠️  Run from the Proxmox Shell\"; exit; fi\nwhile true; do\n  read -p \"Use to copy all data from a Podman Home Assistant LXC to a Docker Home Assistant LXC. Proceed(y/n)?\" yn\n  case $yn in\n  [Yy]*) break ;;\n  [Nn]*) exit ;;\n  *) echo \"Please answer yes or no.\" ;;\n  esac\ndone\nset -o errexit\nset -o errtrace\nset -o nounset\nset -o pipefail\nshopt -s expand_aliases\nalias die='EXIT=$? LINE=$LINENO error_exit'\ntrap die ERR\ntrap cleanup EXIT\n\nfunction error_exit() {\n  trap - ERR\n  local DEFAULT='Unknown failure occured.'\n  local REASON=\"\\e[97m${1:-$DEFAULT}\\e[39m\"\n  local FLAG=\"\\e[91m[ERROR] \\e[93m$EXIT@$LINE\"\n  msg \"$FLAG $REASON\"\n  exit $EXIT\n}\nfunction warn() {\n  local REASON=\"\\e[97m$1\\e[39m\"\n  local FLAG=\"\\e[93m[WARNING]\\e[39m\"\n  msg \"$FLAG $REASON\"\n}\nfunction info() {\n  local REASON=\"$1\"\n  local FLAG=\"\\e[36m[INFO]\\e[39m\"\n  msg \"$FLAG $REASON\"\n}\nfunction msg() {\n  local TEXT=\"$1\"\n  echo -e \"$TEXT\"\n}\nfunction cleanup() {\n  [ -d \"${CTID_FROM_PATH:-}\" ] && pct unmount $CTID_FROM\n  [ -d \"${CTID_TO_PATH:-}\" ] && pct unmount $CTID_TO\n  popd >/dev/null\n  rm -rf $TEMP_DIR\n}\nTEMP_DIR=$(mktemp -d)\npushd $TEMP_DIR >/dev/null\n\nTITLE=\"Home Assistant LXC Data Copy\"\nwhile read -r line; do\n  TAG=$(echo \"$line\" | awk '{print $1}')\n  ITEM=$(echo \"$line\" | awk '{print substr($0,36)}')\n  OFFSET=2\n  if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then\n    MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET))\n  fi\n  CTID_MENU+=(\"$TAG\" \"$ITEM \" \"OFF\")\ndone < <(pct list | awk 'NR>1')\nwhile [ -z \"${CTID_FROM:+x}\" ]; do\n  CTID_FROM=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"$TITLE\" --radiolist \\\n    \"\\nWhich HA Podman LXC would you like to copy FROM?\\n\" \\\n    16 $(($MSG_MAX_LENGTH + 23)) 6 \\\n    \"${CTID_MENU[@]}\" 3>&1 1>&2 2>&3) || exit\ndone\nwhile [ -z \"${CTID_TO:+x}\" ]; do\n  CTID_TO=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"$TITLE\" --radiolist \\\n    \"\\nWhich HA LXC would you like to copy TO?\\n\" \\\n    16 $(($MSG_MAX_LENGTH + 23)) 6 \\\n    \"${CTID_MENU[@]}\" 3>&1 1>&2 2>&3) || exit\ndone\nfor i in ${!CTID_MENU[@]}; do\n  [ \"${CTID_MENU[$i]}\" == \"$CTID_FROM\" ] &&\n    CTID_FROM_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]})\n  [ \"${CTID_MENU[$i]}\" == \"$CTID_TO\" ] &&\n    CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]})\ndone\nwhiptail --backtitle \"Proxmox VE Helper Scripts\" --defaultno --title \"$TITLE\" --yesno \\\n  \"Are you sure you want to copy data between the following LXCs?\n$CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME})\nVersion: 2022.03.31\" 13 50 || exit\ninfo \"Home Assistant Data from '$CTID_FROM' to '$CTID_TO'\"\nif [ $(pct status $CTID_TO | sed 's/.* //') == 'running' ]; then\n  msg \"Stopping '$CTID_TO'...\"\n  pct stop $CTID_TO\nfi\nmsg \"Mounting Container Disks...\"\nDOCKER_PATH=/var/lib/docker/volumes/hass_config/\nPODMAN_PATH=/var/lib/containers/storage/volumes/hass_config/\nCTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n \"s/.*'\\(.*\\)'/\\1/p\") ||\n  die \"There was a problem mounting the root disk of LXC '${CTID_FROM}'.\"\n[ -d \"${CTID_FROM_PATH}${PODMAN_PATH}\" ] ||\n  die \"Home Assistant directories in '$CTID_FROM' not found.\"\nCTID_TO_PATH=$(pct mount $CTID_TO | sed -n \"s/.*'\\(.*\\)'/\\1/p\") ||\n  die \"There was a problem mounting the root disk of LXC '${CTID_TO}'.\"\n[ -d \"${CTID_TO_PATH}${DOCKER_PATH}\" ] ||\n  die \"Home Assistant directories in '$CTID_TO' not found.\"\n\nrm -rf ${CTID_TO_PATH}${DOCKER_PATH}\nmkdir ${CTID_TO_PATH}${DOCKER_PATH}\n\nmsg \"Copying Data Between Containers...\"\nRSYNC_OPTIONS=(\n  --archive\n  --hard-links\n  --sparse\n  --xattrs\n  --no-inc-recursive\n  --info=progress2\n)\nmsg \"<======== Data ========>\"\nrsync ${RSYNC_OPTIONS[*]} ${CTID_FROM_PATH}${PODMAN_PATH} ${CTID_TO_PATH}${DOCKER_PATH}\necho -en \"\\e[1A\\e[0K\\e[1A\\e[0K\"\n\ninfo \"Successfully Transferred Data.\"\n\n# Use to copy all data from a Podman Home Assistant LXC to a Docker Home Assistant LXC.\n# run from the Proxmox Shell\n# bash -c \"$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/copy-data/podman-home-assistant-copy-data-home-assistant-container.sh)\"\n"
  },
  {
    "path": "misc/copy-data/z2m-copy-data-z2m.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\n# Use to copy all data from one Zigbee2MQTT LXC to another\n# run from the Proxmox Shell\nclear\nif ! command -v pveversion >/dev/null 2>&1; then echo -e \"⚠️  Run from the Proxmox Shell\"; exit; fi\nwhile true; do\n  read -p \"Use to copy all data from one Zigbee2MQTT LXC to another. Proceed(y/n)?\" yn\n  case $yn in\n  [Yy]*) break ;;\n  [Nn]*) exit ;;\n  *) echo \"Please answer yes or no.\" ;;\n  esac\ndone\nset -o errexit\nset -o errtrace\nset -o nounset\nset -o pipefail\nshopt -s expand_aliases\nalias die='EXIT=$? LINE=$LINENO error_exit'\ntrap die ERR\ntrap cleanup EXIT\n\nfunction error_exit() {\n  trap - ERR\n  local DEFAULT='Unknown failure occured.'\n  local REASON=\"\\e[97m${1:-$DEFAULT}\\e[39m\"\n  local FLAG=\"\\e[91m[ERROR] \\e[93m$EXIT@$LINE\"\n  msg \"$FLAG $REASON\"\n  exit $EXIT\n}\nfunction warn() {\n  local REASON=\"\\e[97m$1\\e[39m\"\n  local FLAG=\"\\e[93m[WARNING]\\e[39m\"\n  msg \"$FLAG $REASON\"\n}\nfunction info() {\n  local REASON=\"$1\"\n  local FLAG=\"\\e[36m[INFO]\\e[39m\"\n  msg \"$FLAG $REASON\"\n}\nfunction msg() {\n  local TEXT=\"$1\"\n  echo -e \"$TEXT\"\n}\nfunction cleanup() {\n  [ -d \"${CTID_FROM_PATH:-}\" ] && pct unmount $CTID_FROM\n  [ -d \"${CTID_TO_PATH:-}\" ] && pct unmount $CTID_TO\n  popd >/dev/null\n  rm -rf $TEMP_DIR\n}\nTEMP_DIR=$(mktemp -d)\npushd $TEMP_DIR >/dev/null\n\nTITLE=\"Zigbee2MQTT LXC Data Copy\"\nwhile read -r line; do\n  TAG=$(echo \"$line\" | awk '{print $1}')\n  ITEM=$(echo \"$line\" | awk '{print substr($0,36)}')\n  OFFSET=2\n  if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then\n    MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET))\n  fi\n  CTID_MENU+=(\"$TAG\" \"$ITEM \" \"OFF\")\ndone < <(pct list | awk 'NR>1')\nwhile [ -z \"${CTID_FROM:+x}\" ]; do\n  CTID_FROM=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"$TITLE\" --radiolist \\\n    \"\\nWhich Zigbee2MQTT LXC would you like to copy FROM?\\n\" \\\n    16 $(($MSG_MAX_LENGTH + 23)) 6 \\\n    \"${CTID_MENU[@]}\" 3>&1 1>&2 2>&3) || exit\ndone\nwhile [ -z \"${CTID_TO:+x}\" ]; do\n  CTID_TO=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"$TITLE\" --radiolist \\\n    \"\\nWhich Zigbee2MQTT LXC would you like to copy TO?\\n\" \\\n    16 $(($MSG_MAX_LENGTH + 23)) 6 \\\n    \"${CTID_MENU[@]}\" 3>&1 1>&2 2>&3) || exit\ndone\nfor i in ${!CTID_MENU[@]}; do\n  [ \"${CTID_MENU[$i]}\" == \"$CTID_FROM\" ] &&\n    CTID_FROM_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]})\n  [ \"${CTID_MENU[$i]}\" == \"$CTID_TO\" ] &&\n    CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]})\ndone\nwhiptail --backtitle \"Proxmox VE Helper Scripts\" --defaultno --title \"$TITLE\" --yesno \\\n  \"Are you sure you want to copy data between the following LXCs?\n$CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME})\nVersion: 2022.01.23\" 13 50 || exit\ninfo \"Zigbee2MQTT Data from '$CTID_FROM' to '$CTID_TO'\"\nif [ $(pct status $CTID_TO | sed 's/.* //') == 'running' ]; then\n  msg \"Stopping '$CTID_TO'...\"\n  pct stop $CTID_TO\nfi\nmsg \"Mounting Container Disks...\"\nDATA_PATH=/opt/zigbee2mqtt/data/\nCTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n \"s/.*'\\(.*\\)'/\\1/p\") ||\n  die \"There was a problem mounting the root disk of LXC '${CTID_FROM}'.\"\n[ -d \"${CTID_FROM_PATH}${DATA_PATH}\" ] ||\n  die \"Zigbee2igbee2MQTT directories in '$CTID_FROM' not found.\"\nCTID_TO_PATH=$(pct mount $CTID_TO | sed -n \"s/.*'\\(.*\\)'/\\1/p\") ||\n  die \"There was a problem mounting the root disk of LXC '${CTID_TO}'.\"\n[ -d \"${CTID_TO_PATH}${DATA_PATH}\" ] ||\n  die \"Zigbee2MQTT directories in '$CTID_TO' not found.\"\n\n#rm -rf ${CTID_TO_PATH}${DATA_PATH}\n#mkdir ${CTID_TO_PATH}${DATA_PATH}\n\nmsg \"Copying Data Between Containers...\"\nRSYNC_OPTIONS=(\n  --archive\n  --hard-links\n  --sparse\n  --xattrs\n  --no-inc-recursive\n  --info=progress2\n)\nmsg \"<======== Zigbee2MQTT Data ========>\"\nrsync ${RSYNC_OPTIONS[*]} ${CTID_FROM_PATH}${DATA_PATH} ${CTID_TO_PATH}${DATA_PATH}\necho -en \"\\e[1A\\e[0K\\e[1A\\e[0K\"\n\ninfo \"Successfully Transferred Data.\"\n\n# Use to copy all data from one Zigbee2MQTT LXC to another\n# run from the Proxmox Shell\n# bash -c \"$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/copy-data/z2m-copy-data-z2m.sh)\"\n"
  },
  {
    "path": "misc/copy-data/zwavejs2mqtt-copy-data-zwavejsui.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\n# Use to copy all data from a Zwavejs2MQTT LXC to a Z-wave JS UI LXC\n# run from the Proxmox Shell\nclear\nif ! command -v pveversion >/dev/null 2>&1; then echo -e \"⚠️  Run from the Proxmox Shell\"; exit; fi\nwhile true; do\n  read -p \"Use to copy all data from a Zwavejs2MQTT LXC to a Z-wave JS UI LXC. Proceed(y/n)?\" yn\n  case $yn in\n  [Yy]*) break ;;\n  [Nn]*) exit ;;\n  *) echo \"Please answer yes or no.\" ;;\n  esac\ndone\nclear\nset -o errexit\nset -o errtrace\nset -o nounset\nset -o pipefail\nshopt -s expand_aliases\nalias die='EXIT=$? LINE=$LINENO error_exit'\ntrap die ERR\ntrap cleanup EXIT\n\nfunction error_exit() {\n  trap - ERR\n  local DEFAULT='Unknown failure occured.'\n  local REASON=\"\\e[97m${1:-$DEFAULT}\\e[39m\"\n  local FLAG=\"\\e[91m[ERROR] \\e[93m$EXIT@$LINE\"\n  msg \"$FLAG $REASON\"\n  exit $EXIT\n}\nfunction warn() {\n  local REASON=\"\\e[97m$1\\e[39m\"\n  local FLAG=\"\\e[93m[WARNING]\\e[39m\"\n  msg \"$FLAG $REASON\"\n}\nfunction info() {\n  local REASON=\"$1\"\n  local FLAG=\"\\e[36m[INFO]\\e[39m\"\n  msg \"$FLAG $REASON\"\n}\nfunction msg() {\n  local TEXT=\"$1\"\n  echo -e \"$TEXT\"\n}\nfunction cleanup() {\n  [ -d \"${CTID_FROM_PATH:-}\" ] && pct unmount $CTID_FROM\n  [ -d \"${CTID_TO_PATH:-}\" ] && pct unmount $CTID_TO\n  popd >/dev/null\n  rm -rf $TEMP_DIR\n}\nTEMP_DIR=$(mktemp -d)\npushd $TEMP_DIR >/dev/null\n\nTITLE=\"Zigbee2MQTT to Z-wave JS UI Data Copy\"\nwhile read -r line; do\n  TAG=$(echo \"$line\" | awk '{print $1}')\n  ITEM=$(echo \"$line\" | awk '{print substr($0,36)}')\n  OFFSET=2\n  if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then\n    MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET))\n  fi\n  CTID_MENU+=(\"$TAG\" \"$ITEM \" \"OFF\")\ndone < <(pct list | awk 'NR>1')\nwhile [ -z \"${CTID_FROM:+x}\" ]; do\n  CTID_FROM=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"$TITLE\" --radiolist \\\n    \"\\nWhich Zwavejs2MQTT LXC would you like to copy FROM?\\n\" \\\n    16 $(($MSG_MAX_LENGTH + 23)) 6 \\\n    \"${CTID_MENU[@]}\" 3>&1 1>&2 2>&3) || exit\ndone\nwhile [ -z \"${CTID_TO:+x}\" ]; do\n  CTID_TO=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"$TITLE\" --radiolist \\\n    \"\\nWhich Z-wave JS UI LXC would you like to copy TO?\\n\" \\\n    16 $(($MSG_MAX_LENGTH + 23)) 6 \\\n    \"${CTID_MENU[@]}\" 3>&1 1>&2 2>&3) || exit\ndone\nfor i in ${!CTID_MENU[@]}; do\n  [ \"${CTID_MENU[$i]}\" == \"$CTID_FROM\" ] &&\n    CTID_FROM_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]})\n  [ \"${CTID_MENU[$i]}\" == \"$CTID_TO\" ] &&\n    CTID_TO_HOSTNAME=$(sed 's/[[:space:]]*$//' <<<${CTID_MENU[$i + 1]})\ndone\nwhiptail --backtitle \"Proxmox VE Helper Scripts\" --defaultno --title \"$TITLE\" --yesno \\\n  \"Are you sure you want to copy data between the following LXCs?\n$CTID_FROM (${CTID_FROM_HOSTNAME}) -> $CTID_TO (${CTID_TO_HOSTNAME})\nVersion: 2022.09.21\" 13 50 || exit\ninfo \"Zwavejs2MQTT Data from '$CTID_FROM' to '$CTID_TO'\"\nif [ $(pct status $CTID_TO | sed 's/.* //') == 'running' ]; then\n  msg \"Stopping '$CTID_TO'...\"\n  pct stop $CTID_TO\nfi\nmsg \"Mounting Container Disks...\"\nDATA_PATH=/opt/zwavejs2mqtt/store/\nDATA_PATH_NEW=/opt/zwave-js-ui/store/\nCTID_FROM_PATH=$(pct mount $CTID_FROM | sed -n \"s/.*'\\(.*\\)'/\\1/p\") ||\n  die \"There was a problem mounting the root disk of LXC '${CTID_FROM}'.\"\n[ -d \"${CTID_FROM_PATH}${DATA_PATH}\" ] ||\n  die \"Zwavejs2MQTT directories in '$CTID_FROM' not found.\"\nCTID_TO_PATH=$(pct mount $CTID_TO | sed -n \"s/.*'\\(.*\\)'/\\1/p\") ||\n  die \"There was a problem mounting the root disk of LXC '${CTID_TO}'.\"\n[ -d \"${CTID_TO_PATH}${DATA_PATH_NEW}\" ] ||\n  die \"Zwavejs2MQTT directories in '$CTID_TO' not found.\"\n\n#rm -rf ${CTID_TO_PATH}${DATA_PATH}\n#mkdir ${CTID_TO_PATH}${DATA_PATH}\n\nmsg \"Copying Data Between Containers...\"\nRSYNC_OPTIONS=(\n  --archive\n  --hard-links\n  --sparse\n  --xattrs\n  --no-inc-recursive\n  --info=progress2\n)\nmsg \"<======== Zwavejs Data ========>\"\nrsync ${RSYNC_OPTIONS[*]} ${CTID_FROM_PATH}${DATA_PATH} ${CTID_TO_PATH}${DATA_PATH_NEW}\necho -en \"\\e[1A\\e[0K\\e[1A\\e[0K\"\n\ninfo \"Successfully Transferred Data.\"\n\n# Use to copy all data from a Zwavejs2MQTT LXC to a Z-wave JS UI LXC\n# run from the Proxmox Shell\n# bash -c \"$(wget -qLO - https://raw.githubusercontent.com/tteck/Proxmox/main/misc/copy-data/zwavejs2mqtt-copy-data-zwavejsui.sh)\"\n"
  },
  {
    "path": "misc/core-restore-from-backup.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nclear\nif command -v pveversion >/dev/null 2>&1; then echo -e \"⚠️  Can't Run from the Proxmox Shell\"; exit; fi\nYW=$(echo \"\\033[33m\")\nBL=$(echo \"\\033[36m\")\nRD=$(echo \"\\033[01;31m\")\nBGN=$(echo \"\\033[4;92m\")\nGN=$(echo \"\\033[1;92m\")\nDGN=$(echo \"\\033[32m\")\nCL=$(echo \"\\033[m\")\nBFR=\"\\\\r\\\\033[K\"\nHOLD=\"-\"\nCM=\"${GN}✓${CL}\"\nCROSS=\"${RD}✗${CL}\"\nAPP=\"Home Assistant Core\"\nwhile true; do\n    read -p \"This will restore ${APP} from a backup. Proceed(y/n)?\" yn\n    case $yn in\n    [Yy]*) break ;;\n    [Nn]*) exit ;;\n    *) echo \"Please answer yes or no.\" ;;\n    esac\ndone\nclear\nfunction header_info {\n    cat <<\"EOF\"\n    __  __                        ___              _      __              __     ______              \n   / / / /___  ____ ___  ___     /   |  __________(_)____/ /_____ _____  / /_   / ____/___  ________ \n  / /_/ / __ \\/ __ `__ \\/ _ \\   / /| | / ___/ ___/ / ___/ __/ __ `/ __ \\/ __/  / /   / __ \\/ ___/ _ \\\n / __  / /_/ / / / / / /  __/  / ___ |(__  |__  ) (__  ) /_/ /_/ / / / / /_   / /___/ /_/ / /  /  __/\n/_/ /_/\\____/_/ /_/ /_/\\___/  /_/  |_/____/____/_/____/\\__/\\__,_/_/ /_/\\__/   \\____/\\____/_/   \\___/ \n                                     RESTORE FROM BACKUP                                \nEOF\n}\n\nheader_info\n\nfunction msg_info() {\n    local msg=\"$1\"\n    echo -ne \" ${HOLD} ${YW}${msg}...\"\n}\nfunction msg_ok() {\n    local msg=\"$1\"\n    echo -e \"${BFR} ${CM} ${GN}${msg}${CL}\"\n}\nfunction msg_error() {\n    local msg=\"$1\"\n    echo -e \"${BFR} ${CROSS} ${RD}${msg}${CL}\"\n}\nif [ -z \"$(ls -A /root/.homeassistant/backups/)\" ]; then\n    msg_error \"No backups found! \\n\"\n    exit 1\nfi\nDIR=/root/.homeassistant/restore\nif [ -d \"$DIR\" ]; then\n    msg_ok \"Restore Directory Exists.\"\nelse\n    mkdir -p /root/.homeassistant/restore\n    msg_ok \"Created Restore Directory.\"\nfi\ncd /root/.homeassistant/backups/\nPS3=\"Please enter your choice: \"\nfiles=\"$(ls -A .)\"\nselect filename in ${files}; do\n    msg_ok \"You selected ${BL}${filename}${CL}\"\n    break\ndone\nmsg_info \"Stopping Home Assistant\"\nsudo service homeassistant stop\nmsg_ok \"Stopped Home Assistant\"\nmsg_info \"Restoring Home Assistant using ${filename}\"\ntar xvf ${filename} -C /root/.homeassistant/restore &>/dev/null\ncd /root/.homeassistant/restore\ntar -xvf homeassistant.tar.gz &>/dev/null\nif ! command -v rsync >/dev/null 2>&1; then apt-get install -y rsync &>/dev/null; fi\nrsync -a /root/.homeassistant/restore/data/ /root/.homeassistant\nrm -rf /root/.homeassistant/restore/*\nmsg_ok \"Restore Complete\"\nmsg_ok \"Starting Home Assistant \\n\"\nsudo service homeassistant start\n"
  },
  {
    "path": "misc/cron-update-lxcs.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n# bash -c \"$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/cron-update-lxcs.sh)\"\n\nclear\ncat <<\"EOF\"\n   ______                    __  __          __      __          __   _  ________\n  / ____/________  ____     / / / /___  ____/ /___ _/ /____     / /  | |/ / ____/____\n / /   / ___/ __ \\/ __ \\   / / / / __ \\/ __  / __ `/ __/ _ \\   / /   |   / /   / ___/\n/ /___/ /  / /_/ / / / /  / /_/ / /_/ / /_/ / /_/ / /_/  __/  / /___/   / /___(__  )\n\\____/_/   \\____/_/ /_/   \\____/ .___/\\__,_/\\__,_/\\__/\\___/  /_____/_/|_\\____/____/\n                              /_/\nEOF\n\nadd() {\n  while true; do\n    read -p \"This script will add a crontab schedule that updates all LXCs every Sunday at midnight. Proceed(y/n)?\" yn\n    case $yn in\n    [Yy]*) break ;;\n    [Nn]*) exit ;;\n    *) echo \"Please answer yes or no.\" ;;\n    esac\n  done\n  sh -c '(crontab -l -u root 2>/dev/null; echo \"0 0 * * 0 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin /bin/bash -c \\\"\\$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/update-lxcs-cron.sh)\\\" >>/var/log/update-lxcs-cron.log 2>/dev/null\") | crontab -u root -'\n  clear\n  echo -e \"\\n To view Cron Update LXCs logs: cat /var/log/update-lxcs-cron.log\"\n}\n\nremove() {\n  (crontab -l | grep -v \"github.com/tteck/Proxmox/raw/main/misc/update-lxcs-cron.sh\") | crontab -\n  rm -rf /var/log/update-lxcs-cron.log\n  echo \"Removed Crontab Schedule from Proxmox VE\"\n}\n\nOPTIONS=(Add \"Add Crontab Schedule\"\n  Remove \"Remove Crontab Schedule\")\n\nCHOICE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"Cron Update LXCs\" --menu \"Select an option:\" 10 58 2 \\\n  \"${OPTIONS[@]}\" 3>&1 1>&2 2>&3)\n\ncase $CHOICE in\n\"Add\")\n  add\n  ;;\n\"Remove\")\n  remove\n  ;;\n*)\n  echo \"Exiting...\"\n  exit 0\n  ;;\nesac\n"
  },
  {
    "path": "misc/crowdsec.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nYW=$(echo \"\\033[33m\")\nBL=$(echo \"\\033[36m\")\nRD=$(echo \"\\033[01;31m\")\nBGN=$(echo \"\\033[4;92m\")\nGN=$(echo \"\\033[1;92m\")\nDGN=$(echo \"\\033[32m\")\nCL=$(echo \"\\033[m\")\nBFR=\"\\\\r\\\\033[K\"\nHOLD=\"-\"\nCM=\"${GN}✓${CL}\"\nAPP=\"CrowdSec\"\nhostname=\"$(hostname)\"\nset -o errexit\nset -o errtrace\nset -o nounset\nset -o pipefail\nshopt -s expand_aliases\nalias die='EXIT=$? LINE=$LINENO error_exit'\ntrap die ERR\n\nfunction error_exit() {\n    trap - ERR\n    local reason=\"Unknown failure occured.\"\n    local msg=\"${1:-$reason}\"\n    local flag=\"${RD}‼ ERROR ${CL}$EXIT@$LINE\"\n    echo -e \"$flag $msg\" 1>&2\n    exit $EXIT\n}\nif command -v pveversion >/dev/null 2>&1; then echo -e \"⚠️  Can't Install on Proxmox \"; exit; fi\nwhile true; do\n    read -p \"This will Install ${APP} on $hostname. Proceed(y/n)?\" yn\n    case $yn in\n    [Yy]*) break ;;\n    [Nn]*) exit ;;\n    *) echo \"Please answer yes or no.\" ;;\n    esac\ndone\nclear\nfunction header_info {\n    echo -e \"${BL}\n   _____                      _  _____           \n  / ____|                    | |/ ____|          \n | |     _ __ _____      ____| | (___   ___  ___ \n | |    |  __/ _ \\ \\ /\\ / / _  |\\___ \\ / _ \\/ __|\n | |____| | | (_) \\ V  V / (_| |____) |  __/ (__ \n  \\_____|_|  \\___/ \\_/\\_/ \\__ _|_____/ \\___|\\___|\n${CL}\"\n}\n\nheader_info\n\nfunction msg_info() {\n    local msg=\"$1\"\n    echo -ne \" ${HOLD} ${YW}${msg}...\"\n}\n\nfunction msg_ok() {\n    local msg=\"$1\"\n    echo -e \"${BFR} ${CM} ${GN}${msg}${CL}\"\n}\n\nmsg_info \"Setting up ${APP} Repository\"\napt-get update &>/dev/null\napt-get install -y curl &>/dev/null\napt-get install -y gnupg &>/dev/null\ncurl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.deb.sh | bash &>/dev/null\nmsg_ok \"Setup ${APP} Repository\"\n\nmsg_info \"Installing ${APP}\"\napt-get update &>/dev/null\napt-get install -y crowdsec &>/dev/null\nmsg_ok \"Installed ${APP} on $hostname\"\n\nmsg_info \"Installing ${APP} Common Bouncer\"\napt-get install -y crowdsec-firewall-bouncer-iptables &>/dev/null\nmsg_ok \"Installed ${APP} Common Bouncer\"\n\nmsg_ok \"Completed Successfully!\\n\"\n"
  },
  {
    "path": "misc/filebrowser.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\n    clear\n    cat <<\"EOF\"\n    _______ __     ____\n   / ____(_) /__  / __ )_________ _      __________  _____\n  / /_  / / / _ \\/ __  / ___/ __ \\ | /| / / ___/ _ \\/ ___/\n / __/ / / /  __/ /_/ / /  / /_/ / |/ |/ (__  )  __/ /\n/_/   /_/_/\\___/_____/_/   \\____/|__/|__/____/\\___/_/\n\nEOF\n}\nIP=$(hostname -I | awk '{print $1}')\nYW=$(echo \"\\033[33m\")\nBL=$(echo \"\\033[36m\")\nRD=$(echo \"\\033[01;31m\")\nBGN=$(echo \"\\033[4;92m\")\nGN=$(echo \"\\033[1;92m\")\nDGN=$(echo \"\\033[32m\")\nCL=$(echo \"\\033[m\")\nBFR=\"\\\\r\\\\033[K\"\nHOLD=\"-\"\nCM=\"${GN}✓${CL}\"\nAPP=\"FileBrowser\"\nhostname=\"$(hostname)\"\nheader_info\nif [ -f /root/filebrowser.db ]; then\n  read -r -p \"Would you like to uninstall ${APP} on $hostname.? <y/N> \" prompt\n    if [[ \"${prompt,,}\" =~ ^(y|yes)$ ]]; then\n      systemctl disable -q --now filebrowser.service\n      rm -rf /usr/local/bin/filebrowser /root/filebrowser.db /etc/systemd/system/filebrowser.service\n      echo \"$APP Removed\"\n      sleep 2\n      clear\n      exit\n    else\n      clear\n      exit\n    fi\nfi \nwhile true; do\n    read -p \"This will Install ${APP} on $hostname. Proceed(y/n)?\" yn\n    case $yn in\n    [Yy]*) break ;;\n    [Nn]*) exit ;;\n    *) echo \"Please answer yes or no.\" ;;\n    esac\ndone\nheader_info\nfunction msg_info() {\n    local msg=\"$1\"\n    echo -ne \" ${HOLD} ${YW}${msg}...\"\n}\n\nfunction msg_ok() {\n    local msg=\"$1\"\n    echo -e \"${BFR} ${CM} ${GN}${msg}${CL}\"\n}\n\nread -r -p \"Would you like to use No Authentication? <y/N> \" prompt\nmsg_info \"Installing ${APP}\"\napt-get install -y curl &>/dev/null\nRELEASE=$(curl -fsSL https://api.github.com/repos/filebrowser/filebrowser/releases/latest | grep -o '\"tag_name\": \".*\"' | sed 's/\"//g' | sed 's/tag_name: //g')\ncurl -fsSL https://github.com/filebrowser/filebrowser/releases/download/$RELEASE/linux-amd64-filebrowser.tar.gz | tar -xzv -C /usr/local/bin &>/dev/null\n\nif [[ \"${prompt,,}\" =~ ^(y|yes)$ ]]; then\n  filebrowser config init -a '0.0.0.0' &>/dev/null\n  filebrowser config set -a '0.0.0.0' &>/dev/null\n  filebrowser config init --auth.method=noauth &>/dev/null\n  filebrowser config set --auth.method=noauth &>/dev/null\n  filebrowser users add ID 1 --perm.admin &>/dev/null  \nelse\n  filebrowser config init -a '0.0.0.0' &>/dev/null\n  filebrowser config set -a '0.0.0.0' &>/dev/null\n  filebrowser users add admin helper-scripts.com --perm.admin &>/dev/null\nfi\nmsg_ok \"Installed ${APP} on $hostname\"\n\nmsg_info \"Creating Service\"\ncat <<EOF >/etc/systemd/system/filebrowser.service\n[Unit]\nDescription=Filebrowser\nAfter=network-online.target\n\n[Service]\nUser=root\nWorkingDirectory=/root/\nExecStart=/usr/local/bin/filebrowser -r /\n\n[Install]\nWantedBy=default.target\nEOF\nsystemctl enable -q --now filebrowser.service\nmsg_ok \"Created Service\"\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://$IP:8080${CL} \\n\"\n"
  },
  {
    "path": "misc/frigate-support.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\n    clear\ncat <<\"EOF\"\n   ____    _           __        ____                        __\n  / __/___(_)__ ____ _/ /____   / __/_ _____  ___  ___  ____/ /_\n / _// __/ / _ `/ _ `/ __/ -_) _\\ \\/ // / _ \\/ _ \\/ _ \\/ __/ __/\n/_/ /_/ /_/\\_, /\\_,_/\\__/\\__/ /___/\\_,_/ .__/ .__/\\___/_/  \\__/\n          /___/                       /_/  /_/\nEOF\n}\nheader_info\nwhile true; do\n  read -p \"This will Prepare a LXC Container for Frigate. Proceed (y/n)?\" yn\n  case $yn in\n  [Yy]*) break ;;\n  [Nn]*) exit ;;\n  *) echo \"Please answer yes or no.\" ;;\n  esac\ndone\nheader_info\n\n# The array of device types\n# CHAR_DEVS+=(major:minor)\nCHAR_DEVS+=(\"1:1\") # mem\nCHAR_DEVS+=(\"29:0\") # fb0\nCHAR_DEVS+=(\"188:.*\") # ttyUSB*\nCHAR_DEVS+=(\"189:.*\") # bus/usb/*\nCHAR_DEVS+=(\"226:0\") # card0\nCHAR_DEVS+=(\"226:128\") # renderD128\n\n# Proccess char device string\nfor char_dev in ${CHAR_DEVS[@]}; do\n  [ ! -z \"${CHAR_DEV_STRING-}\" ] && CHAR_DEV_STRING+=\" -o\"\n  CHAR_DEV_STRING+=\" -regex \\\".*/${char_dev}\\\"\"\ndone\n\n# Store autodev hook script in a variable\nread -r -d '' HOOK_SCRIPT <<-EOF || true\nfor char_dev in \\$(find /sys/dev/char -regextype sed $CHAR_DEV_STRING); do\n  dev=\"/dev/\\$(sed -n \"/DEVNAME/ s/^.*=\\(.*\\)$/\\1/p\" \\${char_dev}/uevent)\";\n  mkdir -p \\$(dirname \\${LXC_ROOTFS_MOUNT}\\${dev});\n  for link in \\$(udevadm info --query=property \\$dev | sed -n \"s/DEVLINKS=//p\"); do\n    mkdir -p \\${LXC_ROOTFS_MOUNT}\\$(dirname \\$link);\n    cp -dpR \\$link \\${LXC_ROOTFS_MOUNT}\\${link};\n  done;\n  cp -dpR \\$dev \\${LXC_ROOTFS_MOUNT}\\${dev};\ndone;\nEOF\n\n# Remove newline char from the variable\nHOOK_SCRIPT=${HOOK_SCRIPT//$'\\n'/}\n\n# Generate menu of LXC containers in current node\nNODE=$(hostname)\nwhile read -r line; do\n  TAG=$(echo \"$line\" | awk '{print $1}')\n  ITEM=$(echo \"$line\" | awk '{print substr($0,36)}')\n  OFFSET=2\n  if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then\n    MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET))\n  fi\n  CTID_MENU+=(\"$TAG\" \"$ITEM \" \"OFF\")\ndone < <(pct list | awk 'NR>1')\n\n# Selection menu for LXC containers\nwhile [ -z \"${CTID:+x}\" ]; do\n  CTID=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"Containers on $NODE\" --radiolist \\\n    \"\\nSelect a container to add support:\\n\" \\\n    16 $(($MSG_MAX_LENGTH + 23)) 6 \\\n    \"${CTID_MENU[@]}\" 3>&1 1>&2 2>&3) || exit\ndone\n\n# Add autodev settings\nCTID_CONFIG_PATH=/etc/pve/lxc/${CTID}.conf\nsed '/autodev/d' $CTID_CONFIG_PATH >CTID.conf\ncat CTID.conf >$CTID_CONFIG_PATH\n\ncat <<EOF >>$CTID_CONFIG_PATH\nlxc.autodev: 1\nlxc.hook.autodev: bash -c '$HOOK_SCRIPT'\nEOF\necho -e \"\\e[1;33m \\nFinished....Reboot ${CTID} LXC to apply the changes.\\n \\e[0m\"\n\n# In the Proxmox web shell run\n# bash -c \"$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/frigate-support.sh)\"\n# Reboot the LXC to apply the changes"
  },
  {
    "path": "misc/fstrim.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info() {\n  clear\n  cat <<\"EOF\"\n    _______ __                     __                    ______     _\n   / ____(_) /__  _______  _______/ /____  ____ ___     /_  __/____(_)___ ___\n  / /_  / / / _ \\/ ___/ / / / ___/ __/ _ \\/ __ `__ \\     / / / ___/ / __ `__ \\\n / __/ / / /  __(__  ) /_/ (__  ) /_/  __/ / / / / /    / / / /  / / / / / / /\n/_/   /_/_/\\___/____/\\__, /____/\\__/\\___/_/ /_/ /_/    /_/ /_/  /_/_/ /_/ /_/\n                    /____/\nEOF\n}\nBL=$(echo \"\\033[36m\")\nRD=$(echo \"\\033[01;31m\")\nCM='\\xE2\\x9C\\x94\\033'\nGN=$(echo \"\\033[1;92m\")\nCL=$(echo \"\\033[m\")\nheader_info\necho \"Loading...\"\n\nROOT_FS=$(df -Th \"/\" | awk 'NR==2 {print $2}')\nif [ \"$ROOT_FS\" != \"ext4\" ]; then\n    echo \"Root filesystem is not ext4. Exiting script.\"\n    exit 1\nfi\n\nwhiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"Proxmox VE LXC Filesystem Trim\" --yesno \"The LXC containers will undergo the fstrim command. Proceed?\" 10 58 || exit\nNODE=$(hostname)\nEXCLUDE_MENU=()\nMSG_MAX_LENGTH=0\nwhile read -r TAG ITEM; do\n  OFFSET=2\n  ((${#ITEM} + OFFSET > MSG_MAX_LENGTH)) && MSG_MAX_LENGTH=${#ITEM}+OFFSET\n  EXCLUDE_MENU+=(\"$TAG\" \"$ITEM \" \"OFF\")\ndone < <(pct list | awk 'NR>1')\nexcluded_containers=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"Containers on $NODE\" --checklist \"\\nSelect containers to skip from trimming:\\n\" \\\n  16 $((MSG_MAX_LENGTH + 23)) 6 \"${EXCLUDE_MENU[@]}\" 3>&1 1>&2 2>&3 | tr -d '\"') || exit  \n\nfunction trim_container() {\n  local container=$1\n  header_info\n  echo -e \"${BL}[Info]${GN} Trimming ${BL}$container${CL} \\n\"\n  local before_trim=$(lvs | awk -F '[[:space:]]+' 'NR>1 && (/Data%|'\"vm-$container\"'/) {gsub(/%/, \"\", $7); print $7}')\n  echo -e \"${RD}Data before trim $before_trim%${CL}\"\n  pct fstrim $container\n  local after_trim=$(lvs | awk -F '[[:space:]]+' 'NR>1 && (/Data%|'\"vm-$container\"'/) {gsub(/%/, \"\", $7); print $7}')\n  echo -e \"${GN}Data after trim $after_trim%${CL}\"\n  sleep 1.5\n}\n\n\n\nfor container in $(pct list | awk '{if(NR>1) print $1}'); do\n  if [[ \" ${excluded_containers[@]} \" =~ \" $container \" ]]; then\n    header_info\n    echo -e \"${BL}[Info]${GN} Skipping ${BL}$container${CL}\"\n    sleep 1\n  else\n    template=$(pct config $container | grep -q \"template:\" && echo \"true\" || echo \"false\")\n    if [ \"$template\" == \"true\" ]; then\n      header_info\n      echo -e \"${BL}[Info]${GN} Skipping ${container} ${RD}$container is a template ${CL} \\n\"\n      sleep 1\n      continue\n    fi\n      trim_container $container\n  fi\ndone\n\nwait\nheader_info\necho -e \"${GN} Finished, LXC Containers Trimmed. ${CL} \\n\"\n"
  },
  {
    "path": "misc/glances.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\n    clear\n    cat <<\"EOF\"\n   ________\n  / ____/ /___ _____  ________  _____\n / / __/ / __ `/ __ \\/ ___/ _ \\/ ___/\n/ /_/ / / /_/ / / / / /__/  __(__  )\n\\____/_/\\__,_/_/ /_/\\___/\\___/____/\n\nEOF\n}\nIP=$(hostname -I | awk '{print $1}')\nYW=$(echo \"\\033[33m\")\nBL=$(echo \"\\033[36m\")\nRD=$(echo \"\\033[01;31m\")\nBGN=$(echo \"\\033[4;92m\")\nGN=$(echo \"\\033[1;92m\")\nDGN=$(echo \"\\033[32m\")\nCL=$(echo \"\\033[m\")\nBFR=\"\\\\r\\\\033[K\"\nHOLD=\" \"\nCM=\"${GN}✓${CL}\"\nAPP=\"Glances\"\nhostname=\"$(hostname)\"\nsilent() { \"$@\" >/dev/null 2>&1; }\nset -e\nspinner() {\n    local chars=\"/-\\|\"\n    local spin_i=0\n    printf \"\\e[?25l\"\n    while true; do\n        printf \"\\r \\e[36m%s\\e[0m\" \"${chars:spin_i++%${#chars}:1}\"\n        sleep 0.1\n    done\n}\n\nmsg_info() {\n  local msg=\"$1\"\n  echo -ne \" ${HOLD} ${YW}${msg}   \"\n  spinner &\n  SPINNER_PID=$!\n}\n\nmsg_ok() {\n  if [ -n \"$SPINNER_PID\" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi\n  printf \"\\e[?25h\"\n  local msg=\"$1\"\n  echo -e \"${BFR} ${CM} ${GN}${msg}${CL}\"\n}\n\ninstall() {\n  header_info\n  while true; do\n      read -p \"This will Install ${APP} on $hostname. Proceed(y/n)?\" yn\n      case $yn in\n      [Yy]*) break ;;\n      [Nn]*) exit ;;\n      *) echo \"Please answer yes or no.\" ;;\n      esac\n  done\n  header_info\n  read -r -p \"Verbose mode? <y/N> \" prompt\n  if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then\n  STD=\"\"\n  else\n  STD=\"silent\"\n  fi\n  msg_info \"Installing $APP\"\n  rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED\n  $STD bash -c \"$(wget -qLO - https://raw.githubusercontent.com/nicolargo/glancesautoinstall/master/install.sh)\"\n  cat <<EOF >/etc/systemd/system/glances.service\n[Unit]\nDescription=Glances - An eye on your system\nAfter=network.target\n\n[Service]\nType=simple\nExecStart=/usr/local/bin/glances -w\nRestart=on-failure\n\n[Install]\nWantedBy=multi-user.target\nEOF\n  systemctl enable -q --now glances.service\n  msg_ok \"Installed $APP on $hostname\"\n\n  echo -e \"${APP} should be reachable by going to the following URL.\n           ${BL}http://$IP:61208${CL} \\n\"\n}\nuninstall() {\n  header_info\n  msg_info \"Uninstalling $APP\"\n  if [ -n \"$SPINNER_PID\" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi\n  systemctl disable -q --now glances\n  bash -c \"$(wget -qLO - https://raw.githubusercontent.com/nicolargo/glancesautoinstall/master/uninstall.sh)\"\n  rm -rf /etc/systemd/system/glances.service\n  msg_ok \"Uninstalled $APP\"\n  msg_ok \"Completed Successfully!\\n\"\n}\n\nOPTIONS=(Install \"Install $APP\" \\\n         Uninstall \"Uninstall $APP\")\n\nCHOICE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"$APP\" --menu \"Select an option:\" 10 58 2 \\\n          \"${OPTIONS[@]}\" 3>&1 1>&2 2>&3)\n\ncase $CHOICE in\n  \"Install\")\n    install\n    ;;\n  \"Uninstall\")\n    uninstall\n    ;;\n  *)\n    echo \"Exiting...\"\n    exit 0\n    ;;\nesac\n"
  },
  {
    "path": "misc/host-backup.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\n  clear\n  cat <<\"EOF\"\n   __ __         __    ___           __\n  / // /__  ___ / /_  / _ )___ _____/ /____ _____\n / _  / _ \\(_-</ __/ / _  / _ `/ __/  '_/ // / _ \\\n/_//_/\\___/___/\\__/ /____/\\_,_/\\__/_/\\_\\\\_,_/ .__/\n                                           /_/\nEOF\n}\n\n# Function to perform backup\nfunction perform_backup {\n  local BACKUP_PATH\n  local DIR\n  local DIR_DASH\n  local BACKUP_FILE\n  local selected_directories=()\n\n  # Get backup path from user\n  BACKUP_PATH=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"\\nDefaults to /root/\\ne.g. /mnt/backups/\" 11 68 --title \"Directory to backup to:\" 3>&1 1>&2 2>&3) || return\n\n  # Default to /root/ if no input\n  BACKUP_PATH=\"${BACKUP_PATH:-/root/}\"\n\n  # Get directory to work in from user\n  DIR=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"\\nDefaults to /etc/\\ne.g. /root/, /var/lib/pve-cluster/ etc.\" 11 68 --title \"Directory to work in:\" 3>&1 1>&2 2>&3) || return\n\n  # Default to /etc/ if no input\n  DIR=\"${DIR:-/etc/}\"\n\n  DIR_DASH=$(echo \"$DIR\" | tr '/' '-')\n  BACKUP_FILE=\"$(hostname)${DIR_DASH}backup\"\n\n  # Build a list of directories for backup\n  local CTID_MENU=()\n  while read -r dir; do\n    CTID_MENU+=(\"$(basename \"$dir\")\" \"$dir \" \"OFF\")\n  done < <(ls -d \"${DIR}\"*)\n\n  # Allow the user to select directories\n  local HOST_BACKUP\n  while [ -z \"${HOST_BACKUP:+x}\" ]; do\n    HOST_BACKUP=$(whiptail --backtitle \"Proxmox VE Host Backup\" --title \"Working in the ${DIR} directory \" --checklist \\\n      \"\\nSelect what files/directories to backup:\\n\" 16 $(((${#DIRNAME} + 2) + 88)) 6 \"${CTID_MENU[@]}\" 3>&1 1>&2 2>&3) || return\n\n    for selected_dir in ${HOST_BACKUP//\\\"/}; do\n      selected_directories+=(\"${DIR}$selected_dir\")\n    done\n  done\n\n  # Perform the backup\n  header_info\n  echo -e \"This will create a backup in\\e[1;33m $BACKUP_PATH \\e[0mfor these files and directories\\e[1;33m ${selected_directories[*]} \\e[0m\"\n  read -p \"Press ENTER to continue...\"\n  header_info\n  echo \"Working...\"\n  tar -czf \"$BACKUP_PATH$BACKUP_FILE-$(date +%Y_%m_%d).tar.gz\" --absolute-names \"${selected_directories[@]}\"\n  header_info\n  echo -e \"\\nFinished\"\n  echo -e \"\\e[1;33m \\nA backup is rendered ineffective when it remains stored on the host.\\n \\e[0m\"\n  sleep 2\n}\n\n# Main script execution loop\nwhile true; do\n  if (whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"Proxmox VE Host Backup\" --yesno \"This will create backups for particular files and directories located within a designated directory. Proceed?\" 10 88); then\n    perform_backup\n  else\n    break\n  fi\ndone\n"
  },
  {
    "path": "misc/hw-acceleration.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n# Execute within the Proxmox shell\n# bash -c \"$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/hw-acceleration.sh)\"\n\nset -e\nfunction header_info {\n  clear\n  cat <<\"EOF\"\n\n   __ ___      __  ___              __             __  _\n  / // / | /| / / / _ |___________ / /__ _______ _/ /_(_)__  ___\n / _  /| |/ |/ / / __ / __/ __/ -_) / -_) __/ _ `/ __/ / _ \\/ _ \\\n/_//_/ |__/|__/ /_/ |_\\__/\\__/\\__/_/\\__/_/  \\_,_/\\__/_/\\___/_//_/\n\nEOF\n}\n\nYW=$(echo \"\\033[33m\")\nBL=$(echo \"\\033[36m\")\nRD=$(echo \"\\033[01;31m\")\nGN=$(echo \"\\033[1;92m\")\nCL=$(echo \"\\033[m\")\nBFR=\"\\\\r\\\\033[K\"\nHOLD=\"-\"\nCM=\"${GN}✓${CL}\"\nset -e\nheader_info\necho \"Loading...\"\nfunction msg_info() {\n  local msg=\"$1\"\n  echo -ne \" ${HOLD} ${YW}${msg}...\"\n}\n\nfunction msg_ok() {\n  local msg=\"$1\"\n  echo -e \"${BFR} ${CM} ${GN}${msg}${CL}\"\n}\n\nif ! pveversion | grep -Eq \"pve-manager/(8\\.[1-3])\"; then\n  msg_error \"This version of Proxmox Virtual Environment is not supported\"\n  echo -e \"Requires PVE Version 8.1 or higher\"\n  echo -e \"Exiting...\"\n  sleep 2\n  exit\nfi\n\nwhiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"Add Intel HW Acceleration\" --yesno \"This Will Add Intel HW Acceleration to an existing LXC Container. Proceed?\" 8 72 || exit\nNODE=$(hostname)\nPREV_MENU=()\nMSG_MAX_LENGTH=0\nprivileged_containers=$(pct list | awk 'NR>1 && system(\"grep -q \\047unprivileged: 1\\047 /etc/pve/lxc/\" $1 \".conf\")')\n\nif [ -z \"$privileged_containers\" ]; then\n    whiptail --msgbox \"No Privileged Containers Found.\" 10 58\n    exit\nfi\n\nwhile read -r TAG ITEM; do\n  OFFSET=2\n  ((${#ITEM} + OFFSET > MSG_MAX_LENGTH)) && MSG_MAX_LENGTH=${#ITEM}+OFFSET\n  PREV_MENU+=(\"$TAG\" \"$ITEM \" \"OFF\")\ndone < <(echo \"$privileged_containers\")\n\nprivileged_container=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"Privileged Containers on $NODE\" --checklist \"\\nSelect a Container To Add Intel HW Acceleration:\\n\" 16 $((MSG_MAX_LENGTH + 23)) 6 \"${PREV_MENU[@]}\" 3>&1 1>&2 2>&3 | tr -d '\"') || exit\nheader_info\nread -r -p \"Verbose mode? <y/N> \" prompt\n  if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then\n  STD=\"\"\n  else\n  STD=\"silent\"\n  fi\nheader_info\n\ncat <<EOF >>/etc/pve/lxc/${privileged_container}.conf\nlxc.cgroup2.devices.allow: c 226:0 rwm\nlxc.cgroup2.devices.allow: c 226:128 rwm\nlxc.cgroup2.devices.allow: c 29:0 rwm\nlxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file\nlxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir\nlxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file\nEOF\n\nread -r -p \"Do you need the intel-media-va-driver-non-free driver (Debian 12 only)? <y/N> \" prompt\nif [[ ${prompt,,} =~ ^(y|yes)$ ]]; then\n  header_info\n  msg_info \"Installing Hardware Acceleration (non-free)\"\n  pct exec ${privileged_container} -- bash -c \"cat <<EOF >/etc/apt/sources.list.d/non-free.list\n\ndeb http://deb.debian.org/debian bookworm main contrib non-free non-free-firmware\ndeb-src http://deb.debian.org/debian bookworm main contrib non-free non-free-firmware\n\ndeb http://deb.debian.org/debian-security bookworm-security main contrib non-free non-free-firmware\ndeb-src http://deb.debian.org/debian-security bookworm-security main contrib non-free non-free-firmware\n\ndeb http://deb.debian.org/debian bookworm-updates main contrib non-free non-free-firmware\ndeb-src http://deb.debian.org/debian bookworm-updates main contrib non-free non-free-firmware\nEOF\"\n\n  pct exec ${privileged_container} -- bash -c \"silent() { \\\"\\$@\\\" >/dev/null 2>&1; } && $STD apt-get update && $STD apt-get install -y intel-media-va-driver-non-free ocl-icd-libopencl1 intel-opencl-icd vainfo intel-gpu-tools && $STD adduser \\$(id -u -n) video && $STD adduser \\$(id -u -n) render\"\n  msg_ok \"Installed Hardware Acceleration (non-free)\"\nelse\n  header_info\n  msg_info \"Installing Hardware Acceleration\"\n  pct exec ${privileged_container} -- bash -c \"silent() { \\\"\\$@\\\" >/dev/null 2>&1; } && $STD apt-get install -y va-driver-all ocl-icd-libopencl1 intel-opencl-icd vainfo intel-gpu-tools && chgrp video /dev/dri && chmod 755 /dev/dri && $STD adduser \\$(id -u -n) video && $STD adduser \\$(id -u -n) render\"\n  msg_ok \"Installed Hardware Acceleration\"\nfi\nsleep 1\nwhiptail --backtitle \"Proxmox VE Helper Scripts\" --msgbox --title \"Added tools\" \"vainfo, execute command 'vainfo'\\nintel-gpu-tools, execute command 'intel_gpu_top'\" 8 58\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"Reboot container ${BL}$privileged_container${CL} to apply the new settings\\n\"\n"
  },
  {
    "path": "misc/install.func",
    "content": "# This function sets color variables for formatting output in the terminal\ncolor() {\n  YW=$(echo \"\\033[33m\")\n  BL=$(echo \"\\033[36m\")\n  RD=$(echo \"\\033[01;31m\")\n  BGN=$(echo \"\\033[4;92m\")\n  GN=$(echo \"\\033[1;92m\")\n  DGN=$(echo \"\\033[32m\")\n  CL=$(echo \"\\033[m\")\n  RETRY_NUM=10\n  RETRY_EVERY=3\n  CM=\"${GN}✓${CL}\"\n  CROSS=\"${RD}✗${CL}\"\n  BFR=\"\\\\r\\\\033[K\"\n  HOLD=\" \"\n}\n\n# This function enables IPv6 if it's not disabled and sets verbose mode if the global variable is set to \"yes\"\nverb_ip6() {\n  if [ \"$VERBOSE\" = \"yes\" ]; then\n    STD=\"\"\n  else STD=\"silent\"; fi\n  silent() { \"$@\" >/dev/null 2>&1; }\n  if [ \"$DISABLEIPV6\" == \"yes\" ]; then\n    echo \"net.ipv6.conf.all.disable_ipv6 = 1\" >>/etc/sysctl.conf\n    $STD sysctl -p\n  fi\n}\n\n# This function sets error handling options and defines the error_handler function to handle errors\ncatch_errors() {\n  set -Eeuo pipefail\n  trap 'error_handler $LINENO \"$BASH_COMMAND\"' ERR\n}\n\n# This function handles errors\nerror_handler() {\n  if [ -n \"$SPINNER_PID\" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi\n  printf \"\\e[?25h\"\n  local exit_code=\"$?\"\n  local line_number=\"$1\"\n  local command=\"$2\"\n  local error_message=\"${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}\"\n  echo -e \"\\n$error_message\"\n  if [[ \"$line_number\" -eq 23 ]]; then\n    echo -e \"The silent function has suppressed the error, run the script with verbose mode enabled, which will provide more detailed output.\\n\"\n  fi\n}\n\n# This function displays a spinner.\nspinner() {\n    local chars=\"/-\\|\"\n    local spin_i=0\n    printf \"\\e[?25l\"\n    while true; do\n        printf \"\\r \\e[36m%s\\e[0m\" \"${chars:spin_i++%${#chars}:1}\"\n        sleep 0.1\n    done\n}\n\n# This function displays an informational message with a yellow color.\nmsg_info() {\n  local msg=\"$1\"\n  echo -ne \" ${HOLD} ${YW}${msg}   \"\n  spinner &\n  SPINNER_PID=$!\n}\n\n\n# This function displays a success message with a green color.\nmsg_ok() {\n  if [ -n \"$SPINNER_PID\" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi\n  printf \"\\e[?25h\"\n  local msg=\"$1\"\n  echo -e \"${BFR} ${CM} ${GN}${msg}${CL}\"\n}\n\n# This function displays a error message with a red color.\nmsg_error() {\n  if [ -n \"$SPINNER_PID\" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi\n  printf \"\\e[?25h\"\n  local msg=\"$1\"\n  echo -e \"${BFR} ${CROSS} ${RD}${msg}${CL}\"\n}\n\n# This function sets up the Container OS by generating the locale, setting the timezone, and checking the network connection\nsetting_up_container() {\n  msg_info \"Setting up Container OS\"\n  sed -i \"/$LANG/ s/\\(^# \\)//\" /etc/locale.gen\n  locale_line=$(grep -v '^#' /etc/locale.gen | grep -E '^[a-zA-Z]' | awk '{print $1}' | head -n 1)\n  echo \"LANG=${locale_line}\" >/etc/default/locale\n  locale-gen >/dev/null\n  export LANG=${locale_line}\n  echo $tz >/etc/timezone\n  ln -sf /usr/share/zoneinfo/$tz /etc/localtime\n  for ((i = RETRY_NUM; i > 0; i--)); do\n    if [ \"$(hostname -I)\" != \"\" ]; then\n      break\n    fi\n    echo 1>&2 -en \"${CROSS}${RD} No Network! \"\n    sleep $RETRY_EVERY\n  done\n  if [ \"$(hostname -I)\" = \"\" ]; then\n    echo 1>&2 -e \"\\n${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}\"\n    echo -e \" 🖧  Check Network Settings\"\n    exit 1\n  fi\n  rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED\n  systemctl disable -q --now systemd-networkd-wait-online.service\n  msg_ok \"Set up Container OS\"\n  msg_ok \"Network Connected: ${BL}$(hostname -I)\"\n}\n\n# This function checks the network connection by pinging a known IP address and prompts the user to continue if the internet is not connected\nnetwork_check() {\n  set +e\n  trap - ERR\n  ipv4_connected=false\n  ipv6_connected=false\n  sleep 1\n# Check IPv4 connectivity\n  if ping -c 1 -W 1 1.1.1.1 &>/dev/null; then \n    msg_ok \"IPv4 Internet Connected\";\n    ipv4_connected=true\n  else\n    msg_error \"IPv4 Internet Not Connected\";\n  fi\n\n# Check IPv6 connectivity\n  if ping6 -c 1 -W 1 2606:4700:4700::1111 &>/dev/null; then\n    msg_ok \"IPv6 Internet Connected\";\n    ipv6_connected=true\n  else\n    msg_error \"IPv6 Internet Not Connected\";\n  fi\n\n# If both IPv4 and IPv6 checks fail, prompt the user\n  if [[ $ipv4_connected == false && $ipv6_connected == false ]]; then\n    read -r -p \"No Internet detected,would you like to continue anyway? <y/N> \" prompt\n    if [[ \"${prompt,,}\" =~ ^(y|yes)$ ]]; then\n      echo -e \" ⚠️  ${RD}Expect Issues Without Internet${CL}\"\n    else\n      echo -e \" 🖧  Check Network Settings\"\n      exit 1\n    fi\n  fi\n\n  RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }')\n  if [[ -z \"$RESOLVEDIP\" ]]; then msg_error \"DNS Lookup Failure\"; else msg_ok \"DNS Resolved github.com to ${BL}$RESOLVEDIP${CL}\"; fi\n  set -e\n  trap 'error_handler $LINENO \"$BASH_COMMAND\"' ERR\n}\n\n# This function updates the Container OS by running apt-get update and upgrade\nupdate_os() {\n  msg_info \"Updating Container OS\"\n  if [[ \"$CACHER\" == \"yes\" ]]; then\n    echo \"Acquire::http::Proxy-Auto-Detect \\\"/usr/local/bin/apt-proxy-detect.sh\\\";\" >/etc/apt/apt.conf.d/00aptproxy\n    cat <<EOF >/usr/local/bin/apt-proxy-detect.sh\n#!/bin/bash\nif nc -w1 -z \"${CACHER_IP}\" 3142; then\n  echo -n \"http://${CACHER_IP}:3142\"\nelse\n  echo -n \"DIRECT\"\nfi\nEOF\n  chmod +x /usr/local/bin/apt-proxy-detect.sh\n  fi\n  $STD apt-get update\n  $STD apt-get -o Dpkg::Options::=\"--force-confold\" -y dist-upgrade\n  rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED\n  msg_ok \"Updated Container OS\"\n}\n\n# This function modifies the message of the day (motd) and SSH settings\nmotd_ssh() {\n  echo \"export TERM='xterm-256color'\" >>/root/.bashrc\n  echo -e \"$APPLICATION LXC provided by https://helper-scripts.com/\\n\" >/etc/motd\n  chmod -x /etc/update-motd.d/*\n  if [[ \"${SSH_ROOT}\" == \"yes\" ]]; then\n    sed -i \"s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g\" /etc/ssh/sshd_config\n    systemctl restart sshd\n  fi\n}\n\n# This function customizes the container by modifying the getty service and enabling auto-login for the root user\ncustomize() {\n  if [[ \"$PASSWORD\" == \"\" ]]; then\n    msg_info \"Customizing Container\"\n    GETTY_OVERRIDE=\"/etc/systemd/system/container-getty@1.service.d/override.conf\"\n    mkdir -p $(dirname $GETTY_OVERRIDE)\n    cat <<EOF >$GETTY_OVERRIDE\n  [Service]\n  ExecStart=\n  ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \\$TERM\nEOF\n    systemctl daemon-reload\n    systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\\.d//')\n    msg_ok \"Customized Container\"\n  fi\n  echo \"bash -c \\\"\\$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/${app}.sh)\\\"\" >/usr/bin/update\n  chmod +x /usr/bin/update\n}\n"
  },
  {
    "path": "misc/kernel-clean.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\n  clear\n  cat <<\"EOF\"\n    __ __                     __   ________\n   / //_/__  _________  ___  / /  / ____/ /__  ____ _____\n  / ,< / _ \\/ ___/ __ \\/ _ \\/ /  / /   / / _ \\/ __ `/ __ \\\n / /| /  __/ /  / / / /  __/ /  / /___/ /  __/ /_/ / / / /\n/_/ |_\\___/_/  /_/ /_/\\___/_/   \\____/_/\\___/\\__,_/_/ /_/\n\nEOF\n}\nYW=$(echo \"\\033[33m\")\nRD=$(echo \"\\033[01;31m\")\nGN=$(echo \"\\033[1;92m\")\nCL=$(echo \"\\033[m\")\nBFR=\"\\\\r\\\\033[K\"\nHOLD=\"-\"\nCM=\"${GN}✓${CL}\"\ncurrent_kernel=$(uname -r)\navailable_kernels=$(dpkg --list | grep 'kernel-.*-pve' | awk '{print $2}' | grep -v \"$current_kernel\" | sort -V)\nheader_info\n\nfunction msg_info() {\n  local msg=\"$1\"\n  echo -ne \" ${HOLD} ${YW}${msg}...\"\n}\n\nfunction msg_ok() {\n  local msg=\"$1\"\n  echo -e \"${BFR} ${CM} ${GN}${msg}${CL}\"\n}\n\nwhiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"Proxmox VE Kernel Clean\" --yesno \"This will Clean Unused Kernel Images, USE AT YOUR OWN RISK. Proceed?\" 10 68 || exit\nif [ -z \"$available_kernels\" ]; then\n  whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"No Old Kernels\" --msgbox \"It appears there are no old Kernels on your system. \\nCurrent kernel ($current_kernel).\" 10 68\n  echo \"Exiting...\"\n  sleep 2\n  clear\n  exit\nfi\n  KERNEL_MENU=()\n  MSG_MAX_LENGTH=0\nwhile read -r TAG ITEM; do\n  OFFSET=2\n  ((${#ITEM} + OFFSET > MSG_MAX_LENGTH)) && MSG_MAX_LENGTH=${#ITEM}+OFFSET\n  KERNEL_MENU+=(\"$TAG\" \"$ITEM \" \"OFF\")\ndone < <(echo \"$available_kernels\")\n\nremove_kernels=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"Current Kernel $current_kernel\" --checklist \"\\nSelect Kernels to remove:\\n\" 16 $((MSG_MAX_LENGTH + 58)) 6 \"${KERNEL_MENU[@]}\" 3>&1 1>&2 2>&3 | tr -d '\"') || exit\n[ -z \"$remove_kernels\" ] && {\n  whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"No Kernel Selected\" --msgbox \"It appears that no Kernel was selected\" 10 68\n  echo \"Exiting...\"\n  sleep 2\n  clear\n  exit\n}\nwhiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"Remove Kernels\" --yesno \"Would you like to remove the $(echo $remove_kernels | awk '{print NF}') previously selected Kernels?\" 10 68 || exit\n\nmsg_info \"Removing ${CL}${RD}$(echo $remove_kernels | awk '{print NF}') ${CL}${YW}old Kernels${CL}\"\n/usr/bin/apt purge -y $remove_kernels >/dev/null 2>&1\nmsg_ok \"Successfully Removed Kernels\"\n\nmsg_info \"Updating GRUB\"\n/usr/sbin/update-grub >/dev/null 2>&1\nmsg_ok \"Successfully Updated GRUB\"\nmsg_info \"Exiting\"\nsleep 2\nmsg_ok \"Finished\"\n"
  },
  {
    "path": "misc/kernel-pin.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\n  clear\n  cat <<\"EOF\"\n    __ __                     __   ____  _\n   / //_/__  _________  ___  / /  / __ \\(_)___\n  / ,< / _ \\/ ___/ __ \\/ _ \\/ /  / /_/ / / __ \\\n / /| /  __/ /  / / / /  __/ /  / ____/ / / / /\n/_/ |_\\___/_/  /_/ /_/\\___/_/  /_/   /_/_/ /_/\n\nEOF\n}\nYW=$(echo \"\\033[33m\")\nRD=$(echo \"\\033[01;31m\")\nGN=$(echo \"\\033[1;92m\")\nCL=$(echo \"\\033[m\")\nBFR=\"\\\\r\\\\033[K\"\nHOLD=\"-\"\nCM=\"${GN}✓${CL}\"\ncurrent_kernel=$(uname -r)\navailable_kernels=$(dpkg --list | grep 'kernel-.*-pve' | awk '{print substr($2, 16, length($2)-22)}')\nheader_info\n\nfunction msg_info() {\n  local msg=\"$1\"\n  echo -ne \" ${HOLD} ${YW}${msg}...\"\n}\n\nfunction msg_ok() {\n  local msg=\"$1\"\n  echo -e \"${BFR} ${CM} ${GN}${msg}${CL}\"\n}\n\nwhiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"Proxmox VE Kernel Pin\" --yesno \"This will Pin/Unpin Kernel Images, Proceed?\" 10 68 || exit\n\n  KERNEL_MENU=()\n  MSG_MAX_LENGTH=0\nwhile read -r TAG ITEM; do\n  OFFSET=2\n  ((${#ITEM} + OFFSET > MSG_MAX_LENGTH)) && MSG_MAX_LENGTH=${#ITEM}+OFFSET\n  KERNEL_MENU+=(\"$TAG\" \"$ITEM \" \"OFF\")\ndone < <(echo \"$available_kernels\")\n\npin_kernel=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"Current Kernel $current_kernel\" --radiolist \"\\nSelect Kernel to pin:\\nCancel to Unpin any Kernel\" 16 $((MSG_MAX_LENGTH + 58)) 6 \"${KERNEL_MENU[@]}\" 3>&1 1>&2 2>&3 | tr -d '\"') || exit\n[ -z \"$pin_kernel\" ] && {\n  whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"No Kernel Selected\" --msgbox \"It appears that no Kernel was selected\\nUnpinning any pinned Kernel\" 10 68\n  msg_info \"Unpinning any Kernel\"\n  proxmox-boot-tool kernel unpin &>/dev/null\n  msg_ok \"Unpinned any Kernel\\n\"\n  proxmox-boot-tool kernel list\n  echo \"\"\n  msg_ok \"Finished\\n\"\n  echo -e \"${RD} REBOOT${CL}\"\n  exit\n}\nwhiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"Proxmox VE Kernel Pin\" --yesno \"Would you like to pin the $pin_kernel Kernel?\" 10 68 || exit\n\nmsg_info \"Pinning $pin_kernel\"\nproxmox-boot-tool kernel pin $pin_kernel &>/dev/null\nmsg_ok \"Successfully Pinned $pin_kernel\\n\"\nproxmox-boot-tool kernel list\necho \"\"\nmsg_ok \"Finished\\n\"\necho -e \"${RD} REBOOT${CL}\"\n"
  },
  {
    "path": "misc/microcode.sh",
    "content": "#!/usr/bin/env bash\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\n  clear\n  cat <<\"EOF\"\n    ____                                               __  ____                                __\n   / __ \\_________  ________  ______________  _____   /  |/  (_)_____________  _________  ____/ /__\n  / /_/ / ___/ __ \\/ ___/ _ \\/ ___/ ___/ __ \\/ ___/  / /|_/ / / ___/ ___/ __ \\/ ___/ __ \\/ __  / _ \\\n / ____/ /  / /_/ / /__/  __(__  |__  ) /_/ / /     / /  / / / /__/ /  / /_/ / /__/ /_/ / /_/ /  __/\n/_/   /_/   \\____/\\___/\\___/____/____/\\____/_/     /_/  /_/_/\\___/_/   \\____/\\___/\\____/\\__,_/\\___/\n\nEOF\n}\n\nRD=$(echo \"\\033[01;31m\")\nYW=$(echo \"\\033[33m\")\nGN=$(echo \"\\033[1;92m\")\nCL=$(echo \"\\033[m\")\nBFR=\"\\\\r\\\\033[K\"\nHOLD=\"-\"\nCM=\"${GN}✓${CL}\"\nCROSS=\"${RD}✗${CL}\"\n\nmsg_info() { echo -ne \" ${HOLD} ${YW}$1...\"; }\nmsg_ok() { echo -e \"${BFR} ${CM} ${GN}$1${CL}\"; }\nmsg_error() { echo -e \"${BFR} ${CROSS} ${RD}$1${CL}\"; }\n\nheader_info\ncurrent_microcode=$(journalctl -k | grep -i 'microcode: Current revision:' | grep -oP 'Current revision: \\K0x[0-9a-f]+')\n[ -z \"$current_microcode\" ] && current_microcode=\"Not found.\"\n\nintel() {\n  if ! dpkg -s iucode-tool >/dev/null 2>&1; then\n    msg_info \"Installing iucode-tool (Intel microcode updater)\"\n    apt-get install -y iucode-tool &>/dev/null\n    msg_ok \"Installed iucode-tool\"\n  else\n    msg_ok \"Intel iucode-tool is already installed\"\n    sleep 1\n  fi\n\n  intel_microcode=$(curl -fsSL \"https://ftp.debian.org/debian/pool/non-free-firmware/i/intel-microcode//\" | grep -o 'href=\"[^\"]*amd64.deb\"' | sed 's/href=\"//;s/\"//')\n  [ -z \"$intel_microcode\" ] && { whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"No Microcode Found\" --msgbox \"It appears there were no microcode packages found\\n Try again later.\" 10 68; msg_info \"Exiting\"; sleep 1; msg_ok \"Done\"; exit; }\n\n  MICROCODE_MENU=()\n  MSG_MAX_LENGTH=0\n\n  while read -r TAG ITEM; do\n    OFFSET=2\n    (( ${#ITEM} + OFFSET > MSG_MAX_LENGTH )) && MSG_MAX_LENGTH=${#ITEM}+OFFSET\n    MICROCODE_MENU+=(\"$TAG\" \"$ITEM \" \"OFF\")\n  done < <(echo \"$intel_microcode\")\n\n  microcode=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"Current Microcode revision:${current_microcode}\" --radiolist \"\\nSelect a microcode package to install:\\n\" 16 $((MSG_MAX_LENGTH + 58)) 6 \"${MICROCODE_MENU[@]}\" 3>&1 1>&2 2>&3 | tr -d '\"') || exit\n\n  [ -z \"$microcode\" ] && { whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"No Microcode Selected\" --msgbox \"It appears that no microcode packages were selected\" 10 68; msg_info \"Exiting\"; sleep 1; msg_ok \"Done\"; exit; }\n\n  msg_info \"Downloading the Intel Processor Microcode Package $microcode\"\n  wget -q http://ftp.debian.org/debian/pool/non-free-firmware/i/intel-microcode/$microcode\n  msg_ok \"Downloaded the Intel Processor Microcode Package $microcode\"\n\n  msg_info \"Installing $microcode (Patience)\"\n  dpkg -i $microcode &>/dev/null\n  msg_ok \"Installed $microcode\"\n\n  msg_info \"Cleaning up\"\n  rm $microcode\n  msg_ok \"Cleaned\"\n  echo -e \"\\nIn order to apply the changes, a system reboot will be necessary.\\n\"\n}\n\namd() {\n  amd_microcode=$(curl -fsSL \"https://ftp.debian.org/debian/pool/non-free-firmware/a/amd64-microcode///\" | grep -o 'href=\"[^\"]*amd64.deb\"' | sed 's/href=\"//;s/\"//')\n\n  [ -z \"$amd_microcode\" ] && { whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"No Microcode Found\" --msgbox \"It appears there were no microcode packages found\\n Try again later.\" 10 68; msg_info \"Exiting\"; sleep 1; msg_ok \"Done\"; exit; }\n\n  MICROCODE_MENU=()\n  MSG_MAX_LENGTH=0\n\n  while read -r TAG ITEM; do\n    OFFSET=2\n    (( ${#ITEM} + OFFSET > MSG_MAX_LENGTH )) && MSG_MAX_LENGTH=${#ITEM}+OFFSET\n    MICROCODE_MENU+=(\"$TAG\" \"$ITEM \" \"OFF\")\n  done < <(echo \"$amd_microcode\")\n\n  microcode=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"Current Microcode revision:${current_microcode}\" --radiolist \"\\nSelect a microcode package to install:\\n\" 16 $((MSG_MAX_LENGTH + 58)) 6 \"${MICROCODE_MENU[@]}\" 3>&1 1>&2 2>&3 | tr -d '\"') || exit\n\n  [ -z \"$microcode\" ] && { whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"No Microcode Selected\" --msgbox \"It appears that no microcode packages were selected\" 10 68; msg_info \"Exiting\"; sleep 1; msg_ok \"Done\"; exit; }\n\n  msg_info \"Downloading the AMD Processor Microcode Package $microcode\"\n  wget -q https://ftp.debian.org/debian/pool/non-free-firmware/a/amd64-microcode/$microcode\n  msg_ok \"Downloaded the AMD Processor Microcode Package $microcode\"\n\n  msg_info \"Installing $microcode (Patience)\"\n  dpkg -i $microcode &>/dev/null\n  msg_ok \"Installed $microcode\"\n\n  msg_info \"Cleaning up\"\n  rm $microcode\n  msg_ok \"Cleaned\"\n  echo -e \"\\nIn order to apply the changes, a system reboot will be necessary.\\n\"\n}\n\nif ! command -v pveversion >/dev/null 2>&1; then header_info; msg_error \"No PVE Detected!\"; exit; fi\n\nwhiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"Proxmox VE Processor Microcode\" --yesno \"This will check for CPU microcode packages with the option to install. Proceed?\" 10 58 || exit\n\nmsg_info \"Checking CPU Vendor\"\ncpu=$(lscpu | grep -oP 'Vendor ID:\\s*\\K\\S+' | head -n 1)\nif [ \"$cpu\" == \"GenuineIntel\" ]; then\n  msg_ok \"${cpu} was detected\"\n  sleep 1\n  intel\nelif [ \"$cpu\" == \"AuthenticAMD\" ]; then\n  msg_ok \"${cpu} was detected\"\n  sleep 1\n  amd\nelse\n  msg_error \"${cpu} is not supported\"\n  exit\nfi\n"
  },
  {
    "path": "misc/monitor-all.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nclear\ncat <<\"EOF\"\n    __  ___            _ __                ___    ____\n   /  |/  /___  ____  (_) /_____  _____   /   |  / / /\n  / /|_/ / __ \\/ __ \\/ / __/ __ \\/ ___/  / /| | / / /\n / /  / / /_/ / / / / / /_/ /_/ / /     / ___ |/ / /\n/_/  /_/\\____/_/ /_/_/\\__/\\____/_/     /_/  |_/_/_/\n\nEOF\n\nadd() {\nwhile true; do\n  read -p \"This script will add Monitor All to Proxmox VE. Proceed(y/n)?\" yn\n  case $yn in\n  [Yy]*) break ;;\n  [Nn]*) exit ;;\n  *) echo \"Please answer yes or no.\" ;;\n  esac\ndone\n\necho '#!/usr/bin/env bash\n# Read excluded instances from command line arguments\nexcluded_instances=(\"$@\")\necho \"Excluded instances: ${excluded_instances[@]}\"\n\nwhile true; do\n\n  for instance in $(pct list | awk '\\''{if(NR>1) print $1}'\\''; qm list | awk '\\''{if(NR>1) print $1}'\\''); do\n    # Skip excluded instances\n    if [[ \" ${excluded_instances[@]} \" =~ \" ${instance} \" ]]; then\n      echo \"Skipping $instance because it is excluded\"\n      continue\n    fi\n\n    # Determine the type of the instance (container or virtual machine)\n    if pct status $instance >/dev/null 2>&1; then\n      # It is a container\n      config_cmd=\"pct config\"\n      IP=$(pct exec $instance ip a s dev eth0 | awk '\\''/inet / {print $2}'\\'' | cut -d/ -f1)\n    else\n      # It is a virtual machine\n      config_cmd=\"qm config\"\n      IP=$(qm guest cmd $instance network-get-interfaces | egrep -o \"([0-9]{1,3}\\.){3}[0-9]{1,3}\" | grep -E \"192\\.|10\\.\" | head -n 1)\n    fi\n\n    # Skip instances based on onboot and templates\n    onboot=$($config_cmd $instance | grep -q \"onboot: 0\" || ( ! $config_cmd $instance | grep -q \"onboot\" ) && echo \"true\" || echo \"false\")\n    template=$($config_cmd $instance | grep template | grep -q \"template:\" && echo \"true\" || echo \"false\")\n\n    if [ \"$onboot\" == \"true\" ]; then\n      echo \"Skipping $instance because it is set not to boot\"\n      continue\n    elif [ \"$template\" == \"true\" ]; then\n      echo \"Skipping $instance because it is a template\"\n      continue\n    fi\n\n    # Ping the instance\n    if ! ping -c 1 $IP >/dev/null 2>&1; then\n      # If the instance can not be pinged, stop and start it\n      if pct status $instance >/dev/null 2>&1; then\n        # It is a container\n        echo \"$(date): CT $instance is not responding, restarting...\"\n        pct stop $instance >/dev/null 2>&1\n        sleep 5\n        pct start $instance >/dev/null 2>&1\n      else\n        # It is a virtual machine\n        if qm status $instance | grep -q \"status: running\"; then\n          echo \"$(date): VM $instance is not responding, restarting...\"\n          qm stop $instance >/dev/null 2>&1\n          sleep 5\n        else\n          echo \"$(date): VM $instance is not running, starting...\"\n        fi\n        qm start $instance >/dev/null 2>&1\n      fi\n    fi\n  done\n\n  # Wait for 5 minutes. (Edit to your needs)\n  echo \"$(date): Pausing for 5 minutes...\"\n  sleep 300\ndone >/var/log/ping-instances.log 2>&1' >/usr/local/bin/ping-instances.sh\ntouch /var/log/ping-instances.log\n# Change file permissions to executable\nchmod +x /usr/local/bin/ping-instances.sh\ncat <<EOF >/etc/systemd/system/ping-instances.timer\n[Unit]\nDescription=Delay ping-instances.service by 5 minutes\n\n[Timer]\nOnBootSec=300\nOnUnitActiveSec=300\n\n[Install]\nWantedBy=timers.target\nEOF\n\n# Create ping-instances.service\ncat <<EOF >/etc/systemd/system/ping-instances.service\n[Unit]\nDescription=Ping instances every 5 minutes and restarts if necessary\nAfter=ping-instances.timer\nRequires=ping-instances.timer\n[Service]\nType=simple\n# To specify which CT/VM should be excluded, add the CT/VM ID at the end of the line where ExecStart=/usr/local/bin/ping-instances.sh is specified.\n# For example: ExecStart=/usr/local/bin/ping-instances.sh 100 102\n# Virtual machines without the QEMU guest agent installed must be excluded.\n\nExecStart=/usr/local/bin/ping-instances.sh\nRestart=always\nStandardOutput=file:/var/log/ping-instances.log\nStandardError=file:/var/log/ping-instances.log\n\n[Install]\nWantedBy=multi-user.target\nEOF\n\n# Reload daemon, enable and start ping-instances.service\nsystemctl daemon-reload\nsystemctl enable -q --now ping-instances.timer\nsystemctl enable -q --now ping-instances.service\nclear\necho -e \"\\n To view Monitor All logs: cat /var/log/ping-instances.log\"\n}\n\nremove() {\n  systemctl disable -q --now ping-instances.timer\n  systemctl disable -q --now ping-instances.service\n  rm /etc/systemd/system/ping-instances.service /etc/systemd/system/ping-instances.timer /usr/local/bin/ping-instances.sh /var/log/ping-instances.log\n  echo \"Removed Monitor All from Proxmox VE\"\n}\n\n# Define options for the whiptail menu\nOPTIONS=(Add \"Add Monitor-All to Proxmox VE\" \\\n         Remove \"Remove Monitor-All from Proxmox VE\")\n\n# Show the whiptail menu and save the user's choice\nCHOICE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"Monitor-All for Proxmox VE\" --menu \"Select an option:\" 10 58 2 \\\n          \"${OPTIONS[@]}\" 3>&1 1>&2 2>&3)\n\n# Check the user's choice and perform the corresponding action\ncase $CHOICE in\n  \"Add\")\n    add\n    ;;\n  \"Remove\")\n    remove\n    ;;\n  *)\n    echo \"Exiting...\"\n    exit 0\n    ;;\nesac\n"
  },
  {
    "path": "misc/netdata.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\n    clear\n    cat <<\"EOF\"\n    _   __     __  ____        __\n   / | / /__  / /_/ __ \\____ _/ /_____ _\n  /  |/ / _ \\/ __/ / / / __ `/ __/ __ `/\n / /|  /  __/ /_/ /_/ / /_/ / /_/ /_/ /\n/_/ |_/\\___/\\__/_____/\\__,_/\\__/\\__,_/\n\nEOF\n}\n\nYW=$(echo \"\\033[33m\")\nBL=$(echo \"\\033[36m\")\nRD=$(echo \"\\033[01;31m\")\nGN=$(echo \"\\033[1;92m\")\nCL=$(echo \"\\033[m\")\nBFR=\"\\\\r\\\\033[K\"\nHOLD=\"-\"\nCM=\"${GN}✓${CL}\"\nsilent() { \"$@\" >/dev/null 2>&1; }\nset -e\nheader_info\necho \"Loading...\"\nfunction msg_info() {\n  local msg=\"$1\"\n  echo -ne \" ${HOLD} ${YW}${msg}...\"\n}\n\nfunction msg_ok() {\n  local msg=\"$1\"\n  echo -e \"${BFR} ${CM} ${GN}${msg}${CL}\"\n}\n\ninstall() {\n  header_info\n  while true; do\n    read -p \"Are you sure you want to install NetData on Proxmox VE host. Proceed(y/n)?\" yn\n    case $yn in\n    [Yy]*) break ;;\n    [Nn]*) exit ;;\n    *) echo \"Please answer yes or no.\" ;;\n    esac\n  done\n  header_info\n  read -r -p \"Verbose mode? <y/N> \" prompt\n  if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then\n  STD=\"\"\n  else\n  STD=\"silent\"\n  fi\n  header_info\n\n  msg_info \"Setting up repository\"\n  wget -q https://repo.netdata.cloud/repos/repoconfig/debian/bookworm/netdata-repo_2-2+debian12_all.deb\n  $STD dpkg -i netdata-repo_2-2+debian12_all.deb\n  rm -rf netdata-repo_2-2+debian12_all.deb\n  msg_ok \"Set up repository\"\n\n  msg_info \"Installing Netdata\"\n  $STD apt-get update\n  $STD apt-get install -y netdata\n  msg_ok \"Installed Netdata\"\n  msg_ok \"Completed Successfully!\\n\"\n  echo -e \"\\n Netdata should be reachable at${BL} http://$(hostname -I | awk '{print $1}'):19999 ${CL}\\n\"\n}\n\nuninstall() {\n  header_info\n  read -r -p \"Verbose mode? <y/N> \" prompt\n  if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then\n  STD=\"\"\n  else\n  STD=\"silent\"\n  fi\n  header_info\n\n  msg_info \"Uninstalling Netdata\"\n  systemctl stop netdata\n  rm -rf /var/log/netdata /var/lib/netdata /var/cache/netdata /etc/netdata/go.d\n  rm -rf /etc/apt/trusted.gpg.d/netdata-archive-keyring.gpg /etc/apt/sources.list.d/netdata.list\n  $STD apt-get remove --purge -y netdata netdata-repo\n  systemctl daemon-reload\n  $STD apt autoremove -y\n  $STD userdel netdata\n  msg_ok \"Uninstalled Netdata\"\n  msg_ok \"Completed Successfully!\\n\"\n}\n\nif ! pveversion | grep -Eq \"pve-manager/(8\\.[0-9])\"; then\n  echo -e \"This version of Proxmox Virtual Environment is not supported\"\n  echo -e \"Requires PVE Version 8.0 or higher\"\n  echo -e \"Exiting...\"\n  sleep 2\n  exit\nfi\n\nOPTIONS=(Install \"Install NetData on Proxmox VE\" \\\n         Uninstall \"Uninstall NetData from Proxmox VE\")\n\nCHOICE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"NetData\" --menu \"Select an option:\" 10 58 2 \\\n          \"${OPTIONS[@]}\" 3>&1 1>&2 2>&3)\n\ncase $CHOICE in\n  \"Install\")\n    install\n    ;;\n  \"Uninstall\")\n    uninstall\n    ;;\n  *)\n    echo \"Exiting...\"\n    exit 0\n    ;;\nesac\n"
  },
  {
    "path": "misc/olivetin.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\nclear\ncat <<\"EOF\"\n   ____  ___          _______     \n  / __ \\/ (_)   _____/_  __(_)___ \n / / / / / / | / / _ \\/ / / / __ \\\n/ /_/ / / /| |/ /  __/ / / / / / /\n\\____/_/_/ |___/\\___/_/ /_/_/ /_/ \n                                  \nEOF\n}\n\nIP=$(hostname -I | awk '{print $1}')\nYW=$(echo \"\\033[33m\")\nBL=$(echo \"\\033[36m\")\nGN=$(echo \"\\033[1;92m\")\nCL=$(echo \"\\033[m\")\nBFR=\"\\\\r\\\\033[K\"\nHOLD=\"-\"\nCM=\"${GN}✓${CL}\"\nAPP=\"OliveTin\"\nhostname=\"$(hostname)\"\nset-e\nheader_info\n\nwhile true; do\n    read -p \"This will Install ${APP} on $hostname. Proceed(y/n)?\" yn\n    case $yn in\n    [Yy]*) break ;;\n    [Nn]*) exit ;;\n    *) echo \"Please answer yes or no.\" ;;\n    esac\ndone\nheader_info\n\nfunction msg_info() {\n  local msg=\"$1\"\n  echo -ne \" ${HOLD} ${YW}${msg}...\"\n}\n\nfunction msg_ok() {\n  local msg=\"$1\"\n  echo -e \"${BFR} ${CM} ${GN}${msg}${CL}\"\n}\n\nmsg_info \"Installing ${APP}\"\nwget -q https://github.com/OliveTin/OliveTin/releases/latest/download/OliveTin_linux_amd64.deb\ndpkg -i OliveTin_linux_amd64.deb &>/dev/null\nsystemctl enable --now OliveTin &>/dev/null\nrm OliveTin_linux_amd64.deb\nmsg_ok \"Installed ${APP} on $hostname\"\n\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"${APP} should be reachable by going to the following URL.\n         ${BL}http://$IP:1337${CL} \\n\"\n"
  },
  {
    "path": "misc/pbs3-upgrade.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nheader_info() {\n  clear\n  cat <<\"EOF\"\n    ____  ____ __________    __  ______  __________  ___    ____  ______\n   / __ \\/ __ ) ___/__  /   / / / / __ \\/ ____/ __ \\/   |  / __ \\/ ____/\n  / /_/ / __  \\__ \\ /_ <   / / / / /_/ / / __/ /_/ / /| | / / / / __/\n / ____/ /_/ /__/ /__/ /  / /_/ / ____/ /_/ / _, _/ ___ |/ /_/ / /___\n/_/   /_____/____/____/   \\____/_/    \\____/_/ |_/_/  |_/_____/_____/\n\nEOF\n}\n\nRD=$(echo \"\\033[01;31m\")\nYW=$(echo \"\\033[33m\")\nGN=$(echo \"\\033[1;92m\")\nCL=$(echo \"\\033[m\")\nBFR=\"\\\\r\\\\033[K\"\nHOLD=\"-\"\nCM=\"${GN}✓${CL}\"\nCROSS=\"${RD}✗${CL}\"\n\nset -euo pipefail\nshopt -s inherit_errexit nullglob\n\nmsg_info() {\n  local msg=\"$1\"\n  echo -ne \" ${HOLD} ${YW}${msg}...\"\n}\n\nmsg_ok() {\n  local msg=\"$1\"\n  echo -e \"${BFR} ${CM} ${GN}${msg}${CL}\"\n}\n\nmsg_error() {\n  local msg=\"$1\"\n  echo -e \"${BFR} ${CROSS} ${RD}${msg}${CL}\"\n}\n\n\nstart_routines() {\n  header_info\n  CHOICE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"PBS 2 BACKUP\" --menu \"\\nMake a backup of /etc/proxmox-backup to ensure that in the worst case, any relevant configuration can be recovered?\" 14 58 2 \\\n    \"yes\" \" \" \\\n    \"no\" \" \" 3>&2 2>&1 1>&3)\n  case $CHOICE in\n  yes)\n    msg_info \"Backing up Proxmox Backup Server 2\"\n    tar czf \"pbs2-etc-backup-$(date -I).tar.gz\" -C \"/etc\" \"proxmox-backup\"\n    msg_ok \"Backed up Proxmox Backup Server 2\"\n    ;;\n  no)\n    msg_error \"Selected no to Backing up Proxmox Backup Server 2\"\n    ;;\n  esac\n\n  CHOICE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"PBS 3 SOURCES\" --menu \"This will set the correct sources to update and install Proxmox Backup Server 3.\\n \\nChange to Proxmox Backup Server 3 sources?\" 14 58 2 \\\n    \"yes\" \" \" \\\n    \"no\" \" \" 3>&2 2>&1 1>&3)\n  case $CHOICE in\n  yes)\n    msg_info \"Changing to Proxmox Backup Server 3 Sources\"\n    cat <<EOF >/etc/apt/sources.list\ndeb http://deb.debian.org/debian bookworm main contrib\ndeb http://deb.debian.org/debian bookworm-updates main contrib\ndeb http://security.debian.org/debian-security bookworm-security main contrib\nEOF\n    msg_ok \"Changed to Proxmox Backup Server 3 Sources\"\n    ;;\n  no)\n    msg_error \"Selected no to Correcting Proxmox Backup Server 3 Sources\"\n    ;;\n  esac\n\n  CHOICE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"PBS3-ENTERPRISE\" --menu \"The 'pbs-enterprise' repository is only available to users who have purchased a Proxmox VE subscription.\\n \\nDisable 'pbs-enterprise' repository?\" 14 58 2 \\\n    \"yes\" \" \" \\\n    \"no\" \" \" 3>&2 2>&1 1>&3)\n  case $CHOICE in\n  yes)\n    msg_info \"Disabling 'pbs-enterprise' repository\"\n    cat <<EOF >/etc/apt/sources.list.d/pbs-enterprise.list\n# deb https://enterprise.proxmox.com/debian/pbs bookworm pbs-enterprise\nEOF\n    msg_ok \"Disabled 'pbs-enterprise' repository\"\n    ;;\n  no)\n    msg_error \"Selected no to Disabling 'pbs-enterprise' repository\"\n    ;;\n  esac\n\n  CHOICE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"PBS3-NO-SUBSCRIPTION\" --menu \"The 'pbs-no-subscription' repository provides access to all of the open-source components of Proxmox Backup Server.\\n \\nEnable 'pbs-no-subscription' repository?\" 14 58 2 \\\n    \"yes\" \" \" \\\n    \"no\" \" \" 3>&2 2>&1 1>&3)\n  case $CHOICE in\n  yes)\n    msg_info \"Enabling 'pbs-no-subscription' repository\"\n    cat <<EOF >/etc/apt/sources.list.d/pbs-install-repo.list\ndeb http://download.proxmox.com/debian/pbs bookworm pbs-no-subscription\nEOF\n    msg_ok \"Enabled 'pbs-no-subscription' repository\"\n    ;;\n  no)\n    msg_error \"Selected no to Enabling 'pbs-no-subscription' repository\"\n    ;;\n  esac\n\n  CHOICE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"PBS3 TEST\" --menu \"The 'pbstest' repository can give advanced users access to new features and updates before they are officially released.\\n \\nAdd (Disabled) 'pbstest' repository?\" 14 58 2 \\\n    \"yes\" \" \" \\\n    \"no\" \" \" 3>&2 2>&1 1>&3)\n  case $CHOICE in\n  yes)\n    msg_info \"Adding 'pbstest' repository and set disabled\"\n    cat <<EOF >/etc/apt/sources.list.d/pbstest-for-beta.list\n# deb http://download.proxmox.com/debian/pbs bookworm pbstest\nEOF\n    msg_ok \"Added 'pbstest' repository\"\n    ;;\n  no)\n    msg_error \"Selected no to Adding 'pbstest' repository\"\n    ;;\n  esac\n\n  CHOICE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"PBS 3 UPDATE\" --menu \"\\nUpdate to Proxmox Backup Server 3 now?\" 11 58 2 \\\n    \"yes\" \" \" \\\n    \"no\" \" \" 3>&2 2>&1 1>&3)\n  case $CHOICE in\n  yes)\n    msg_info \"Updating to Proxmox Backup Server 3 (Patience)\"\n    apt-get update\n    DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::=\"--force-confold\" dist-upgrade -y\n    msg_ok \"Updated to Proxmox Backup Server 3\"\n    ;;\n  no)\n    msg_error \"Selected no to Updating to Proxmox Backup Server 3\"\n    ;;\n  esac\n\n  CHOICE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"REBOOT\" --menu \"\\nReboot Proxmox Backup Server 3 now? (recommended)\" 11 58 2 \\\n    \"yes\" \" \" \\\n    \"no\" \" \" 3>&2 2>&1 1>&3)\n  case $CHOICE in\n  yes)\n    msg_info \"Rebooting Proxmox Backup Server 3\"\n    sleep 2\n    msg_ok \"Completed Install Routines\"\n    reboot\n    ;;\n  no)\n    msg_error \"Selected no to Rebooting Proxmox Backup Server 3 (Reboot recommended)\"\n    msg_ok \"Completed Install Routines\"\n    ;;\n  esac\n}\n\nheader_info\nwhile true; do\n  read -p \"Start the Update to Proxmox Backup Server 3 Script (y/n)?\" yn\n  case $yn in\n  [Yy]*) break ;;\n  [Nn]*) clear; exit ;;\n  *) echo \"Please answer yes or no.\" ;;\n  esac\ndone\n\nstart_routines\n"
  },
  {
    "path": "misc/post-pbs-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nheader_info() {\n  clear\n  cat <<\"EOF\"\n    ____  ____ _____    ____             __     ____           __        ____\n   / __ \\/ __ ) ___/   / __ \\____  _____/ /_   /  _/___  _____/ /_____ _/ / /\n  / /_/ / __  \\__ \\   / /_/ / __ \\/ ___/ __/   / // __ \\/ ___/ __/ __ `/ / /\n / ____/ /_/ /__/ /  / ____/ /_/ (__  ) /_   _/ // / / (__  ) /_/ /_/ / / /\n/_/   /_____/____/  /_/    \\____/____/\\__/  /___/_/ /_/____/\\__/\\__,_/_/_/\n\nEOF\n}\n\nRD=$(echo \"\\033[01;31m\")\nYW=$(echo \"\\033[33m\")\nGN=$(echo \"\\033[1;92m\")\nCL=$(echo \"\\033[m\")\nBFR=\"\\\\r\\\\033[K\"\nHOLD=\"-\"\nCM=\"${GN}✓${CL}\"\nCROSS=\"${RD}✗${CL}\"\n\nset -euo pipefail\nshopt -s inherit_errexit nullglob\n\nmsg_info() {\n  local msg=\"$1\"\n  echo -ne \" ${HOLD} ${YW}${msg}...\"\n}\n\nmsg_ok() {\n  local msg=\"$1\"\n  echo -e \"${BFR} ${CM} ${GN}${msg}${CL}\"\n}\n\nmsg_error() {\n  local msg=\"$1\"\n  echo -e \"${BFR} ${CROSS} ${RD}${msg}${CL}\"\n}\n\n\nstart_routines() {\n  header_info\n  VERSION=\"$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)\"\n  CHOICE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"PBS SOURCES\" --menu \"This will set the correct sources to update and install Proxmox Backup Server.\\n \\nChange to Proxmox Backup Server sources?\" 14 58 2 \\\n    \"yes\" \" \" \\\n    \"no\" \" \" 3>&2 2>&1 1>&3)\n  case $CHOICE in\n  yes)\n    msg_info \"Changing to Proxmox Backup Server Sources\"\n    cat <<EOF >/etc/apt/sources.list\ndeb http://deb.debian.org/debian ${VERSION} main contrib\ndeb http://deb.debian.org/debian ${VERSION}-updates main contrib\ndeb http://security.debian.org/debian-security ${VERSION}-security main contrib\nEOF\n    msg_ok \"Changed to Proxmox Backup Server Sources\"\n    ;;\n  no)\n    msg_error \"Selected no to Correcting Proxmox Backup Server Sources\"\n    ;;\n  esac\n\n  CHOICE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"PBS-ENTERPRISE\" --menu \"The 'pbs-enterprise' repository is only available to users who have purchased a Proxmox VE subscription.\\n \\nDisable 'pbs-enterprise' repository?\" 14 58 2 \\\n    \"yes\" \" \" \\\n    \"no\" \" \" 3>&2 2>&1 1>&3)\n  case $CHOICE in\n  yes)\n    msg_info \"Disabling 'pbs-enterprise' repository\"\n    cat <<EOF >/etc/apt/sources.list.d/pbs-enterprise.list\n# deb https://enterprise.proxmox.com/debian/pbs ${VERSION} pbs-enterprise\nEOF\n    msg_ok \"Disabled 'pbs-enterprise' repository\"\n    ;;\n  no)\n    msg_error \"Selected no to Disabling 'pbs-enterprise' repository\"\n    ;;\n  esac\n\n  CHOICE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"PBS-NO-SUBSCRIPTION\" --menu \"The 'pbs-no-subscription' repository provides access to all of the open-source components of Proxmox Backup Server.\\n \\nEnable 'pbs-no-subscription' repository?\" 14 58 2 \\\n    \"yes\" \" \" \\\n    \"no\" \" \" 3>&2 2>&1 1>&3)\n  case $CHOICE in\n  yes)\n    msg_info \"Enabling 'pbs-no-subscription' repository\"\n    cat <<EOF >/etc/apt/sources.list.d/pbs-install-repo.list\ndeb http://download.proxmox.com/debian/pbs ${VERSION} pbs-no-subscription\nEOF\n    msg_ok \"Enabled 'pbs-no-subscription' repository\"\n    ;;\n  no)\n    msg_error \"Selected no to Enabling 'pbs-no-subscription' repository\"\n    ;;\n  esac\n\n  CHOICE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"PBS TEST\" --menu \"The 'pbstest' repository can give advanced users access to new features and updates before they are officially released.\\n \\nAdd (Disabled) 'pbstest' repository?\" 14 58 2 \\\n    \"yes\" \" \" \\\n    \"no\" \" \" 3>&2 2>&1 1>&3)\n  case $CHOICE in\n  yes)\n    msg_info \"Adding 'pbstest' repository and set disabled\"\n    cat <<EOF >/etc/apt/sources.list.d/pbstest-for-beta.list\n# deb http://download.proxmox.com/debian/pbs ${VERSION} pbstest\nEOF\n    msg_ok \"Added 'pbstest' repository\"\n    ;;\n  no)\n    msg_error \"Selected no to Adding 'pbstest' repository\"\n    ;;\n  esac\n\n  if [[ ! -f /etc/apt/apt.conf.d/no-nag-script ]]; then\n    CHOICE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"SUBSCRIPTION NAG\" --menu \"This will disable the nag message reminding you to purchase a subscription every time you log in to the web interface.\\n \\nDisable subscription nag?\" 14 58 2 \\\n      \"yes\" \" \" \\\n      \"no\" \" \" 3>&2 2>&1 1>&3)\n    case $CHOICE in\n    yes)\n      whiptail --backtitle \"Proxmox VE Helper Scripts\" --msgbox --title \"Support Subscriptions\" \"Supporting the software's development team is essential. Check their official website's Support Subscriptions for pricing. Without their dedicated work, we wouldn't have this exceptional software.\" 10 58\n      msg_info \"Disabling subscription nag\"\n      echo \"DPkg::Post-Invoke { \\\"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\\.js$'; if [ \\$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/data\\.status.*{/{s/\\!//;s/active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\\\"; };\" >/etc/apt/apt.conf.d/no-nag-script\n      apt --reinstall install proxmox-widget-toolkit &>/dev/null\n      msg_ok \"Disabled subscription nag (Delete browser cache)\"\n      ;;\n    no)\n      whiptail --backtitle \"Proxmox VE Helper Scripts\" --msgbox --title \"Support Subscriptions\" \"Supporting the software's development team is essential. Check their official website's Support Subscriptions for pricing. Without their dedicated work, we wouldn't have this exceptional software.\" 10 58\n      msg_error \"Selected no to Disabling subscription nag\"\n      ;;\n    esac\n  fi\n\n  CHOICE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"UPDATE\" --menu \"\\nUpdate Proxmox Backup Server now?\" 11 58 2 \\\n    \"yes\" \" \" \\\n    \"no\" \" \" 3>&2 2>&1 1>&3)\n  case $CHOICE in\n  yes)\n    msg_info \"Updating Proxmox Backup Server (Patience)\"\n    apt-get update &>/dev/null\n    apt-get -y dist-upgrade &>/dev/null\n    msg_ok \"Updated Proxmox Backup Server\"\n    ;;\n  no)\n    msg_error \"Selected no to Updating Proxmox Backup Server\"\n    ;;\n  esac\n\n  CHOICE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"REBOOT\" --menu \"\\nReboot Proxmox Backup Server now? (recommended)\" 11 58 2 \\\n    \"yes\" \" \" \\\n    \"no\" \" \" 3>&2 2>&1 1>&3)\n  case $CHOICE in\n  yes)\n    msg_info \"Rebooting Proxmox Backup Server\"\n    sleep 2\n    msg_ok \"Completed Post Install Routines\"\n    reboot\n    ;;\n  no)\n    msg_error \"Selected no to Rebooting Proxmox Backup Server (Reboot recommended)\"\n    msg_ok \"Completed Post Install Routines\"\n    ;;\n  esac\n}\n\nheader_info\necho -e \"\\nThis script will Perform Post Install Routines.\\n\"\nwhile true; do\n  read -p \"Start the Proxmox Backup Server Post Install Script (y/n)?\" yn\n  case $yn in\n  [Yy]*) break ;;\n  [Nn]*) clear; exit ;;\n  *) echo \"Please answer yes or no.\" ;;\n  esac\ndone\n\nif command -v pveversion >/dev/null 2>&1; then\n    echo -e \"\\n🛑  PVE Detected, Wrong Script!\\n\"\n    exit 1\nfi\n\nstart_routines\n"
  },
  {
    "path": "misc/post-pve-install.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nheader_info() {\n  clear\n  cat <<\"EOF\"\n    ____ _    ________   ____             __     ____           __        ____\n   / __ \\ |  / / ____/  / __ \\____  _____/ /_   /  _/___  _____/ /_____ _/ / /\n  / /_/ / | / / __/    / /_/ / __ \\/ ___/ __/   / // __ \\/ ___/ __/ __ `/ / /\n / ____/| |/ / /___   / ____/ /_/ (__  ) /_   _/ // / / (__  ) /_/ /_/ / / /\n/_/     |___/_____/  /_/    \\____/____/\\__/  /___/_/ /_/____/\\__/\\__,_/_/_/\n\nEOF\n}\n\nRD=$(echo \"\\033[01;31m\")\nYW=$(echo \"\\033[33m\")\nGN=$(echo \"\\033[1;92m\")\nCL=$(echo \"\\033[m\")\nBFR=\"\\\\r\\\\033[K\"\nHOLD=\"-\"\nCM=\"${GN}✓${CL}\"\nCROSS=\"${RD}✗${CL}\"\n\nset -euo pipefail\nshopt -s inherit_errexit nullglob\n\nmsg_info() {\n  local msg=\"$1\"\n  echo -ne \" ${HOLD} ${YW}${msg}...\"\n}\n\nmsg_ok() {\n  local msg=\"$1\"\n  echo -e \"${BFR} ${CM} ${GN}${msg}${CL}\"\n}\n\nmsg_error() {\n  local msg=\"$1\"\n  echo -e \"${BFR} ${CROSS} ${RD}${msg}${CL}\"\n}\n\nstart_routines() {\n  header_info\n\n  CHOICE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"SOURCES\" --menu \"The package manager will use the correct sources to update and install packages on your Proxmox VE server.\\n \\nCorrect Proxmox VE sources?\" 14 58 2 \\\n    \"yes\" \" \" \\\n    \"no\" \" \" 3>&2 2>&1 1>&3)\n  case $CHOICE in\n  yes)\n    msg_info \"Correcting Proxmox VE Sources\"\n    cat <<EOF >/etc/apt/sources.list\ndeb http://deb.debian.org/debian bookworm main contrib\ndeb http://deb.debian.org/debian bookworm-updates main contrib\ndeb http://security.debian.org/debian-security bookworm-security main contrib\nEOF\necho 'APT::Get::Update::SourceListWarnings::NonFreeFirmware \"false\";' >/etc/apt/apt.conf.d/no-bookworm-firmware.conf\n    msg_ok \"Corrected Proxmox VE Sources\"\n    ;;\n  no)\n    msg_error \"Selected no to Correcting Proxmox VE Sources\"\n    ;;\n  esac\n\n  CHOICE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"PVE-ENTERPRISE\" --menu \"The 'pve-enterprise' repository is only available to users who have purchased a Proxmox VE subscription.\\n \\nDisable 'pve-enterprise' repository?\" 14 58 2 \\\n    \"yes\" \" \" \\\n    \"no\" \" \" 3>&2 2>&1 1>&3)\n  case $CHOICE in\n  yes)\n    msg_info \"Disabling 'pve-enterprise' repository\"\n    cat <<EOF >/etc/apt/sources.list.d/pve-enterprise.list\n# deb https://enterprise.proxmox.com/debian/pve bookworm pve-enterprise\nEOF\n    msg_ok \"Disabled 'pve-enterprise' repository\"\n    ;;\n  no)\n    msg_error \"Selected no to Disabling 'pve-enterprise' repository\"\n    ;;\n  esac\n\n  CHOICE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"PVE-NO-SUBSCRIPTION\" --menu \"The 'pve-no-subscription' repository provides access to all of the open-source components of Proxmox VE.\\n \\nEnable 'pve-no-subscription' repository?\" 14 58 2 \\\n    \"yes\" \" \" \\\n    \"no\" \" \" 3>&2 2>&1 1>&3)\n  case $CHOICE in\n  yes)\n    msg_info \"Enabling 'pve-no-subscription' repository\"\n    cat <<EOF >/etc/apt/sources.list.d/pve-install-repo.list\ndeb http://download.proxmox.com/debian/pve bookworm pve-no-subscription\nEOF\n    msg_ok \"Enabled 'pve-no-subscription' repository\"\n    ;;\n  no)\n    msg_error \"Selected no to Enabling 'pve-no-subscription' repository\"\n    ;;\n  esac\n\n    CHOICE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"CEPH PACKAGE REPOSITORIES\" --menu \"The 'Ceph Package Repositories' provides access to both the 'no-subscription' and 'enterprise' repositories (initially disabled).\\n \\nCorrect 'ceph package sources?\" 14 58 2 \\\n      \"yes\" \" \" \\\n      \"no\" \" \" 3>&2 2>&1 1>&3)\n    case $CHOICE in\n    yes)\n      msg_info \"Correcting 'ceph package repositories'\"\n      cat <<EOF >/etc/apt/sources.list.d/ceph.list\n# deb https://enterprise.proxmox.com/debian/ceph-quincy bookworm enterprise\n# deb http://download.proxmox.com/debian/ceph-quincy bookworm no-subscription\n# deb https://enterprise.proxmox.com/debian/ceph-reef bookworm enterprise\n# deb http://download.proxmox.com/debian/ceph-reef bookworm no-subscription\nEOF\n      msg_ok \"Corrected 'ceph package repositories'\"\n      ;;\n    no)\n      msg_error \"Selected no to Correcting 'ceph package repositories'\"\n      ;;\n    esac\n\n  CHOICE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"PVETEST\" --menu \"The 'pvetest' repository can give advanced users access to new features and updates before they are officially released.\\n \\nAdd (Disabled) 'pvetest' repository?\" 14 58 2 \\\n    \"yes\" \" \" \\\n    \"no\" \" \" 3>&2 2>&1 1>&3)\n  case $CHOICE in\n  yes)\n    msg_info \"Adding 'pvetest' repository and set disabled\"\n    cat <<EOF >/etc/apt/sources.list.d/pvetest-for-beta.list\n# deb http://download.proxmox.com/debian/pve bookworm pvetest\nEOF\n    msg_ok \"Added 'pvetest' repository\"\n    ;;\n  no)\n    msg_error \"Selected no to Adding 'pvetest' repository\"\n    ;;\n  esac\n\n  if [[ ! -f /etc/apt/apt.conf.d/no-nag-script ]]; then\n    CHOICE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"SUBSCRIPTION NAG\" --menu \"This will disable the nag message reminding you to purchase a subscription every time you log in to the web interface.\\n \\nDisable subscription nag?\" 14 58 2 \\\n      \"yes\" \" \" \\\n      \"no\" \" \" 3>&2 2>&1 1>&3)\n    case $CHOICE in\n    yes)\n      whiptail --backtitle \"Proxmox VE Helper Scripts\" --msgbox --title \"Support Subscriptions\" \"Supporting the software's development team is essential. Check their official website's Support Subscriptions for pricing. Without their dedicated work, we wouldn't have this exceptional software.\" 10 58\n      msg_info \"Disabling subscription nag\"\n        echo \"DPkg::Post-Invoke { \\\"dpkg -V proxmox-widget-toolkit | grep -q '/proxmoxlib\\.js$'; if [ \\$? -eq 1 ]; then { echo 'Removing subscription nag from UI...'; sed -i '/.*data\\.status.*{/{s/\\!//;s/active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; }; fi\\\"; };\" >/etc/apt/apt.conf.d/no-nag-script\n      apt --reinstall install proxmox-widget-toolkit &>/dev/null\n      msg_ok \"Disabled subscription nag (Delete browser cache)\"\n      ;;\n    no)\n      whiptail --backtitle \"Proxmox VE Helper Scripts\" --msgbox --title \"Support Subscriptions\" \"Supporting the software's development team is essential. Check their official website's Support Subscriptions for pricing. Without their dedicated work, we wouldn't have this exceptional software.\" 10 58\n      msg_error \"Selected no to Disabling subscription nag\"\n      ;;\n    esac\n  fi\n\n  if ! systemctl is-active --quiet pve-ha-lrm; then\n    CHOICE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"HIGH AVAILABILITY\" --menu \"Enable high availability?\" 10 58 2 \\\n      \"yes\" \" \" \\\n      \"no\" \" \" 3>&2 2>&1 1>&3)\n    case $CHOICE in\n    yes)\n      msg_info \"Enabling high availability\"\n      systemctl enable -q --now pve-ha-lrm\n      systemctl enable -q --now pve-ha-crm\n      systemctl enable -q --now corosync\n      msg_ok \"Enabled high availability\"\n      ;;\n    no)\n      msg_error \"Selected no to Enabling high availability\"\n      ;;\n    esac\n  fi\n  \n  if systemctl is-active --quiet pve-ha-lrm; then\n    CHOICE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"HIGH AVAILABILITY\" --menu \"If you plan to utilize a single node instead of a clustered environment, you can disable unnecessary high availability (HA) services, thus reclaiming system resources.\\n\\nIf HA becomes necessary at a later stage, the services can be re-enabled.\\n\\nDisable high availability?\" 18 58 2 \\\n      \"yes\" \" \" \\\n      \"no\" \" \" 3>&2 2>&1 1>&3)\n    case $CHOICE in\n    yes)\n      msg_info \"Disabling high availability\"\n      systemctl disable -q --now pve-ha-lrm\n      systemctl disable -q --now pve-ha-crm\n      systemctl disable -q --now corosync\n      msg_ok \"Disabled high availability\"\n      ;;\n    no)\n      msg_error \"Selected no to Disabling high availability\"\n      ;;\n    esac\n  fi\n  \n  CHOICE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"UPDATE\" --menu \"\\nUpdate Proxmox VE now?\" 11 58 2 \\\n    \"yes\" \" \" \\\n    \"no\" \" \" 3>&2 2>&1 1>&3)\n  case $CHOICE in\n  yes)\n    msg_info \"Updating Proxmox VE (Patience)\"\n    apt-get update &>/dev/null\n    apt-get -y dist-upgrade &>/dev/null\n    msg_ok \"Updated Proxmox VE\"\n    ;;\n  no)\n    msg_error \"Selected no to Updating Proxmox VE\"\n    ;;\n  esac\n\n  CHOICE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"REBOOT\" --menu \"\\nReboot Proxmox VE now? (recommended)\" 11 58 2 \\\n    \"yes\" \" \" \\\n    \"no\" \" \" 3>&2 2>&1 1>&3)\n  case $CHOICE in\n  yes)\n    msg_info \"Rebooting Proxmox VE\"\n    sleep 2\n    msg_ok \"Completed Post Install Routines\"\n    reboot\n    ;;\n  no)\n    msg_error \"Selected no to Rebooting Proxmox VE (Reboot recommended)\"\n    msg_ok \"Completed Post Install Routines\"\n    ;;\n  esac\n}\n\nheader_info\necho -e \"\\nThis script will Perform Post Install Routines.\\n\"\nwhile true; do\n  read -p \"Start the Proxmox VE Post Install Script (y/n)?\" yn\n  case $yn in\n  [Yy]*) break ;;\n  [Nn]*) clear; exit ;;\n  *) echo \"Please answer yes or no.\" ;;\n  esac\ndone\n\nif ! pveversion | grep -Eq \"pve-manager/8.[0-2]\"; then\n  msg_error \"This version of Proxmox Virtual Environment is not supported\"\n  echo -e \"Requires Proxmox Virtual Environment Version 8.0 or later.\"\n  echo -e \"Exiting...\"\n  sleep 2\n  exit\nfi\n\nstart_routines\n"
  },
  {
    "path": "misc/pve8-upgrade.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nheader_info() {\n  clear\n  cat <<\"EOF\"\n    ____ _    ____________     __  ______  __________  ___    ____  ______\n   / __ \\ |  / / ____( __ )   / / / / __ \\/ ____/ __ \\/   |  / __ \\/ ____/\n  / /_/ / | / / __/ / __  |  / / / / /_/ / / __/ /_/ / /| | / / / / __/\n / ____/| |/ / /___/ /_/ /  / /_/ / ____/ /_/ / _, _/ ___ |/ /_/ / /___\n/_/     |___/_____/\\____/   \\____/_/    \\____/_/ |_/_/  |_/_____/_____/\n\nEOF\n}\n\nRD=$(echo \"\\033[01;31m\")\nYW=$(echo \"\\033[33m\")\nGN=$(echo \"\\033[1;92m\")\nCL=$(echo \"\\033[m\")\nBFR=\"\\\\r\\\\033[K\"\nHOLD=\"-\"\nCM=\"${GN}✓${CL}\"\nCROSS=\"${RD}✗${CL}\"\n\nset -euo pipefail\nshopt -s inherit_errexit nullglob\n\nmsg_info() {\n  local msg=\"$1\"\n  echo -ne \" ${HOLD} ${YW}${msg}...\"\n}\n\nmsg_ok() {\n  local msg=\"$1\"\n  echo -e \"${BFR} ${CM} ${GN}${msg}${CL}\"\n}\n\nmsg_error() {\n  local msg=\"$1\"\n  echo -e \"${BFR} ${CROSS} ${RD}${msg}${CL}\"\n}\n\nstart_routines() {\n  header_info\n\n  whiptail --backtitle \"Proxmox VE Helper Scripts\" --msgbox --title \"PVE8 SOURCES\" \"This will set the correct sources to update and install Proxmox VE 8.\" 10 58\n    msg_info \"Changing to Proxmox VE 8 Sources\"\n    cat <<EOF >/etc/apt/sources.list\ndeb http://ftp.debian.org/debian bookworm main contrib\ndeb http://ftp.debian.org/debian bookworm-updates main contrib\ndeb http://security.debian.org/debian-security bookworm-security main contrib\nEOF\n    msg_ok \"Changed to Proxmox VE 8 Sources\"\n\n  whiptail --backtitle \"Proxmox VE Helper Scripts\" --msgbox --title \"PVE8-ENTERPRISE\" \"The 'pve-enterprise' repository is only available to users who have purchased a Proxmox VE subscription.\" 10 58\n    msg_info \"Disabling 'pve-enterprise' repository\"\n    cat <<EOF >/etc/apt/sources.list.d/pve-enterprise.list\n# deb https://enterprise.proxmox.com/debian/pve bookworm pve-enterprise\nEOF\n    msg_ok \"Disabled 'pve-enterprise' repository\"\n\n  whiptail --backtitle \"Proxmox VE Helper Scripts\" --msgbox --title \"PVE8-NO-SUBSCRIPTION\" \"The 'pve-no-subscription' repository provides access to all of the open-source components of Proxmox VE.\" 10 58\n    msg_info \"Enabling 'pve-no-subscription' repository\"\n    cat <<EOF >/etc/apt/sources.list.d/pve-install-repo.list\ndeb http://download.proxmox.com/debian/pve bookworm pve-no-subscription\nEOF\n    msg_ok \"Enabled 'pve-no-subscription' repository\"\n\n  whiptail --backtitle \"Proxmox VE Helper Scripts\" --msgbox --title \"PVE8 CEPH PACKAGE REPOSITORIES\" \"The 'Ceph Package Repositories' provides access to both the 'no-subscription' and 'enterprise' repositories.\" 10 58\n    msg_info \"Enabling 'ceph package repositories'\"\n    cat <<EOF >/etc/apt/sources.list.d/ceph.list\n# deb https://enterprise.proxmox.com/debian/ceph-quincy bookworm enterprise\ndeb http://download.proxmox.com/debian/ceph-quincy bookworm no-subscription\nEOF\n    msg_ok \"Enabled 'ceph package repositories'\"\n\n  whiptail --backtitle \"Proxmox VE Helper Scripts\" --msgbox --title \"PVE8 TEST\" \"The 'pvetest' repository can give advanced users access to new features and updates before they are officially released (Disabled).\" 10 58\n    msg_info \"Adding 'pvetest' repository and set disabled\"\n    cat <<EOF >/etc/apt/sources.list.d/pvetest-for-beta.list\n# deb http://download.proxmox.com/debian/pve bookworm pvetest\nEOF\n    msg_ok \"Added 'pvetest' repository\"\n\n  whiptail --backtitle \"Proxmox VE Helper Scripts\" --msgbox --title \"PVE8 UPDATE\" \"Updating to Proxmox VE 8\" 10 58\n    msg_info \"Updating to Proxmox VE 8 (Patience)\"\n    apt-get update\n    DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::=\"--force-confold\" dist-upgrade -y\n    msg_ok \"Updated to Proxmox VE 8\"\n\n  CHOICE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"REBOOT\" --menu \"\\nReboot Proxmox VE 8 now? (recommended)\" 11 58 2 \\\n    \"yes\" \" \" \\\n    \"no\" \" \" 3>&2 2>&1 1>&3)\n  case $CHOICE in\n  yes)\n    msg_info \"Rebooting Proxmox VE 8\"\n    sleep 2\n    msg_ok \"Completed Install Routines\"\n    reboot\n    ;;\n  no)\n    msg_error \"Selected no to Rebooting Proxmox VE 8 (Reboot recommended)\"\n    msg_ok \"Completed Install Routines\"\n    ;;\n  esac\n}\n\nheader_info\nwhile true; do\n  read -p \"Start the Update to Proxmox VE 8 Script (y/n)?\" yn\n  case $yn in\n  [Yy]*) break ;;\n  [Nn]*) clear; exit ;;\n  *) echo \"Please answer yes or no.\" ;;\n  esac\ndone\n\nif ! command -v pveversion >/dev/null 2>&1; then\n  header_info\n  msg_error \"\\n No PVE Detected!\\n\"\n  exit\nfi\n\nif ! pveversion | grep -Eq \"pve-manager/(7\\.4-(16|17|18|19))\"; then\n  header_info\n  msg_error \"This version of Proxmox Virtual Environment is not supported\"\n  echo -e \"  PVE Version 7.4-16 or higher is required.\"\n  echo -e \"\\nExiting...\"\n  sleep 3\n  exit\nfi\n\nstart_routines\n"
  },
  {
    "path": "misc/pyenv.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nset -e\nYW=$(echo \"\\033[33m\")\nRD=$(echo \"\\033[01;31m\")\nBL=$(echo \"\\033[36m\")\nGN=$(echo \"\\033[1;92m\")\nCL=$(echo \"\\033[m\")\nCM=\"${GN}✓${CL}\"\nCROSS=\"${RD}✗${CL}\"\nBFR=\"\\\\r\\\\033[K\"\nHOLD=\"-\"\nfunction msg_info() {\n  local msg=\"$1\"\n  echo -ne \" ${HOLD} ${YW}${msg}...\"\n}\n\nfunction msg_ok() {\n  local msg=\"$1\"\n  echo -e \"${BFR} ${CM} ${GN}${msg}${CL}\"\n}\nfunction msg_error() {\n  local msg=\"$1\"\n  echo -e \"${BFR} ${CROSS} ${RD}${msg}${CL}\"\n}\nif command -v pveversion >/dev/null 2>&1; then msg_error \"Can't Install on Proxmox \"; exit; fi\nmsg_info \"Installing pyenv\"\napt-get install -y \\\n  make \\\n  build-essential \\\n  libjpeg-dev \\\n  libpcap-dev \\\n  libssl-dev \\\n  zlib1g-dev \\\n  libbz2-dev \\\n  libreadline-dev \\\n  libsqlite3-dev \\\n  autoconf \\\n  git \\\n  curl \\\n  sudo \\\n  llvm \\\n  libncursesw5-dev \\\n  xz-utils \\\n  tk-dev \\\n  libxml2-dev \\\n  libxmlsec1-dev \\\n  libffi-dev \\\n  libopenjp2-7 \\\n  libtiff5 \\\n  libturbojpeg0-dev \\\n  liblzma-dev &>/dev/null\n\ngit clone https://github.com/pyenv/pyenv.git ~/.pyenv &>/dev/null\nset +e\necho 'export PYENV_ROOT=\"$HOME/.pyenv\"' >> ~/.bashrc\necho 'export PATH=\"$PYENV_ROOT/bin:$PATH\"' >> ~/.bashrc\necho -e 'if command -v pyenv 1>/dev/null 2>&1; then\\n eval \"$(pyenv init --path)\"\\nfi' >> ~/.bashrc  \nmsg_ok \"Installed pyenv\"\n. ~/.bashrc\nset -e\nmsg_info \"Installing Python 3.11.1\"\npyenv install 3.11.1 &>/dev/null\npyenv global 3.11.1\nmsg_ok \"Installed Python 3.11.1\"\nread -r -p \"Would you like to install Home Assistant Beta? <y/N> \" prompt\nif [[ \"${prompt,,}\" =~ ^(y|yes)$ ]]; then\nmsg_info \"Installing Home Assistant Beta\"\ncat <<EOF >/etc/systemd/system/homeassistant.service\n[Unit]\nDescription=Home Assistant\nAfter=network-online.target\n[Service]\nType=simple\nWorkingDirectory=/root/.homeassistant\nExecStart=/srv/homeassistant/bin/hass -c \"/root/.homeassistant\"\nRestartForceExitStatus=100\n[Install]\nWantedBy=multi-user.target\nEOF\nmkdir /srv/homeassistant\ncd /srv/homeassistant\npython3 -m venv .\nsource bin/activate\npython3 -m pip install wheel &>/dev/null\npip3 install --upgrade pip &>/dev/null\npip3 install psycopg2-binary &>/dev/null\npip3 install --pre homeassistant &>/dev/null\nsystemctl enable homeassistant &>/dev/null\nmsg_ok \"Installed Home Assistant Beta\"\necho -e \" Go to $(hostname -I | awk '{print $1}'):8123\"\nhass\nfi\n\nread -r -p \"Would you like to install ESPHome Beta? <y/N> \" prompt\nif [[ \"${prompt,,}\" =~ ^(y|yes)$ ]]; then\nmsg_info \"Installing ESPHome Beta\"\nmkdir /srv/esphome\ncd /srv/esphome\npython3 -m venv .\nsource bin/activate\npython3 -m pip install wheel &>/dev/null\npip3 install --upgrade pip &>/dev/null\npip3 install --pre esphome &>/dev/null\ncat <<EOF >/srv/esphome/start.sh\n#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nsource /srv/esphome/bin/activate\nesphome dashboard /srv/esphome/\nEOF\nchmod +x start.sh\ncat <<EOF >/etc/systemd/system/esphomedashboard.service\n[Unit]\nDescription=ESPHome Dashboard Service\nAfter=network.target\n[Service]\nType=simple\nUser=root\nWorkingDirectory=/srv/esphome\nExecStart=/srv/esphome/start.sh\nRestartSec=30\nRestart=on-failure\n[Install]\nWantedBy=multi-user.target\nEOF\nsystemctl enable --now esphomedashboard &>/dev/null\nmsg_ok \"Installed ESPHome Beta\"\necho -e \" Go to $(hostname -I | awk '{print $1}'):6052\"\nexec $SHELL\nfi\n\nread -r -p \"Would you like to install Matter-Server (Beta)? <y/N> \" prompt\nif [[ \"${prompt,,}\" =~ ^(y|yes)$ ]]; then\nmsg_info \"Installing Matter Server\"\napt-get install -y \\\nlibcairo2-dev \\\nlibjpeg62-turbo-dev \\\nlibgirepository1.0-dev \\\nlibpango1.0-dev \\\nlibgif-dev \\\ng++ &>/dev/null\npython3 -m pip install wheel \npip3 install --upgrade pip \npip install python-matter-server[server]\nmsg_ok \"Installed Matter Server\"\necho -e \"Start server > python -m matter_server.server\"\nfi\nmsg_ok \"\\nFinished\\n\"\nexec $SHELL\n"
  },
  {
    "path": "misc/scaling-governor.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\nset -e\nheader_info() {\nclear\ncat <<EOF\n  ________  __  __  _____\n / ___/ _ \\/ / / / / ___/__ _  _____ _______  ___  _______\n/ /__/ ___/ /_/ / / (_ / _ \\ |/ / -_) __/ _ \\/ _ \\/ __(_-<\n\\___/_/   \\____/  \\___/\\___/___/\\__/_/ /_//_/\\___/_/ /___/\nEOF\n}\nheader_info\nwhiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"CPU Scaling Governors\" --yesno \"View/Change CPU Scaling Governors. Proceed?\" 10 58 || exit\ncurrent_governor=$(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor)\nGOVERNORS_MENU=()\nMSG_MAX_LENGTH=0\nwhile read -r TAG ITEM; do\n  OFFSET=2\n  ((${#ITEM} + OFFSET > MSG_MAX_LENGTH)) && MSG_MAX_LENGTH=${#ITEM}+OFFSET\n  GOVERNORS_MENU+=(\"$TAG\" \"$ITEM \" \"OFF\")\ndone < <(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors | tr ' ' '\\n' | grep -v \"$current_governor\")\nscaling_governor=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"Current CPU Scaling Governor is set to $current_governor\" --checklist \"\\nSelect the Scaling Governor to use:\\n\" 16 $((MSG_MAX_LENGTH + 58)) 6 \"${GOVERNORS_MENU[@]}\" 3>&1 1>&2 2>&3 | tr -d '\"') || exit\n[ -z \"$scaling_governor\" ] && {\n    whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"No CPU Scaling Governor Selected\" --msgbox \"It appears that no CPU Scaling Governor was selected\" 10 68\n    clear\n    exit\n}\necho \"${scaling_governor}\" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor >/dev/null\ncurrent_governor=$(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor)\nwhiptail --backtitle \"Proxmox VE Helper Scripts\" --msgbox --title \"Current CPU Scaling Governor\" \"\\nCurrent CPU Scaling Governor has been set to $current_governor\\n\" 10 60\nCHOICE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"CPU Scaling Governor\" --menu \"This will establish a crontab to maintain the CPU Scaling Governor configuration across reboots.\\n \\nSetup a crontab?\" 14 68 2 \\\n  \"yes\" \" \" \\\n  \"no\" \" \" 3>&2 2>&1 1>&3)\n\ncase $CHOICE in\n  yes)\n    set +e\n    NEW_CRONTAB_COMMAND=\"(sleep 60 && echo \\\"$current_governor\\\" | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor)\"\n    EXISTING_CRONTAB=$(crontab -l 2>/dev/null)\n    if [[ -n \"$EXISTING_CRONTAB\" ]]; then\n      TEMP_CRONTAB_FILE=$(mktemp)\n      echo \"$EXISTING_CRONTAB\" | grep -v \"@reboot (sleep 60 && echo*\" > \"$TEMP_CRONTAB_FILE\"\n      crontab \"$TEMP_CRONTAB_FILE\"\n      rm \"$TEMP_CRONTAB_FILE\"\n    fi\n    (crontab -l 2>/dev/null; echo \"@reboot $NEW_CRONTAB_COMMAND\") | crontab -\n    echo -e \"\\nCrontab Set (use 'crontab -e' to check)\"\n    ;;\n  no)\n    echo -e \"\\n\\033[31mNOTE: Settings return to default after reboot\\033[m\\n\"\n    ;;\nesac\necho -e \"Current CPU Scaling Governor is set to \\033[36m$current_governor\\033[m\\n\"\n"
  },
  {
    "path": "misc/update-lxcs-cron.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\necho -e \"\\n $(date)\"\nexcluded_containers=(\"$@\")\nfunction update_container() {\n  container=$1\n  name=$(pct exec \"$container\" hostname)\n  echo -e \"\\n [Info] Updating $container : $name \\n\"\n  os=$(pct config \"$container\" | awk '/^ostype/ {print $2}')\n  case \"$os\" in\n  alpine) pct exec \"$container\" -- ash -c \"apk update && apk upgrade\" ;;\n  archlinux) pct exec \"$container\" -- bash -c \"pacman -Syyu --noconfirm\" ;;\n  fedora | rocky | centos | alma) pct exec \"$container\" -- bash -c \"dnf -y update && dnf -y upgrade\" ;;\n  ubuntu | debian | devuan) pct exec \"$container\" -- bash -c \"apt-get update && DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::=\"--force-confold\" dist-upgrade -y; rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED\" ;;\n  opensuse) pct exec \"$container\" -- bash -c \"zypper ref && zypper --non-interactive dup\" ;;\n  esac\n}\n\nfor container in $(pct list | awk '{if(NR>1) print $1}'); do\n  excluded=false\n  for excluded_container in \"${excluded_containers[@]}\"; do\n    if [ \"$container\" == \"$excluded_container\" ]; then\n      excluded=true\n      break\n    fi\n  done\n  if [ \"$excluded\" == true ]; then\n    echo -e \"[Info] Skipping $container\"\n    sleep 1\n  else\n    status=$(pct status $container)\n    template=$(pct config $container | grep -q \"template:\" && echo \"true\" || echo \"false\")\n    if [ \"$template\" == \"false\" ] && [ \"$status\" == \"status: stopped\" ]; then\n      echo -e \"[Info] Starting $container\"\n      pct start $container\n      sleep 5\n      update_container $container\n      echo -e \"[Info] Shutting down $container\"\n      pct shutdown $container &\n    elif [ \"$status\" == \"status: running\" ]; then\n      update_container $container\n    fi\n  fi\ndone\nwait\n"
  },
  {
    "path": "misc/update-lxcs.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\n  clear\n  cat <<\"EOF\"\n   __  __          __      __          __   _  ________\n  / / / /___  ____/ /___ _/ /____     / /  | |/ / ____/\n / / / / __ \\/ __  / __ `/ __/ _ \\   / /   |   / /\n/ /_/ / /_/ / /_/ / /_/ / /_/  __/  / /___/   / /___\n\\____/ .___/\\__,_/\\__,_/\\__/\\___/  /_____/_/|_\\____/\n    /_/\n\nEOF\n}\nset -eEuo pipefail\nYW=$(echo \"\\033[33m\")\nBL=$(echo \"\\033[36m\")\nRD=$(echo \"\\033[01;31m\")\nCM='\\xE2\\x9C\\x94\\033'\nGN=$(echo \"\\033[1;92m\")\nCL=$(echo \"\\033[m\")\nheader_info\necho \"Loading...\"\nwhiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"Proxmox VE LXC Updater\" --yesno \"This Will Update LXC Containers. Proceed?\" 10 58 || exit\nNODE=$(hostname)\nEXCLUDE_MENU=()\nMSG_MAX_LENGTH=0\nwhile read -r TAG ITEM; do\n  OFFSET=2\n  ((${#ITEM} + OFFSET > MSG_MAX_LENGTH)) && MSG_MAX_LENGTH=${#ITEM}+OFFSET\n  EXCLUDE_MENU+=(\"$TAG\" \"$ITEM \" \"OFF\")\ndone < <(pct list | awk 'NR>1')\nexcluded_containers=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"Containers on $NODE\" --checklist \"\\nSelect containers to skip from updates:\\n\" 16 $((MSG_MAX_LENGTH + 23)) 6 \"${EXCLUDE_MENU[@]}\" 3>&1 1>&2 2>&3 | tr -d '\"') || exit\n\nfunction needs_reboot() {\n    local container=$1\n    local os=$(pct config \"$container\" | awk '/^ostype/ {print $2}')\n    local reboot_required_file=\"/var/run/reboot-required.pkgs\"\n    if [ -f \"$reboot_required_file\" ]; then\n        if [[ \"$os\" == \"ubuntu\" || \"$os\" == \"debian\" ]]; then\n            if pct exec \"$container\" -- [ -s \"$reboot_required_file\" ]; then\n                return 0\n            fi\n        fi\n    fi\n    return 1\n}\n\nfunction update_container() {\n  container=$1\n  header_info\n  name=$(pct exec \"$container\" hostname)\n  os=$(pct config \"$container\" | awk '/^ostype/ {print $2}')\n  if [[ \"$os\" == \"ubuntu\" || \"$os\" == \"debian\" || \"$os\" == \"fedora\" ]]; then\n    disk_info=$(pct exec \"$container\" df /boot | awk 'NR==2{gsub(\"%\",\"\",$5); printf \"%s %.1fG %.1fG %.1fG\", $5, $3/1024/1024, $2/1024/1024, $4/1024/1024 }')\n    read -ra disk_info_array <<<\"$disk_info\"\n    echo -e \"${BL}[Info]${GN} Updating ${BL}$container${CL} : ${GN}$name${CL} - ${YW}Boot Disk: ${disk_info_array[0]}% full [${disk_info_array[1]}/${disk_info_array[2]} used, ${disk_info_array[3]} free]${CL}\\n\"\n  else\n    echo -e \"${BL}[Info]${GN} Updating ${BL}$container${CL} : ${GN}$name${CL} - ${YW}[No disk info for ${os}]${CL}\\n\"\n  fi\n  case \"$os\" in\n  alpine) pct exec \"$container\" -- ash -c \"apk update && apk upgrade\" ;;\n  archlinux) pct exec \"$container\" -- bash -c \"pacman -Syyu --noconfirm\" ;;\n  fedora | rocky | centos | alma) pct exec \"$container\" -- bash -c \"dnf -y update && dnf -y upgrade\" ;;\n  ubuntu | debian | devuan) pct exec \"$container\" -- bash -c \"apt-get update 2>/dev/null | grep 'packages.*upgraded'; apt list --upgradable && apt-get -yq dist-upgrade 2>&1; rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED\" ;;\n  opensuse) pct exec \"$container\" -- bash -c \"zypper ref && zypper --non-interactive dup\" ;;\n  esac\n}\n\ncontainers_needing_reboot=()\nheader_info\nfor container in $(pct list | awk '{if(NR>1) print $1}'); do\n  if [[ \" ${excluded_containers[@]} \" =~ \" $container \" ]]; then\n    header_info\n    echo -e \"${BL}[Info]${GN} Skipping ${BL}$container${CL}\"\n    sleep 1\n  else\n    status=$(pct status $container)\n    template=$(pct config $container | grep -q \"template:\" && echo \"true\" || echo \"false\")\n    if [ \"$template\" == \"false\" ] && [ \"$status\" == \"status: stopped\" ]; then\n      echo -e \"${BL}[Info]${GN} Starting${BL} $container ${CL} \\n\"\n      pct start $container\n      echo -e \"${BL}[Info]${GN} Waiting For${BL} $container${CL}${GN} To Start ${CL} \\n\"\n      sleep 5\n      update_container $container\n      echo -e \"${BL}[Info]${GN} Shutting down${BL} $container ${CL} \\n\"\n      pct shutdown $container &\n    elif [ \"$status\" == \"status: running\" ]; then\n      update_container $container\n    fi\n    if pct exec \"$container\" -- [ -e \"/var/run/reboot-required\" ]; then\n        # Get the container's hostname and add it to the list\n        container_hostname=$(pct exec \"$container\" hostname)\n        containers_needing_reboot+=(\"$container ($container_hostname)\")\n    fi\n  fi\ndone\nwait\nheader_info\necho -e \"${GN}The process is complete, and the containers have been successfully updated.${CL}\\n\"\nif [ \"${#containers_needing_reboot[@]}\" -gt 0 ]; then\n    echo -e \"${RD}The following containers require a reboot:${CL}\"\n    for container_name in \"${containers_needing_reboot[@]}\"; do\n        echo \"$container_name\"\n    done\nfi\necho \"\"\n"
  },
  {
    "path": "misc/usb-passthrough.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\necho -e \"\\e[1;33m This script will allow USB passthrough to a PRIVILEGED LXC Container ONLY\\e[0m\"\nwhile true; do\n  read -p \"Did you replace 106 with your LXC ID? Proceed(y/n)?\" yn\n  case $yn in\n  [Yy]*) break ;;\n  [Nn]*) exit ;;\n  *) echo \"Please answer yes or no.\" ;;\n  esac\ndone\n\nTEMP_DIR=$(mktemp -d)\npushd $TEMP_DIR >/dev/null\nCHAR_DEVS+=(\"166:.*\")\nCHAR_DEVS+=(\"188:.*\")\nCHAR_DEVS+=(\"189:.*\")\n\nfor char_dev in ${CHAR_DEVS[@]}; do\n  [ ! -z \"${CHAR_DEV_STRING-}\" ] && CHAR_DEV_STRING+=\" -o\"\n  CHAR_DEV_STRING+=\" -regex \\\".*/${char_dev}\\\"\"\ndone\n\nread -r -d '' HOOK_SCRIPT <<-EOF || true\nfor char_dev in \\$(find /sys/dev/char -regextype sed $CHAR_DEV_STRING); do\n  dev=\"/dev/\\$(sed -n \"/DEVNAME/ s/^.*=\\(.*\\)$/\\1/p\" \\${char_dev}/uevent)\";\n  mkdir -p \\$(dirname \\${LXC_ROOTFS_MOUNT}\\${dev});\n  for link in \\$(udevadm info --query=property \\$dev | sed -n \"s/DEVLINKS=//p\"); do\n    mkdir -p \\${LXC_ROOTFS_MOUNT}\\$(dirname \\$link);\n    cp -dpR \\$link \\${LXC_ROOTFS_MOUNT}\\${link};\n  done;\n  cp -dpR \\$dev \\${LXC_ROOTFS_MOUNT}\\${dev};\ndone;\nEOF\nHOOK_SCRIPT=${HOOK_SCRIPT//$'\\n'/}\n\nCTID=$1\nCTID_CONFIG_PATH=/etc/pve/lxc/${CTID}.conf\nsed '/autodev/d' $CTID_CONFIG_PATH >CTID.conf\ncat CTID.conf >$CTID_CONFIG_PATH\n\ncat <<EOF >>$CTID_CONFIG_PATH\nlxc.autodev: 1\nlxc.hook.autodev: bash -c '$HOOK_SCRIPT'\nEOF\necho -e \"\\e[1;33m Finished....Reboot ${CTID} LXC to apply the changes \\e[0m\"\n"
  },
  {
    "path": "misc/webmin.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\n  clear\n  cat <<\"EOF\"\n  _      __    __         _\n | | /| / /__ / /  __ _  (_)__\n | |/ |/ / -_) _ \\/  ' \\/ / _ \\\n |__/|__/\\__/_.__/_/_/_/_/_//_/\n\nEOF\n}\nset -eEuo pipefail\nYW=$(echo \"\\033[33m\")\nBL=$(echo \"\\033[36m\")\nBGN=$(echo \"\\033[4;92m\")\nGN=$(echo \"\\033[1;92m\")\nDGN=$(echo \"\\033[32m\")\nCL=$(echo \"\\033[m\")\nCM=\"${GN}✓${CL}\"\nBFR=\"\\\\r\\\\033[K\"\nHOLD=\"-\"\n\nmsg_info() {\n  local msg=\"$1\"\n  echo -ne \" ${HOLD} ${YW}${msg}...\"\n}\n\nmsg_ok() {\n  local msg=\"$1\"\n  echo -e \"${BFR} ${CM} ${GN}${msg}${CL}\"\n}\n\nheader_info\n\nwhiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"Webmin Installer\" --yesno \"This Will Install Webmin on this LXC Container. Proceed?\" 10 58 || exit\n\nmsg_info \"Installing Prerequisites\"\napt update &>/dev/null\napt-get -y install libnet-ssleay-perl libauthen-pam-perl libio-pty-perl unzip shared-mime-info &>/dev/null\nmsg_ok \"Installed Prerequisites\"\n\nLATEST=$(curl -sL https://api.github.com/repos/webmin/webmin/releases/latest | grep '\"tag_name\":' | cut -d'\"' -f4)\n\nmsg_info \"Downloading Webmin\"\nwget -q https://github.com/webmin/webmin/releases/download/$LATEST/webmin_${LATEST}_all.deb\nmsg_ok \"Downloaded Webmin\"\n\nmsg_info \"Installing Webmin\"\ndpkg -i webmin_${LATEST}_all.deb &>/dev/null\n/usr/share/webmin/changepass.pl /etc/webmin root root &>/dev/null\nrm -rf /root/webmin_${LATEST}_all.deb\nmsg_ok \"Installed Webmin\"\n\nIP=$(hostname -I | cut -f1 -d ' ')\necho -e \"Successfully Installed!! Webmin should be reachable by going to ${BL}https://${IP}:10000${CL}\"\n"
  },
  {
    "path": "turnkey/turnkey.sh",
    "content": "#!/usr/bin/env bash\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\n  clear\n  cat <<\"EOF\"\n ______              __ __           __   _  _______\n/_  __/_ _________  / //_/__ __ __  / /  | |/_/ ___/\n / / / // / __/ _ \\/ ,< / -_) // / / /___>  </ /__\n/_/  \\_,_/_/ /_//_/_/|_|\\__/\\_, / /____/_/|_|\\___/\n                           /___/\nEOF\n}\n\nset -euo pipefail\nshopt -s expand_aliases\nalias die='EXIT=$? LINE=$LINENO error_exit'\ntrap die ERR\nfunction error_exit() {\n  trap - ERR\n  local DEFAULT='Unknown failure occured.'\n  local REASON=\"\\e[97m${1:-$DEFAULT}\\e[39m\"\n  local FLAG=\"\\e[91m[ERROR] \\e[93m$EXIT@$LINE\"\n  msg \"$FLAG $REASON\" 1>&2\n  [ ! -z ${CTID-} ] && cleanup_ctid\n  exit $EXIT\n}\nfunction warn() {\n  local REASON=\"\\e[97m$1\\e[39m\"\n  local FLAG=\"\\e[93m[WARNING]\\e[39m\"\n  msg \"$FLAG $REASON\"\n}\nfunction info() {\n  local REASON=\"$1\"\n  local FLAG=\"\\e[36m[INFO]\\e[39m\"\n  msg \"$FLAG $REASON\"\n}\nfunction msg() {\n  local TEXT=\"$1\"\n  echo -e \"$TEXT\"\n}\nfunction cleanup_ctid() {\n  if pct status $CTID &>/dev/null; then\n    if [ \"$(pct status $CTID | awk '{print $2}')\" == \"running\" ]; then\n      pct stop $CTID\n    fi\n    pct destroy $CTID\n  fi\n}\n\n# Stop Proxmox VE Monitor-All if running\nif systemctl is-active -q ping-instances.service; then\n  systemctl stop ping-instances.service\nfi\nheader_info\nwhiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"TurnKey LXCs\" --yesno \"This will allow for the creation of one of the many TurnKey LXC Containers. Proceed?\" 10 68 || exit\nTURNKEY_MENU=()\nMSG_MAX_LENGTH=0\nwhile read -r TAG ITEM; do\n  OFFSET=2\n  ((${#ITEM} + OFFSET > MSG_MAX_LENGTH)) && MSG_MAX_LENGTH=${#ITEM}+OFFSET\n  TURNKEY_MENU+=(\"$TAG\" \"$ITEM \" \"OFF\")\ndone < <(\n  cat <<EOF\nansible Ansible\nbookstack BookStack\ncore Core\nfaveo-helpdesk Faveo Helpdesk\nfileserver File Server\ngallery Gallery\ngameserver Game Server\ngitea Gitea\ngitlab GitLab\ninvoice-ninja Invoice Ninja\nmediaserver Media Server\nnextcloud Nextcloud\nobservium Observium\nodoo Odoo\nopenvpn OpenVPN\nowncloud ownCloud\nphpbb phpBB\ntorrentserver Torrent Server\nwireguard WireGuard\nwordpress Wordpress\nzoneminder ZoneMinder\nEOF\n)\nturnkey=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"TurnKey LXCs\" --radiolist \"\\nSelect a TurnKey LXC to create:\\n\" 16 $((MSG_MAX_LENGTH + 58)) 6 \"${TURNKEY_MENU[@]}\" 3>&1 1>&2 2>&3 | tr -d '\"') || exit\n[ -z \"$turnkey\" ] && {\n  whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"No TurnKey LXC Selected\" --msgbox \"It appears that no TurnKey LXC container was selected\" 10 68\n  msg \"Done\"\n  exit\n}\n\n# Setup script environment\nPASS=\"$(openssl rand -base64 8)\"\nCTID=$(pvesh get /cluster/nextid)\nPCT_OPTIONS=\"\n    -features keyctl=1,nesting=1\n    -hostname turnkey-${turnkey}\n    -tags proxmox-helper-scripts\n    -onboot 1\n    -cores 2\n    -memory 2048\n    -password $PASS\n    -net0 name=eth0,bridge=vmbr0,ip=dhcp\n    -unprivileged 1\n  \"\nDEFAULT_PCT_OPTIONS=(\n  -arch $(dpkg --print-architecture)\n)\n\n# Set the CONTENT and CONTENT_LABEL variables\nfunction select_storage() {\n  local CLASS=$1\n  local CONTENT\n  local CONTENT_LABEL\n  case $CLASS in\n  container)\n    CONTENT='rootdir'\n    CONTENT_LABEL='Container'\n    ;;\n  template)\n    CONTENT='vztmpl'\n    CONTENT_LABEL='Container template'\n    ;;\n  *) false || die \"Invalid storage class.\" ;;\n  esac\n\n  # Query all storage locations\n  local -a MENU\n  while read -r line; do\n    local TAG=$(echo $line | awk '{print $1}')\n    local TYPE=$(echo $line | awk '{printf \"%-10s\", $2}')\n    local FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( \"%9sB\", $6)}')\n    local ITEM=\"  Type: $TYPE Free: $FREE \"\n    local OFFSET=2\n    if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then\n      local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET))\n    fi\n    MENU+=(\"$TAG\" \"$ITEM\" \"OFF\")\n  done < <(pvesm status -content $CONTENT | awk 'NR>1')\n\n  # Select storage location\n  if [ $((${#MENU[@]} / 3)) -eq 0 ]; then\n    warn \"'$CONTENT_LABEL' needs to be selected for at least one storage location.\"\n    die \"Unable to detect valid storage location.\"\n  elif [ $((${#MENU[@]} / 3)) -eq 1 ]; then\n    printf ${MENU[0]}\n  else\n    local STORAGE\n    while [ -z \"${STORAGE:+x}\" ]; do\n      STORAGE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"Storage Pools\" --radiolist \\\n        \"Which storage pool you would like to use for the ${CONTENT_LABEL,,}?\\n\\n\" \\\n        16 $(($MSG_MAX_LENGTH + 23)) 6 \\\n        \"${MENU[@]}\" 3>&1 1>&2 2>&3) || die \"Menu aborted.\"\n    done\n    printf $STORAGE\n  fi\n}\n\n# Get template storage\nTEMPLATE_STORAGE=$(select_storage template) || exit\ninfo \"Using '$TEMPLATE_STORAGE' for template storage.\"\n\n# Get container storage\nCONTAINER_STORAGE=$(select_storage container) || exit\ninfo \"Using '$CONTAINER_STORAGE' for container storage.\"\n\n# Update LXC template list\nmsg \"Updating LXC template list...\"\npveam update >/dev/null\n\n# Get LXC template string\nmapfile -t TEMPLATES < <(pveam available -section turnkeylinux | awk -v turnkey=\"${turnkey}\" '$0 ~ turnkey {print $2}' | sort -t - -k 2 -V)\n[ ${#TEMPLATES[@]} -gt 0 ] || die \"Unable to find a template when searching for '${turnkey}'.\"\nTEMPLATE=\"${TEMPLATES[-1]}\"\n\n# Download LXC template\nif ! pveam list $TEMPLATE_STORAGE | grep -q $TEMPLATE; then\n  msg \"Downloading LXC template (Patience)...\"\n  pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null ||\n    die \"A problem occured while downloading the LXC template.\"\nfi\n\n# Create variable for 'pct' options\nPCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}})\n[[ \" ${PCT_OPTIONS[@]} \" =~ \" -rootfs \" ]] || PCT_OPTIONS+=(-rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8})\n\n# Create LXC\nmsg \"Creating LXC container...\"\npct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null ||\n  die \"A problem occured while trying to create container.\"\n\n# Save password\necho \"TurnKey ${turnkey} password: ${PASS}\" >>~/turnkey-${turnkey}.creds # file is located in the Proxmox root directory\n\n# Start container\nmsg \"Starting LXC Container...\"\npct start \"$CTID\"\nsleep 5\n\n# Get container IP\nset +euo pipefail # Turn off error checking\nmax_attempts=5\nattempt=1\nIP=\"\"\nwhile [[ $attempt -le $max_attempts ]]; do\n  IP=$(pct exec $CTID ip a show dev eth0 | grep -oP 'inet \\K[^/]+')\n  if [[ -n $IP ]]; then\n    break\n  else\n    warn \"Attempt $attempt: IP address not found. Pausing for 5 seconds...\"\n    sleep 5\n    ((attempt++))\n  fi\ndone\n\nif [[ -z $IP ]]; then\n  warn \"Maximum number of attempts reached. IP address not found.\"\n  IP=\"NOT FOUND\"\nfi\n\n# Start Proxmox VE Monitor-All if available\nif [[ -f /etc/systemd/system/ping-instances.service ]]; then\n  systemctl start ping-instances.service\nfi\n\n# Success message\nheader_info\necho\ninfo \"LXC container '$CTID' was successfully created, and its IP address is ${IP}.\"\necho\ninfo \"Proceed to the LXC console to complete the setup.\"\necho\ninfo \"login: root\"\ninfo \"password: $PASS\"\necho\n"
  },
  {
    "path": "vm/debian-vm.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\n  clear\n  cat <<\"EOF\"\n    ____       __    _                ______\n   / __ \\___  / /_  (_)___ _____     <  /__ \\\n  / / / / _ \\/ __ \\/ / __ `/ __ \\    / /__/ /\n / /_/ /  __/ /_/ / / /_/ / / / /   / // __/\n/_____/\\___/_.___/_/\\__,_/_/ /_/   /_//____/\n\nEOF\n}\nheader_info\necho -e \"\\n Loading...\"\nGEN_MAC=02:$(openssl rand -hex 5 | awk '{print toupper($0)}' | sed 's/\\(..\\)/\\1:/g; s/.$//')\nNEXTID=$(pvesh get /cluster/nextid)\n\nYW=$(echo \"\\033[33m\")\nBL=$(echo \"\\033[36m\")\nHA=$(echo \"\\033[1;34m\")\nRD=$(echo \"\\033[01;31m\")\nBGN=$(echo \"\\033[4;92m\")\nGN=$(echo \"\\033[1;92m\")\nDGN=$(echo \"\\033[32m\")\nCL=$(echo \"\\033[m\")\nBFR=\"\\\\r\\\\033[K\"\nHOLD=\"-\"\nCM=\"${GN}✓${CL}\"\nCROSS=\"${RD}✗${CL}\"\nTHIN=\"discard=on,ssd=1,\"\nset -e\ntrap 'error_handler $LINENO \"$BASH_COMMAND\"' ERR\ntrap cleanup EXIT\nfunction error_handler() {\n  local exit_code=\"$?\"\n  local line_number=\"$1\"\n  local command=\"$2\"\n  local error_message=\"${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}\"\n  echo -e \"\\n$error_message\\n\"\n  cleanup_vmid\n}\n\nfunction cleanup_vmid() {\n  if qm status $VMID &>/dev/null; then\n    qm stop $VMID &>/dev/null\n    qm destroy $VMID &>/dev/null\n  fi\n}\n\nfunction cleanup() {\n  popd >/dev/null\n  rm -rf $TEMP_DIR\n}\n\nTEMP_DIR=$(mktemp -d)\npushd $TEMP_DIR >/dev/null\nif whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"Debian 12 VM\" --yesno \"This will create a New Debian 12 VM. Proceed?\" 10 58; then\n  :\nelse\n  header_info && echo -e \"⚠ User exited script \\n\" && exit\nfi\n\nfunction msg_info() {\n  local msg=\"$1\"\n  echo -ne \" ${HOLD} ${YW}${msg}...\"\n}\n\nfunction msg_ok() {\n  local msg=\"$1\"\n  echo -e \"${BFR} ${CM} ${GN}${msg}${CL}\"\n}\n\nfunction msg_error() {\n  local msg=\"$1\"\n  echo -e \"${BFR} ${CROSS} ${RD}${msg}${CL}\"\n}\n\nfunction check_root() {\n  if [[ \"$(id -u)\" -ne 0 || $(ps -o comm= -p $PPID) == \"sudo\" ]]; then\n    clear\n    msg_error \"Please run this script as root.\"\n    echo -e \"\\nExiting...\"\n    sleep 2\n    exit\n  fi\n}\n\nfunction pve_check() {\n  if ! pveversion | grep -Eq \"pve-manager/8.[1-3]\"; then\n    msg_error \"This version of Proxmox Virtual Environment is not supported\"\n    echo -e \"Requires Proxmox Virtual Environment Version 8.1 or later.\"\n    echo -e \"Exiting...\"\n    sleep 2\n    exit\nfi\n}\n\nfunction arch_check() {\n  if [ \"$(dpkg --print-architecture)\" != \"amd64\" ]; then\n    msg_error \"This script will not work with PiMox! \\n\"\n    echo -e \"Exiting...\"\n    sleep 2\n    exit\n  fi\n}\n\nfunction ssh_check() {\n  if command -v pveversion >/dev/null 2>&1; then\n    if [ -n \"${SSH_CLIENT:+x}\" ]; then\n      if whiptail --backtitle \"Proxmox VE Helper Scripts\" --defaultno --title \"SSH DETECTED\" --yesno \"It's suggested to use the Proxmox shell instead of SSH, since SSH can create issues while gathering variables. Would you like to proceed with using SSH?\" 10 62; then\n        echo \"you've been warned\"\n      else\n        clear\n        exit\n      fi\n    fi\n  fi\n}\n\nfunction exit-script() {\n  clear\n  echo -e \"⚠  User exited script \\n\"\n  exit\n}\n\nfunction default_settings() {\n  VMID=\"$NEXTID\"\n  FORMAT=\",efitype=4m\"\n  MACHINE=\"\"\n  DISK_CACHE=\"\"\n  HN=\"debian\"\n  CPU_TYPE=\"\"\n  CORE_COUNT=\"2\"\n  RAM_SIZE=\"2048\"\n  BRG=\"vmbr0\"\n  MAC=\"$GEN_MAC\"\n  VLAN=\"\"\n  MTU=\"\"\n  START_VM=\"yes\"\n  echo -e \"${DGN}Using Virtual Machine ID: ${BGN}${VMID}${CL}\"\n  echo -e \"${DGN}Using Machine Type: ${BGN}i440fx${CL}\"\n  echo -e \"${DGN}Using Disk Cache: ${BGN}None${CL}\"\n  echo -e \"${DGN}Using Hostname: ${BGN}${HN}${CL}\"\n  echo -e \"${DGN}Using CPU Model: ${BGN}KVM64${CL}\"\n  echo -e \"${DGN}Allocated Cores: ${BGN}${CORE_COUNT}${CL}\"\n  echo -e \"${DGN}Allocated RAM: ${BGN}${RAM_SIZE}${CL}\"\n  echo -e \"${DGN}Using Bridge: ${BGN}${BRG}${CL}\"\n  echo -e \"${DGN}Using MAC Address: ${BGN}${MAC}${CL}\"\n  echo -e \"${DGN}Using VLAN: ${BGN}Default${CL}\"\n  echo -e \"${DGN}Using Interface MTU Size: ${BGN}Default${CL}\"\n  echo -e \"${DGN}Start VM when completed: ${BGN}yes${CL}\"\n  echo -e \"${BL}Creating a Debian 12 VM using the above default settings${CL}\"\n}\n\nfunction advanced_settings() {\n  while true; do\n    if VMID=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set Virtual Machine ID\" 8 58 $NEXTID --title \"VIRTUAL MACHINE ID\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n      if [ -z \"$VMID\" ]; then\n        VMID=\"$NEXTID\"\n      fi\n      if pct status \"$VMID\" &>/dev/null || qm status \"$VMID\" &>/dev/null; then\n        echo -e \"${CROSS}${RD} ID $VMID is already in use${CL}\"\n        sleep 2\n        continue\n      fi\n      echo -e \"${DGN}Virtual Machine ID: ${BGN}$VMID${CL}\"\n      break\n    else\n      exit-script\n    fi\n  done\n\n  if MACH=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"MACHINE TYPE\" --radiolist --cancel-button Exit-Script \"Choose Type\" 10 58 2 \\\n    \"i440fx\" \"Machine i440fx\" ON \\\n    \"q35\" \"Machine q35\" OFF \\\n    3>&1 1>&2 2>&3); then\n    if [ $MACH = q35 ]; then\n      echo -e \"${DGN}Using Machine Type: ${BGN}$MACH${CL}\"\n      FORMAT=\"\"\n      MACHINE=\" -machine q35\"\n    else\n      echo -e \"${DGN}Using Machine Type: ${BGN}$MACH${CL}\"\n      FORMAT=\",efitype=4m\"\n      MACHINE=\"\"\n    fi\n  else\n    exit-script\n  fi\n\n  if DISK_CACHE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"DISK CACHE\" --radiolist \"Choose\" --cancel-button Exit-Script 10 58 2 \\\n    \"0\" \"None (Default)\" ON \\\n    \"1\" \"Write Through\" OFF \\\n    3>&1 1>&2 2>&3); then\n    if [ $DISK_CACHE = \"1\" ]; then\n      echo -e \"${DGN}Using Disk Cache: ${BGN}Write Through${CL}\"\n      DISK_CACHE=\"cache=writethrough,\"\n    else\n      echo -e \"${DGN}Using Disk Cache: ${BGN}None${CL}\"\n      DISK_CACHE=\"\"\n    fi\n  else\n    exit-script\n  fi\n\n  if VM_NAME=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set Hostname\" 8 58 debian --title \"HOSTNAME\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $VM_NAME ]; then\n      HN=\"debian\"\n      echo -e \"${DGN}Using Hostname: ${BGN}$HN${CL}\"\n    else\n      HN=$(echo ${VM_NAME,,} | tr -d ' ')\n      echo -e \"${DGN}Using Hostname: ${BGN}$HN${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  if CPU_TYPE1=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"CPU MODEL\" --radiolist \"Choose\" --cancel-button Exit-Script 10 58 2 \\\n    \"0\" \"KVM64 (Default)\" ON \\\n    \"1\" \"Host\" OFF \\\n    3>&1 1>&2 2>&3); then\n    if [ $CPU_TYPE1 = \"1\" ]; then\n      echo -e \"${DGN}Using CPU Model: ${BGN}Host${CL}\"\n      CPU_TYPE=\" -cpu host\"\n    else\n      echo -e \"${DGN}Using CPU Model: ${BGN}KVM64${CL}\"\n      CPU_TYPE=\"\"\n    fi\n  else\n    exit-script\n  fi\n\n  if CORE_COUNT=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Allocate CPU Cores\" 8 58 2 --title \"CORE COUNT\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $CORE_COUNT ]; then\n      CORE_COUNT=\"2\"\n      echo -e \"${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}\"\n    else\n      echo -e \"${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  if RAM_SIZE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Allocate RAM in MiB\" 8 58 2048 --title \"RAM\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $RAM_SIZE ]; then\n      RAM_SIZE=\"2048\"\n      echo -e \"${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}\"\n    else\n      echo -e \"${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  if BRG=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set a Bridge\" 8 58 vmbr0 --title \"BRIDGE\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $BRG ]; then\n      BRG=\"vmbr0\"\n      echo -e \"${DGN}Using Bridge: ${BGN}$BRG${CL}\"\n    else\n      echo -e \"${DGN}Using Bridge: ${BGN}$BRG${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  if MAC1=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set a MAC Address\" 8 58 $GEN_MAC --title \"MAC ADDRESS\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $MAC1 ]; then\n      MAC=\"$GEN_MAC\"\n      echo -e \"${DGN}Using MAC Address: ${BGN}$MAC${CL}\"\n    else\n      MAC=\"$MAC1\"\n      echo -e \"${DGN}Using MAC Address: ${BGN}$MAC1${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  if VLAN1=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set a Vlan(leave blank for default)\" 8 58 --title \"VLAN\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $VLAN1 ]; then\n      VLAN1=\"Default\"\n      VLAN=\"\"\n      echo -e \"${DGN}Using Vlan: ${BGN}$VLAN1${CL}\"\n    else\n      VLAN=\",tag=$VLAN1\"\n      echo -e \"${DGN}Using Vlan: ${BGN}$VLAN1${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  if MTU1=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set Interface MTU Size (leave blank for default)\" 8 58 --title \"MTU SIZE\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $MTU1 ]; then\n      MTU1=\"Default\"\n      MTU=\"\"\n      echo -e \"${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}\"\n    else\n      MTU=\",mtu=$MTU1\"\n      echo -e \"${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  if (whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"START VIRTUAL MACHINE\" --yesno \"Start VM when completed?\" 10 58); then\n    echo -e \"${DGN}Start VM when completed: ${BGN}yes${CL}\"\n    START_VM=\"yes\"\n  else\n    echo -e \"${DGN}Start VM when completed: ${BGN}no${CL}\"\n    START_VM=\"no\"\n  fi\n\n  if (whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"ADVANCED SETTINGS COMPLETE\" --yesno \"Ready to create a Debian 12 VM?\" --no-button Do-Over 10 58); then\n    echo -e \"${RD}Creating a Debian 12 VM using the above advanced settings${CL}\"\n  else\n    header_info\n    echo -e \"${RD}Using Advanced Settings${CL}\"\n    advanced_settings\n  fi\n}\n\nfunction start_script() {\n  if (whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"SETTINGS\" --yesno \"Use Default Settings?\" --no-button Advanced 10 58); then\n    header_info\n    echo -e \"${BL}Using Default Settings${CL}\"\n    default_settings\n  else\n    header_info\n    echo -e \"${RD}Using Advanced Settings${CL}\"\n    advanced_settings\n  fi\n}\n\ncheck_root\narch_check\npve_check\nssh_check\nstart_script\n\nmsg_info \"Validating Storage\"\nwhile read -r line; do\n  TAG=$(echo $line | awk '{print $1}')\n  TYPE=$(echo $line | awk '{printf \"%-10s\", $2}')\n  FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( \"%9sB\", $6)}')\n  ITEM=\"  Type: $TYPE Free: $FREE \"\n  OFFSET=2\n  if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then\n    MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET))\n  fi\n  STORAGE_MENU+=(\"$TAG\" \"$ITEM\" \"OFF\")\ndone < <(pvesm status -content images | awk 'NR>1')\nVALID=$(pvesm status -content images | awk 'NR>1')\nif [ -z \"$VALID\" ]; then\n  msg_error \"Unable to detect a valid storage location.\"\n  exit\nelif [ $((${#STORAGE_MENU[@]} / 3)) -eq 1 ]; then\n  STORAGE=${STORAGE_MENU[0]}\nelse\n  while [ -z \"${STORAGE:+x}\" ]; do\n    STORAGE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"Storage Pools\" --radiolist \\\n      \"Which storage pool you would like to use for ${HN}?\\nTo make a selection, use the Spacebar.\\n\" \\\n      16 $(($MSG_MAX_LENGTH + 23)) 6 \\\n      \"${STORAGE_MENU[@]}\" 3>&1 1>&2 2>&3) || exit\n  done\nfi\nmsg_ok \"Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location.\"\nmsg_ok \"Virtual Machine ID is ${CL}${BL}$VMID${CL}.\"\nmsg_info \"Retrieving the URL for the Debian 12 Qcow2 Disk Image\"\nURL=https://cloud.debian.org/images/cloud/bookworm/20240507-1740/debian-12-nocloud-amd64-20240507-1740.qcow2\nsleep 2\nmsg_ok \"${CL}${BL}${URL}${CL}\"\nwget -q --show-progress $URL\necho -en \"\\e[1A\\e[0K\"\nFILE=$(basename $URL)\nmsg_ok \"Downloaded ${CL}${BL}${FILE}${CL}\"\n\nSTORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}')\ncase $STORAGE_TYPE in\nnfs | dir)\n  DISK_EXT=\".qcow2\"\n  DISK_REF=\"$VMID/\"\n  DISK_IMPORT=\"-format qcow2\"\n  THIN=\"\"\n  ;;\nbtrfs)\n  DISK_EXT=\".raw\"\n  DISK_REF=\"$VMID/\"\n  DISK_IMPORT=\"-format raw\"\n  FORMAT=\",efitype=4m\"\n  THIN=\"\"\n  ;;\nesac\nfor i in {0,1}; do\n  disk=\"DISK$i\"\n  eval DISK${i}=vm-${VMID}-disk-${i}${DISK_EXT:-}\n  eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk}\ndone\n\nmsg_info \"Creating a Debian 12 VM\"\nqm create $VMID -agent 1${MACHINE} -tablet 0 -localtime 1 -bios ovmf${CPU_TYPE} -cores $CORE_COUNT -memory $RAM_SIZE \\\n  -name $HN -tags proxmox-helper-scripts -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU -onboot 1 -ostype l26 -scsihw virtio-scsi-pci\npvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null\nqm importdisk $VMID ${FILE} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null\nqm set $VMID \\\n  -efidisk0 ${DISK0_REF}${FORMAT} \\\n  -scsi0 ${DISK1_REF},${DISK_CACHE}${THIN}size=2G \\\n  -boot order=scsi0 \\\n  -serial0 socket \\\n  -description \"<div align='center'><a href='https://Helper-Scripts.com'><img src='https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/logo-81x112.png'/></a>\n\n  # Debian 12 VM\n\n  <a href='https://ko-fi.com/D1D7EP4GF'><img src='https://img.shields.io/badge/&#x2615;-Buy me a coffee-blue' /></a>\n  </div>\" >/dev/null\nmsg_ok \"Created a Debian 12 VM ${CL}${BL}(${HN})\"\nif [ \"$START_VM\" == \"yes\" ]; then\n  msg_info \"Starting Debian 12 VM\"\n  qm start $VMID\n  msg_ok \"Started Debian 12 VM\"\nfi\nmsg_ok \"Completed Successfully!\\n\"\necho \"More Info at https://github.com/tteck/Proxmox/discussions/1988\"\n"
  },
  {
    "path": "vm/haos-vm.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\n  clear\n  cat <<\"EOF\"\n    __  __                        ___              _      __              __     ____  _____\n   / / / /___  ____ ___  ___     /   |  __________(_)____/ /_____ _____  / /_   / __ \\/ ___/\n  / /_/ / __ \\/ __ `__ \\/ _ \\   / /| | / ___/ ___/ / ___/ __/ __ `/ __ \\/ __/  / / / /\\__ \\\n / __  / /_/ / / / / / /  __/  / ___ |(__  |__  ) (__  ) /_/ /_/ / / / / /_   / /_/ /___/ /\n/_/ /_/\\____/_/ /_/ /_/\\___/  /_/  |_/____/____/_/____/\\__/\\__,_/_/ /_/\\__/   \\____//____/\n\nEOF\n}\nheader_info\necho -e \"\\n Loading...\"\nGEN_MAC=02:$(openssl rand -hex 5 | awk '{print toupper($0)}' | sed 's/\\(..\\)/\\1:/g; s/.$//')\nNEXTID=$(pvesh get /cluster/nextid)\nVERSIONS=(stable beta dev)\nfor version in \"${VERSIONS[@]}\"; do\n  eval \"$version=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/$version.json | grep \"ova\" | cut -d '\"' -f 4)\"\ndone\nYW=$(echo \"\\033[33m\")\nBL=$(echo \"\\033[36m\")\nHA=$(echo \"\\033[1;34m\")\nRD=$(echo \"\\033[01;31m\")\nBGN=$(echo \"\\033[4;92m\")\nGN=$(echo \"\\033[1;92m\")\nDGN=$(echo \"\\033[32m\")\nCL=$(echo \"\\033[m\")\nBFR=\"\\\\r\\\\033[K\"\nHOLD=\" \"\nCM=\"${GN}✓${CL}\"\nCROSS=\"${RD}✗${CL}\"\nTHIN=\"discard=on,ssd=1,\"\nSPINNER_PID=\"\"\nset -Eeuo pipefail\ntrap 'error_handler $LINENO \"$BASH_COMMAND\"' ERR\ntrap cleanup EXIT\n\nfunction error_handler() {\n  if [ -n \"$SPINNER_PID\" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi\n  printf \"\\e[?25h\"\n  local exit_code=\"$?\"\n  local line_number=\"$1\"\n  local command=\"$2\"\n  local error_message=\"${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}\"\n  echo -e \"\\n$error_message\\n\"\n  cleanup_vmid\n}\n\nfunction cleanup_vmid() {\n  if qm status $VMID &>/dev/null; then\n    qm stop $VMID &>/dev/null\n    qm destroy $VMID &>/dev/null\n  fi\n}\n\nfunction cleanup() {\n  popd >/dev/null\n  rm -rf $TEMP_DIR\n}\n\nTEMP_DIR=$(mktemp -d)\npushd $TEMP_DIR >/dev/null\nif whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"HOME ASSISTANT OS VM\" --yesno \"This will create a New Home Assistant OS VM. Proceed?\" 10 58; then\n  :\nelse\n  header_info && echo -e \"⚠ User exited script \\n\" && exit\nfi\n\nfunction spinner() {\n    local chars=\"/-\\|\"\n    local spin_i=0\n    printf \"\\e[?25l\"\n    while true; do\n        printf \"\\r \\e[36m%s\\e[0m\" \"${chars:spin_i++%${#chars}:1}\"\n        sleep 0.1\n    done\n}\n\nfunction msg_info() {\n  local msg=\"$1\"\n  echo -ne \" ${HOLD} ${YW}${msg}   \"\n  spinner &\n  SPINNER_PID=$!\n}\n\nfunction msg_ok() {\n  if [ -n \"$SPINNER_PID\" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi\n  printf \"\\e[?25h\"\n  local msg=\"$1\"\n  echo -e \"${BFR} ${CM} ${GN}${msg}${CL}\"\n}\n\nfunction msg_error() {\n  if [ -n \"$SPINNER_PID\" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi\n  printf \"\\e[?25h\"\n  local msg=\"$1\"\n  echo -e \"${BFR} ${CROSS} ${RD}${msg}${CL}\"\n}\n\nfunction check_root() {\n  if [[ \"$(id -u)\" -ne 0 || $(ps -o comm= -p $PPID) == \"sudo\" ]]; then\n    clear\n    msg_error \"Please run this script as root.\"\n    echo -e \"\\nExiting...\"\n    sleep 2\n    exit\n  fi\n}\n\nfunction pve_check() {\n  if ! pveversion | grep -Eq \"pve-manager/8.[1-3]\"; then\n    msg_error \"This version of Proxmox Virtual Environment is not supported\"\n    echo -e \"Requires Proxmox Virtual Environment Version 8.1 or later.\"\n    echo -e \"Exiting...\"\n    sleep 2\n    exit\nfi\n}\n\nfunction arch_check() {\n  if [ \"$(dpkg --print-architecture)\" != \"amd64\" ]; then\n    msg_error \"This script will not work with PiMox! \\n\"\n    echo -e \"Exiting...\"\n    sleep 2\n    exit\n  fi\n}\n\nfunction ssh_check() {\n  if command -v pveversion >/dev/null 2>&1; then\n    if [ -n \"${SSH_CLIENT:+x}\" ]; then\n      if whiptail --backtitle \"Proxmox VE Helper Scripts\" --defaultno --title \"SSH DETECTED\" --yesno \"It's suggested to use the Proxmox shell instead of SSH, since SSH can create issues while gathering variables. Would you like to proceed with using SSH?\" 10 62; then\n        echo \"you've been warned\"\n      else\n        clear\n        exit\n      fi\n    fi\n  fi\n}\n\nfunction exit-script() {\n  clear\n  echo -e \"⚠  User exited script \\n\"\n  exit\n}\n\nfunction default_settings() {\n  BRANCH=\"$stable\"\n  VMID=\"$NEXTID\"\n  FORMAT=\",efitype=4m\"\n  MACHINE=\"\"\n  DISK_CACHE=\"cache=writethrough,\"\n  HN=\"haos$stable\"\n  CPU_TYPE=\" -cpu host\"\n  CORE_COUNT=\"2\"\n  RAM_SIZE=\"4096\"\n  BRG=\"vmbr0\"\n  MAC=\"$GEN_MAC\"\n  VLAN=\"\"\n  MTU=\"\"\n  START_VM=\"yes\"\n  echo -e \"${DGN}Using HAOS Version: ${BGN}${BRANCH}${CL}\"\n  echo -e \"${DGN}Using Virtual Machine ID: ${BGN}${VMID}${CL}\"\n  echo -e \"${DGN}Using Machine Type: ${BGN}i440fx${CL}\"\n  echo -e \"${DGN}Using Disk Cache: ${BGN}Write Through${CL}\"\n  echo -e \"${DGN}Using Hostname: ${BGN}${HN}${CL}\"\n  echo -e \"${DGN}Using CPU Model: ${BGN}Host${CL}\"\n  echo -e \"${DGN}Allocated Cores: ${BGN}${CORE_COUNT}${CL}\"\n  echo -e \"${DGN}Allocated RAM: ${BGN}${RAM_SIZE}${CL}\"\n  echo -e \"${DGN}Using Bridge: ${BGN}${BRG}${CL}\"\n  echo -e \"${DGN}Using MAC Address: ${BGN}${MAC}${CL}\"\n  echo -e \"${DGN}Using VLAN: ${BGN}Default${CL}\"\n  echo -e \"${DGN}Using Interface MTU Size: ${BGN}Default${CL}\"\n  echo -e \"${DGN}Start VM when completed: ${BGN}yes${CL}\"\n  echo -e \"${BL}Creating a HAOS VM using the above default settings${CL}\"\n}\n\nfunction advanced_settings() {\n  if BRANCH=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"HAOS VERSION\" --radiolist \"Choose Version\" --cancel-button Exit-Script 10 58 3 \\\n    \"$stable\" \"Stable  \" ON \\\n    \"$beta\" \"Beta  \" OFF \\\n    \"$dev\" \"Dev  \" OFF \\\n    3>&1 1>&2 2>&3); then\n    echo -e \"${DGN}Using HAOS Version: ${BGN}$BRANCH${CL}\"\n  else\n    exit-script\n  fi\n\n  while true; do\n    if VMID=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set Virtual Machine ID\" 8 58 $NEXTID --title \"VIRTUAL MACHINE ID\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n      if [ -z \"$VMID\" ]; then\n        VMID=\"$NEXTID\"\n      fi\n      if pct status \"$VMID\" &>/dev/null || qm status \"$VMID\" &>/dev/null; then\n        echo -e \"${CROSS}${RD} ID $VMID is already in use${CL}\"\n        sleep 2\n        continue\n      fi\n      echo -e \"${DGN}Virtual Machine ID: ${BGN}$VMID${CL}\"\n      break\n    else\n      exit-script\n    fi\n  done\n\n  if MACH=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"MACHINE TYPE\" --radiolist --cancel-button Exit-Script \"Choose Type\" 10 58 2 \\\n    \"i440fx\" \"Machine i440fx\" ON \\\n    \"q35\" \"Machine q35\" OFF \\\n    3>&1 1>&2 2>&3); then\n    if [ $MACH = q35 ]; then\n      echo -e \"${DGN}Using Machine Type: ${BGN}$MACH${CL}\"\n      FORMAT=\"\"\n      MACHINE=\" -machine q35\"\n    else\n      echo -e \"${DGN}Using Machine Type: ${BGN}$MACH${CL}\"\n      FORMAT=\",efitype=4m\"\n      MACHINE=\"\"\n    fi\n  else\n    exit-script\n  fi\n\n  if DISK_CACHE1=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"DISK CACHE\" --radiolist \"Choose\" --cancel-button Exit-Script 10 58 2 \\\n    \"0\" \"None\" OFF \\\n    \"1\" \"Write Through (Default)\" ON \\\n    3>&1 1>&2 2>&3); then\n    if [ $DISK_CACHE1 = \"1\" ]; then\n      echo -e \"${DGN}Using Disk Cache: ${BGN}Write Through${CL}\"\n      DISK_CACHE=\"cache=writethrough,\"\n    else\n      echo -e \"${DGN}Using Disk Cache: ${BGN}None${CL}\"\n      DISK_CACHE=\"\"\n    fi\n  else\n    exit-script\n  fi\n\n  if VM_NAME=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set Hostname\" 8 58 haos${BRANCH} --title \"HOSTNAME\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $VM_NAME ]; then\n      HN=\"haos${BRANCH}\"\n      echo -e \"${DGN}Using Hostname: ${BGN}$HN${CL}\"\n    else\n      HN=$(echo ${VM_NAME,,} | tr -d ' ')\n      echo -e \"${DGN}Using Hostname: ${BGN}$HN${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  if CPU_TYPE1=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"CPU MODEL\" --radiolist \"Choose\" --cancel-button Exit-Script 10 58 2 \\\n    \"0\" \"KVM64\" OFF \\\n    \"1\" \"Host (Default)\" ON \\\n    3>&1 1>&2 2>&3); then\n    if [ $CPU_TYPE1 = \"1\" ]; then\n      echo -e \"${DGN}Using CPU Model: ${BGN}Host${CL}\"\n      CPU_TYPE=\" -cpu host\"\n    else\n      echo -e \"${DGN}Using CPU Model: ${BGN}KVM64${CL}\"\n      CPU_TYPE=\"\"\n    fi\n  else\n    exit-script\n  fi\n\n  if CORE_COUNT=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Allocate CPU Cores\" 8 58 2 --title \"CORE COUNT\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $CORE_COUNT ]; then\n      CORE_COUNT=\"2\"\n      echo -e \"${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}\"\n    else\n      echo -e \"${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  if RAM_SIZE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Allocate RAM in MiB\" 8 58 4096 --title \"RAM\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $RAM_SIZE ]; then\n      RAM_SIZE=\"4096\"\n      echo -e \"${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}\"\n    else\n      echo -e \"${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  if BRG=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set a Bridge\" 8 58 vmbr0 --title \"BRIDGE\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $BRG ]; then\n      BRG=\"vmbr0\"\n      echo -e \"${DGN}Using Bridge: ${BGN}$BRG${CL}\"\n    else\n      echo -e \"${DGN}Using Bridge: ${BGN}$BRG${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  if MAC1=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set a MAC Address\" 8 58 $GEN_MAC --title \"MAC ADDRESS\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $MAC1 ]; then\n      MAC=\"$GEN_MAC\"\n      echo -e \"${DGN}Using MAC Address: ${BGN}$MAC${CL}\"\n    else\n      MAC=\"$MAC1\"\n      echo -e \"${DGN}Using MAC Address: ${BGN}$MAC1${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  if VLAN1=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set a Vlan(leave blank for default)\" 8 58 --title \"VLAN\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $VLAN1 ]; then\n      VLAN1=\"Default\"\n      VLAN=\"\"\n      echo -e \"${DGN}Using Vlan: ${BGN}$VLAN1${CL}\"\n    else\n      VLAN=\",tag=$VLAN1\"\n      echo -e \"${DGN}Using Vlan: ${BGN}$VLAN1${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  if MTU1=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set Interface MTU Size (leave blank for default)\" 8 58 --title \"MTU SIZE\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $MTU1 ]; then\n      MTU1=\"Default\"\n      MTU=\"\"\n      echo -e \"${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}\"\n    else\n      MTU=\",mtu=$MTU1\"\n      echo -e \"${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  if (whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"START VIRTUAL MACHINE\" --yesno \"Start VM when completed?\" 10 58); then\n    echo -e \"${DGN}Start VM when completed: ${BGN}yes${CL}\"\n    START_VM=\"yes\"\n  else\n    echo -e \"${DGN}Start VM when completed: ${BGN}no${CL}\"\n    START_VM=\"no\"\n  fi\n\n  if (whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"ADVANCED SETTINGS COMPLETE\" --yesno \"Ready to create HAOS ${BRANCH} VM?\" --no-button Do-Over 10 58); then\n    echo -e \"${RD}Creating a HAOS VM using the above advanced settings${CL}\"\n  else\n    header_info\n    echo -e \"${RD}Using Advanced Settings${CL}\"\n    advanced_settings\n  fi\n}\n\nfunction start_script() {\n  if (whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"SETTINGS\" --yesno \"Use Default Settings?\" --no-button Advanced 10 58); then\n    header_info\n    echo -e \"${BL}Using Default Settings${CL}\"\n    default_settings\n  else\n    header_info\n    echo -e \"${RD}Using Advanced Settings${CL}\"\n    advanced_settings\n  fi\n}\n\ncheck_root\narch_check\npve_check\nssh_check\nstart_script\n\nmsg_info \"Validating Storage\"\nwhile read -r line; do\n  TAG=$(echo $line | awk '{print $1}')\n  TYPE=$(echo $line | awk '{printf \"%-10s\", $2}')\n  FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( \"%9sB\", $6)}')\n  ITEM=\"  Type: $TYPE Free: $FREE \"\n  OFFSET=2\n  if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then\n    MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET))\n  fi\n  STORAGE_MENU+=(\"$TAG\" \"$ITEM\" \"OFF\")\ndone < <(pvesm status -content images | awk 'NR>1')\nVALID=$(pvesm status -content images | awk 'NR>1')\nif [ -z \"$VALID\" ]; then\n  msg_error \"Unable to detect a valid storage location.\"\n  exit\nelif [ $((${#STORAGE_MENU[@]} / 3)) -eq 1 ]; then\n  STORAGE=${STORAGE_MENU[0]}\nelse\n  while [ -z \"${STORAGE:+x}\" ]; do\n    if [ -n \"$SPINNER_PID\" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi\n    printf \"\\e[?25h\"\n    STORAGE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"Storage Pools\" --radiolist \\\n      \"Which storage pool you would like to use for ${HN}?\\nTo make a selection, use the Spacebar.\\n\" \\\n      16 $(($MSG_MAX_LENGTH + 23)) 6 \\\n      \"${STORAGE_MENU[@]}\" 3>&1 1>&2 2>&3) || exit\n  done\nfi\nmsg_ok \"Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location.\"\nmsg_ok \"Virtual Machine ID is ${CL}${BL}$VMID${CL}.\"\nmsg_info \"Retrieving the URL for Home Assistant ${BRANCH} Disk Image\"\nif [ \"$BRANCH\" == \"$dev\" ]; then\n  URL=https://os-artifacts.home-assistant.io/${BRANCH}/haos_ova-${BRANCH}.qcow2.xz\nelse\n  URL=https://github.com/home-assistant/operating-system/releases/download/${BRANCH}/haos_ova-${BRANCH}.qcow2.xz\nfi\nsleep 2\nmsg_ok \"${CL}${BL}${URL}${CL}\"\nwget -q --show-progress $URL\necho -en \"\\e[1A\\e[0K\"\nFILE=$(basename $URL)\nmsg_ok \"Downloaded ${CL}${BL}haos_ova-${BRANCH}.qcow2.xz${CL}\"\nmsg_info \"Extracting KVM Disk Image\"\nunxz $FILE\nSTORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}')\ncase $STORAGE_TYPE in\nnfs | dir)\n  DISK_EXT=\".raw\"\n  DISK_REF=\"$VMID/\"\n  DISK_IMPORT=\"-format raw\"\n  THIN=\"\"\n  ;;\nbtrfs | local-zfs)\n  DISK_EXT=\".raw\"\n  DISK_REF=\"$VMID/\"\n  DISK_IMPORT=\"-format raw\"\n  FORMAT=\",efitype=4m\"\n  THIN=\"\"\n  ;;\nesac\nfor i in {0,1}; do\n  disk=\"DISK$i\"\n  eval DISK${i}=vm-${VMID}-disk-${i}${DISK_EXT:-}\n  eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk}\ndone\nmsg_ok \"Extracted KVM Disk Image\"\nmsg_info \"Creating HAOS VM\"\nqm create $VMID -agent 1${MACHINE} -tablet 0 -localtime 1 -bios ovmf${CPU_TYPE} -cores $CORE_COUNT -memory $RAM_SIZE \\\n  -name $HN -tags proxmox-helper-scripts -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU -onboot 1 -ostype l26 -scsihw virtio-scsi-pci\npvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null\nqm importdisk $VMID ${FILE%.*} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null\nqm set $VMID \\\n  -efidisk0 ${DISK0_REF}${FORMAT} \\\n  -scsi0 ${DISK1_REF},${DISK_CACHE}${THIN}size=32G \\\n  -boot order=scsi0 \\\n  -description \"<div align='center'><a href='https://Helper-Scripts.com' target='_blank' rel='noopener noreferrer'><img src='https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/logo-81x112.png'/></a>\n\n  # Home Assistant OS\n\n  <a href='https://ko-fi.com/D1D7EP4GF'><img src='https://img.shields.io/badge/&#x2615;-Buy me a coffee-blue' /></a>\n  </div>\" >/dev/null\nmsg_ok \"Created HAOS VM ${CL}${BL}(${HN})\"\nif [ \"$START_VM\" == \"yes\" ]; then\n  msg_info \"Starting Home Assistant OS VM\"\n  qm start $VMID\n  msg_ok \"Started Home Assistant OS VM\"\nfi\nmsg_ok \"Completed Successfully!\\n\"\n"
  },
  {
    "path": "vm/mikrotik-routeros.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\n  cat <<\"EOF\"\n    __  ____ __              __  _ __      ____              __            ____  _____    ________  ______\n   /  |/  (_) /___________  / /_(_) /__   / __ \\____  __  __/ /____  _____/ __ \\/ ___/   / ____/ / / / __ \\\n  / /|_/ / / //_/ ___/ __ \\/ __/ / //_/  / /_/ / __ \\/ / / / __/ _ \\/ ___/ / / /\\__ \\   / /   / /_/ / /_/ /\n / /  / / / ,< / /  / /_/ / /_/ / ,<    / _, _/ /_/ / /_/ / /_/  __/ /  / /_/ /___/ /  / /___/ __  / _, _/\n/_/  /_/_/_/|_/_/   \\____/\\__/_/_/|_|  /_/ |_|\\____/\\__,_/\\__/\\___/_/   \\____//____/   \\____/_/ /_/_/ |_|\n\nEOF\n}\nclear\nheader_info\necho -e \"Loading...\"\nGEN_MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]')\nNEXTID=$(pvesh get /cluster/nextid)\nYW=$(echo \"\\033[33m\")\nBL=$(echo \"\\033[36m\")\nHA=$(echo \"\\033[1;34m\")\nRD=$(echo \"\\033[01;31m\")\nBGN=$(echo \"\\033[4;92m\")\nGN=$(echo \"\\033[1;92m\")\nDGN=$(echo \"\\033[32m\")\nCL=$(echo \"\\033[m\")\nBFR=\"\\\\r\\\\033[K\"\nHOLD=\"-\"\nCM=\"${GN}✓${CL}\"\nset -o errexit\nset -o errtrace\nset -o nounset\nset -o pipefail\nshopt -s expand_aliases\nalias die='EXIT=$? LINE=$LINENO error_exit'\ntrap die ERR\ntrap cleanup EXIT\nfunction error_exit() {\n  trap - ERR\n  local reason=\"Unknown failure occurred.\"\n  local msg=\"${1:-$reason}\"\n  local flag=\"${RD}‼ ERROR ${CL}$EXIT@$LINE\"\n  echo -e \"$flag $msg\" 1>&2\n  [ ! -z ${VMID-} ] && cleanup_vmid\n  exit $EXIT\n}\nfunction cleanup_vmid() {\n  if $(qm status $VMID &>/dev/null); then\n    if [ \"$(qm status $VMID | awk '{print $2}')\" == \"running\" ]; then\n      qm stop $VMID\n    fi\n    qm destroy $VMID\n  fi\n}\nfunction cleanup() {\n  popd >/dev/null\n  rm -rf $TEMP_DIR\n}\nTEMP_DIR=$(mktemp -d)\npushd $TEMP_DIR >/dev/null\nif ! pveversion | grep -Eq \"pve-manager/8.[1-3]\"; then\n  msg_error \"This version of Proxmox Virtual Environment is not supported\"\n  echo -e \"Requires Proxmox Virtual Environment Version 8.1 or later.\"\n  echo -e \"Exiting...\"\n  sleep 2\n  exit\nfi\nif (whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"Mikrotik RouterOS CHR VM\" --yesno \"This will create a New Mikrotik RouterOS CHR VM. Proceed?\" 10 58); then\n  echo \"User selected Yes\"\nelse\n  clear\n  echo -e \"⚠ User exited script \\n\"\n  exit\nfi\n\nfunction msg_info() {\n  local msg=\"$1\"\n  echo -ne \" ${HOLD} ${YW}${msg}...\"\n}\nfunction msg_ok() {\n  local msg=\"$1\"\n  echo -e \"${BFR} ${CM} ${GN}${msg}${CL}\"\n}\nfunction default_settings() {\n  echo -e \"${DGN}Using Virtual Machine ID: ${BGN}$NEXTID${CL}\"\n  VMID=$NEXTID\n  echo -e \"${DGN}Using Hostname: ${BGN}mikrotik-routeros-chr${CL}\"\n  HN=mikrotik-routeros-chr\n  echo -e \"${DGN}Allocated Cores: ${BGN}1${CL}\"\n  CORE_COUNT=\"2\"\n  echo -e \"${DGN}Allocated RAM: ${BGN}256${CL}\"\n  RAM_SIZE=\"512\"\n  echo -e \"${DGN}Using Bridge: ${BGN}vmbr0${CL}\"\n  BRG=\"vmbr0\"\n  echo -e \"${DGN}Using MAC Address: ${BGN}$GEN_MAC${CL}\"\n  MAC=$GEN_MAC\n  echo -e \"${DGN}Using VLAN: ${BGN}Default${CL}\"\n  VLAN=\"\"\n  echo -e \"${DGN}Using Interface MTU Size: ${BGN}Default${CL}\"\n  MTU=\"\"\n  echo -e \"${DGN}Start VM when completed: ${BGN}no${CL}\"\n  START_VM=\"no\"\n  echo -e \"${BL}Creating a Mikrotik RouterOS CHR VM using the above default settings${CL}\"\n}\nfunction advanced_settings() {\n  VMID=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set Virtual Machine ID\" 8 58 $NEXTID --title \"VIRTUAL MACHINE ID\" 3>&1 1>&2 2>&3)\n  exitstatus=$?\n  if [ $exitstatus = 0 ]; then\n    echo -e \"${DGN}Using Virtual Machine ID: ${BGN}$VMID${CL}\"\n  else\n    exit\n  fi\n  VM_NAME=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set Hostname\" 8 58 mikrotik-routeros-chr --title \"HOSTNAME\" 3>&1 1>&2 2>&3)\n  exitstatus=$?\n  if [ $exitstatus = 0 ]; then\n    HN=$(echo ${VM_NAME,,} | tr -d ' ')\n    echo -e \"${DGN}Using Hostname: ${BGN}$HN${CL}\"\n  else\n    exit\n  fi\n  CORE_COUNT=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Allocate CPU Cores\" 8 58 2 --title \"CORE COUNT\" 3>&1 1>&2 2>&3)\n  exitstatus=$?\n  if [ $exitstatus = 0 ]; then\n    echo -e \"${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}\"\n  else\n    exit\n  fi\n  RAM_SIZE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Allocate RAM in MiB\" 8 58 512 --title \"RAM\" 3>&1 1>&2 2>&3)\n  exitstatus=$?\n  if [ $exitstatus = 0 ]; then\n    echo -e \"${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}\"\n  else\n    exit\n  fi\n  BRG=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set a Bridge\" 8 58 vmbr0 --title \"BRIDGE\" 3>&1 1>&2 2>&3)\n  exitstatus=$?\n  if [ $exitstatus = 0 ]; then\n    echo -e \"${DGN}Using Bridge: ${BGN}$BRG${CL}\"\n  else\n    exit\n  fi\n  MAC1=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set a MAC Address\" 8 58 $GEN_MAC --title \"MAC ADDRESS\" 3>&1 1>&2 2>&3)\n  exitstatus=$?\n  if [ $exitstatus = 0 ]; then\n    MAC=\"$MAC1\"\n    echo -e \"${DGN}Using MAC Address: ${BGN}$MAC1${CL}\"\n  else\n    exit\n  fi\n  VLAN1=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set a Vlan(leave blank for default)\" 8 58 --title \"VLAN\" 3>&1 1>&2 2>&3)\n  exitstatus=$?\n  if [ $exitstatus = 0 ]; then\n    if [ -z $VLAN1 ]; then\n      VLAN1=\"Default\" VLAN=\"\"\n      echo -e \"${DGN}Using Vlan: ${BGN}$VLAN1${CL}\"\n    else\n      VLAN=\",tag=$VLAN1\"\n      echo -e \"${DGN}Using Vlan: ${BGN}$VLAN1${CL}\"\n    fi\n  fi\n  MTU1=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set Interface MTU Size (leave blank for default)\" 8 58 --title \"MTU SIZE\" --cancel-button Exit-Script 3>&1 1>&2 2>&3)\n  exitstatus=$?\n  if [ $exitstatus = 0 ]; then\n    if [ -z $MTU1 ]; then\n      MTU1=\"Default\" MTU=\"\"\n      echo -e \"${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}\"\n    else\n      MTU=\",mtu=$MTU1\"\n      echo -e \"${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}\"\n    fi\n  fi\n  if (whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"START VIRTUAL MACHINE\" --yesno \"Start Mikrotik RouterOS CHR VM when completed?\" 10 58); then\n    echo -e \"${DGN}Start Mikrotik RouterOS CHR VM when completed: ${BGN}yes${CL}\"\n    START_VM=\"yes\"\n  else\n    echo -e \"${DGN}Start Mikrotik RouterOS CHR VM when completed: ${BGN}no${CL}\"\n    START_VM=\"no\"\n  fi\n  if (whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"ADVANCED SETTINGS COMPLETE\" --yesno \"Ready to create Mikrotik RouterOS VM?\" 10 58); then\n    echo -e \"${RD}Creating Mikrotik RouterOS CHR VM using the above advanced settings${CL}\"\n  else\n    clear\n    header_info\n    echo -e \"${RD}Using Advanced Settings${CL}\"\n    advanced_settings\n  fi\n}\nfunction start_script() {\n  if (whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"SETTINGS\" --yesno \"Use Default Settings?\" --no-button Advanced 10 58); then\n    clear\n    header_info\n    echo -e \"${BL}Using Default Settings${CL}\"\n    default_settings\n  else\n    clear\n    header_info\n    echo -e \"${RD}Using Advanced Settings${CL}\"\n    advanced_settings\n  fi\n}\nstart_script\nmsg_info \"Validating Storage\"\nwhile read -r line; do\n  TAG=$(echo $line | awk '{print $1}')\n  TYPE=$(echo $line | awk '{printf \"%-10s\", $2}')\n  FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( \"%9sB\", $6)}')\n  ITEM=\"  Type: $TYPE Free: $FREE \"\n  OFFSET=2\n  if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then\n    MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET))\n  fi\n  STORAGE_MENU+=(\"$TAG\" \"$ITEM\" \"OFF\")\ndone < <(pvesm status -content images | awk 'NR>1')\nVALID=$(pvesm status -content images | awk 'NR>1')\nif [ -z \"$VALID\" ]; then\n  echo -e \"\\n${RD}⚠ Unable to detect a valid storage location.${CL}\"\n  echo -e \"Exiting...\"\n  exit\nelif [ $((${#STORAGE_MENU[@]} / 3)) -eq 1 ]; then\n  STORAGE=${STORAGE_MENU[0]}\nelse\n  while [ -z \"${STORAGE:+x}\" ]; do\n    STORAGE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"Storage Pools\" --radiolist \\\n      \"Which storage pool you would like to use for the Mikrotik RouterOS CHR VM?\\n\\n\" \\\n      16 $(($MSG_MAX_LENGTH + 23)) 6 \\\n      \"${STORAGE_MENU[@]}\" 3>&1 1>&2 2>&3) || exit\n  done\nfi\nmsg_ok \"Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location.\"\nmsg_ok \"Virtual Machine ID is ${CL}${BL}$VMID${CL}.\"\nmsg_info \"Getting URL for Mikrotik RouterOS CHR Disk Image\"\n\nURL=https://download.mikrotik.com/routeros/7.15.3/chr-7.15.3.img.zip\n\nsleep 2\nmsg_ok \"${CL}${BL}${URL}${CL}\"\nwget -q --show-progress $URL\necho -en \"\\e[1A\\e[0K\"\nFILE=$(basename $URL)\nmsg_ok \"Downloaded ${CL}${BL}$FILE${CL}\"\nmsg_info \"Extracting Mikrotik RouterOS CHR Disk Image\"\ngunzip -f -S .zip $FILE\nSTORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}')\ncase $STORAGE_TYPE in\nnfs | dir)\n  DISK_EXT=\".qcow2\"\n  DISK_REF=\"$VMID/\"\n  DISK_IMPORT=\"-format qcow2\"\n  ;;\nbtrfs | zfspool)\n  DISK_EXT=\"\"\n  DISK_REF=\"$VMID/\"\n  DISK_IMPORT=\"-format raw\"\n  ;;\nesac\n\nDISK_VAR=\"vm-${VMID}-disk-0${DISK_EXT:-}\"\nDISK_REF=\"${STORAGE}:${DISK_REF:-}${DISK_VAR:-}\"\n\nmsg_ok \"Extracted Mikrotik RouterOS CHR Disk Image\"\nmsg_info \"Creating Mikrotik RouterOS CHR VM\"\nqm create $VMID -tablet 0 -localtime 1 -cores $CORE_COUNT -memory $RAM_SIZE -name $HN \\\n  -tags proxmox-helper-scripts -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU \\\n  -onboot 1 -ostype l26 -scsihw virtio-scsi-pci\nqm importdisk $VMID ${FILE%.*} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null\nqm set $VMID \\\n  -scsi0 \"$DISK_REF\" \\\n  -boot order=scsi0 \\\n  -description \"<div align='center'><a href='https://Helper-Scripts.com'><img src='https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/logo-81x112.png'/></a>\n\n  # Mikrotik RouterOS CHR\n\n  <a href='https://ko-fi.com/D1D7EP4GF'><img src='https://img.shields.io/badge/&#x2615;-Buy me a coffee-blue' /></a>\n  </div>\" >/dev/null\nmsg_ok \"Mikrotik RouterOS CHR VM ${CL}${BL}(${HN})\"\nif [ \"$START_VM\" == \"yes\" ]; then\n  msg_info \"Starting Mikrotik RouterOS CHR VM\"\n  qm start $VMID\n  msg_ok \"Started Mikrotik RouterOS CHR VM\"\nfi\nmsg_ok \"Completed Successfully!\\n\"\n"
  },
  {
    "path": "vm/nextcloud-vm.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\n  clear\n  cat <<\"EOF\"\n ______              __ __           _  __            __             __  _   ____  ___\n/_  __/_ _________  / //_/__ __ __  / |/ /____ ______/ /__  __ _____/ / | | / /  |/  /\n / / / // / __/ _ \\/ ,< / -_) // / /    / -_) \\ / __/ / _ \\/ // / _  /  | |/ / /|_/ /\n/_/  \\_,_/_/ /_//_/_/|_|\\__/\\_, / /_/|_/\\__/_\\_\\\\__/_/\\___/\\_,_/\\_,_/   |___/_/  /_/\n                           /___/\nEOF\n}\nheader_info\necho -e \"\\n Loading...\"\nGEN_MAC=02:$(openssl rand -hex 5 | awk '{print toupper($0)}' | sed 's/\\(..\\)/\\1:/g; s/.$//')\nNEXTID=$(pvesh get /cluster/nextid)\nNAME=\"TurnKey Nexcloud VM\"\nYW=$(echo \"\\033[33m\")\nBL=$(echo \"\\033[36m\")\nHA=$(echo \"\\033[1;34m\")\nRD=$(echo \"\\033[01;31m\")\nBGN=$(echo \"\\033[4;92m\")\nGN=$(echo \"\\033[1;92m\")\nDGN=$(echo \"\\033[32m\")\nCL=$(echo \"\\033[m\")\nBFR=\"\\\\r\\\\033[K\"\nHOLD=\"-\"\nCM=\"${GN}✓${CL}\"\nCROSS=\"${RD}✗${CL}\"\nTHIN=\"discard=on,ssd=1,\"\nset -e\ntrap 'error_handler $LINENO \"$BASH_COMMAND\"' ERR\ntrap cleanup EXIT\nfunction error_handler() {\n  local exit_code=\"$?\"\n  local line_number=\"$1\"\n  local command=\"$2\"\n  local error_message=\"${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}\"\n  echo -e \"\\n$error_message\\n\"\n  cleanup_vmid\n}\n\nfunction cleanup_vmid() {\n  if qm status $VMID &>/dev/null; then\n    qm stop $VMID &>/dev/null\n    qm destroy $VMID &>/dev/null\n  fi\n}\n\nfunction cleanup() {\n  popd >/dev/null\n  rm -rf $TEMP_DIR\n}\n\nTEMP_DIR=$(mktemp -d)\npushd $TEMP_DIR >/dev/null\nif whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"$NAME\" --yesno \"This will create a New $NAME. Proceed?\" 10 58; then\n  :\nelse\n  header_info && echo -e \"⚠ User exited script \\n\" && exit\nfi\n\nfunction msg_info() {\n  local msg=\"$1\"\n  echo -ne \" ${HOLD} ${YW}${msg}...\"\n}\n\nfunction msg_ok() {\n  local msg=\"$1\"\n  echo -e \"${BFR} ${CM} ${GN}${msg}${CL}\"\n}\n\nfunction msg_error() {\n  local msg=\"$1\"\n  echo -e \"${BFR} ${CROSS} ${RD}${msg}${CL}\"\n}\n\nfunction check_root() {\n  if [[ \"$(id -u)\" -ne 0 || $(ps -o comm= -p $PPID) == \"sudo\" ]]; then\n    clear\n    msg_error \"Please run this script as root.\"\n    echo -e \"\\nExiting...\"\n    sleep 2\n    exit\n  fi\n}\n\nfunction pve_check() {\n  if ! pveversion | grep -Eq \"pve-manager/8.[1-3]\"; then\n    msg_error \"This version of Proxmox Virtual Environment is not supported\"\n    echo -e \"Requires Proxmox Virtual Environment Version 8.1 or later.\"\n    echo -e \"Exiting...\"\n    sleep 2\n    exit\nfi\n}\n\nfunction arch_check() {\n  if [ \"$(dpkg --print-architecture)\" != \"amd64\" ]; then\n    msg_error \"This script will not work with PiMox! \\n\"\n    echo -e \"Exiting...\"\n    sleep 2\n    exit\n  fi\n}\n\nfunction ssh_check() {\n  if command -v pveversion >/dev/null 2>&1; then\n    if [ -n \"${SSH_CLIENT:+x}\" ]; then\n      if whiptail --backtitle \"Proxmox VE Helper Scripts\" --defaultno --title \"SSH DETECTED\" --yesno \"It's suggested to use the Proxmox shell instead of SSH, since SSH can create issues while gathering variables. Would you like to proceed with using SSH?\" 10 62; then\n        echo \"you've been warned\"\n      else\n        clear\n        exit\n      fi\n    fi\n  fi\n}\n\nfunction exit-script() {\n  clear\n  echo -e \"⚠  User exited script \\n\"\n  exit\n}\n\nfunction default_settings() {\n  VMID=\"$NEXTID\"\n  FORMAT=\",efitype=4m\"\n  MACHINE=\"\"\n  DISK_CACHE=\"\"\n  HN=\"turnkey-nextcloud-vm\"\n  CPU_TYPE=\"\"\n  CORE_COUNT=\"2\"\n  RAM_SIZE=\"2048\"\n  BRG=\"vmbr0\"\n  MAC=\"$GEN_MAC\"\n  VLAN=\"\"\n  MTU=\"\"\n  START_VM=\"no\"\n  echo -e \"${DGN}Using Virtual Machine ID: ${BGN}${VMID}${CL}\"\n  echo -e \"${DGN}Using Machine Type: ${BGN}i440fx${CL}\"\n  echo -e \"${DGN}Using Disk Cache: ${BGN}None${CL}\"\n  echo -e \"${DGN}Using Hostname: ${BGN}${HN}${CL}\"\n  echo -e \"${DGN}Using CPU Model: ${BGN}KVM64${CL}\"\n  echo -e \"${DGN}Allocated Cores: ${BGN}${CORE_COUNT}${CL}\"\n  echo -e \"${DGN}Allocated RAM: ${BGN}${RAM_SIZE}${CL}\"\n  echo -e \"${DGN}Using Bridge: ${BGN}${BRG}${CL}\"\n  echo -e \"${DGN}Using MAC Address: ${BGN}${MAC}${CL}\"\n  echo -e \"${DGN}Using VLAN: ${BGN}Default${CL}\"\n  echo -e \"${DGN}Using Interface MTU Size: ${BGN}Default${CL}\"\n  echo -e \"${DGN}Start VM when completed: ${BGN}no${CL}\"\n  echo -e \"${BL}Creating a $NAME using the above default settings${CL}\"\n}\n\nfunction advanced_settings() {\n  while true; do\n    if VMID=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set Virtual Machine ID\" 8 58 $NEXTID --title \"VIRTUAL MACHINE ID\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n      if [ -z \"$VMID\" ]; then\n        VMID=\"$NEXTID\"\n      fi\n      if pct status \"$VMID\" &>/dev/null || qm status \"$VMID\" &>/dev/null; then\n        echo -e \"${CROSS}${RD} ID $VMID is already in use${CL}\"\n        sleep 2\n        continue\n      fi\n      echo -e \"${DGN}Virtual Machine ID: ${BGN}$VMID${CL}\"\n      break\n    else\n      exit-script\n    fi\n  done\n\n  if MACH=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"MACHINE TYPE\" --radiolist --cancel-button Exit-Script \"Choose Type\" 10 58 2 \\\n    \"i440fx\" \"Machine i440fx\" ON \\\n    \"q35\" \"Machine q35\" OFF \\\n    3>&1 1>&2 2>&3); then\n    if [ $MACH = q35 ]; then\n      echo -e \"${DGN}Using Machine Type: ${BGN}$MACH${CL}\"\n      FORMAT=\"\"\n      MACHINE=\" -machine q35\"\n    else\n      echo -e \"${DGN}Using Machine Type: ${BGN}$MACH${CL}\"\n      FORMAT=\",efitype=4m\"\n      MACHINE=\"\"\n    fi\n  else\n    exit-script\n  fi\n\n  if DISK_CACHE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"DISK CACHE\" --radiolist \"Choose\" --cancel-button Exit-Script 10 58 2 \\\n    \"0\" \"None (Default)\" ON \\\n    \"1\" \"Write Through\" OFF \\\n    3>&1 1>&2 2>&3); then\n    if [ $DISK_CACHE = \"1\" ]; then\n      echo -e \"${DGN}Using Disk Cache: ${BGN}Write Through${CL}\"\n      DISK_CACHE=\"cache=writethrough,\"\n    else\n      echo -e \"${DGN}Using Disk Cache: ${BGN}None${CL}\"\n      DISK_CACHE=\"\"\n    fi\n  else\n    exit-script\n  fi\n\n  if VM_NAME=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set Hostname\" 8 58 $HN --title \"HOSTNAME\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $VM_NAME ]; then\n      HN=\"$HN\"\n      echo -e \"${DGN}Using Hostname: ${BGN}$HN${CL}\"\n    else\n      HN=$(echo ${VM_NAME,,} | tr -d ' ')\n      echo -e \"${DGN}Using Hostname: ${BGN}$HN${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  if CPU_TYPE1=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"CPU MODEL\" --radiolist \"Choose\" --cancel-button Exit-Script 10 58 2 \\\n    \"0\" \"KVM64 (Default)\" ON \\\n    \"1\" \"Host\" OFF \\\n    3>&1 1>&2 2>&3); then\n    if [ $CPU_TYPE1 = \"1\" ]; then\n      echo -e \"${DGN}Using CPU Model: ${BGN}Host${CL}\"\n      CPU_TYPE=\" -cpu host\"\n    else\n      echo -e \"${DGN}Using CPU Model: ${BGN}KVM64${CL}\"\n      CPU_TYPE=\"\"\n    fi\n  else\n    exit-script\n  fi\n\n  if CORE_COUNT=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Allocate CPU Cores\" 8 58 2 --title \"CORE COUNT\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $CORE_COUNT ]; then\n      CORE_COUNT=\"2\"\n      echo -e \"${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}\"\n    else\n      echo -e \"${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  if RAM_SIZE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Allocate RAM in MiB\" 8 58 2048 --title \"RAM\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $RAM_SIZE ]; then\n      RAM_SIZE=\"2048\"\n      echo -e \"${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}\"\n    else\n      echo -e \"${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  if BRG=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set a Bridge\" 8 58 vmbr0 --title \"BRIDGE\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $BRG ]; then\n      BRG=\"vmbr0\"\n      echo -e \"${DGN}Using Bridge: ${BGN}$BRG${CL}\"\n    else\n      echo -e \"${DGN}Using Bridge: ${BGN}$BRG${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  if MAC1=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set a MAC Address\" 8 58 $GEN_MAC --title \"MAC ADDRESS\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $MAC1 ]; then\n      MAC=\"$GEN_MAC\"\n      echo -e \"${DGN}Using MAC Address: ${BGN}$MAC${CL}\"\n    else\n      MAC=\"$MAC1\"\n      echo -e \"${DGN}Using MAC Address: ${BGN}$MAC1${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  if VLAN1=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set a Vlan(leave blank for default)\" 8 58 --title \"VLAN\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $VLAN1 ]; then\n      VLAN1=\"Default\"\n      VLAN=\"\"\n      echo -e \"${DGN}Using Vlan: ${BGN}$VLAN1${CL}\"\n    else\n      VLAN=\",tag=$VLAN1\"\n      echo -e \"${DGN}Using Vlan: ${BGN}$VLAN1${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  if MTU1=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set Interface MTU Size (leave blank for default)\" 8 58 --title \"MTU SIZE\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $MTU1 ]; then\n      MTU1=\"Default\"\n      MTU=\"\"\n      echo -e \"${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}\"\n    else\n      MTU=\",mtu=$MTU1\"\n      echo -e \"${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  if (whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"START VIRTUAL MACHINE\" --yesno \"Start VM when completed?\" 10 58); then\n    echo -e \"${DGN}Start VM when completed: ${BGN}yes${CL}\"\n    START_VM=\"yes\"\n  else\n    echo -e \"${DGN}Start VM when completed: ${BGN}no${CL}\"\n    START_VM=\"no\"\n  fi\n\n  if (whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"ADVANCED SETTINGS COMPLETE\" --yesno \"Ready to create a $NAME?\" --no-button Do-Over 10 58); then\n    echo -e \"${RD}Creating a $NAME using the above advanced settings${CL}\"\n  else\n    header_info\n    echo -e \"${RD}Using Advanced Settings${CL}\"\n    advanced_settings\n  fi\n}\n\nfunction start_script() {\n  if (whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"SETTINGS\" --yesno \"Use Default Settings?\" --no-button Advanced 10 58); then\n    header_info\n    echo -e \"${BL}Using Default Settings${CL}\"\n    default_settings\n  else\n    header_info\n    echo -e \"${RD}Using Advanced Settings${CL}\"\n    advanced_settings\n  fi\n}\n\ncheck_root\narch_check\npve_check\nssh_check\nstart_script\n\nmsg_info \"Validating Storage\"\nwhile read -r line; do\n  TAG=$(echo $line | awk '{print $1}')\n  TYPE=$(echo $line | awk '{printf \"%-10s\", $2}')\n  FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( \"%9sB\", $6)}')\n  ITEM=\"  Type: $TYPE Free: $FREE \"\n  OFFSET=2\n  if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then\n    MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET))\n  fi\n  STORAGE_MENU+=(\"$TAG\" \"$ITEM\" \"OFF\")\ndone < <(pvesm status -content images | awk 'NR>1')\nVALID=$(pvesm status -content images | awk 'NR>1')\nif [ -z \"$VALID\" ]; then\n  msg_error \"Unable to detect a valid storage location.\"\n  exit\nelif [ $((${#STORAGE_MENU[@]} / 3)) -eq 1 ]; then\n  STORAGE=${STORAGE_MENU[0]}\nelse\n  while [ -z \"${STORAGE:+x}\" ]; do\n    STORAGE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"Storage Pools\" --radiolist \\\n      \"Which storage pool you would like to use for ${HN}?\\nTo make a selection, use the Spacebar.\\n\" \\\n      16 $(($MSG_MAX_LENGTH + 23)) 6 \\\n      \"${STORAGE_MENU[@]}\" 3>&1 1>&2 2>&3) || exit\n  done\nfi\nmsg_ok \"Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location.\"\nmsg_ok \"Virtual Machine ID is ${CL}${BL}$VMID${CL}.\"\nmsg_info \"Retrieving the URL for the $NAME Disk Image\"\nURL=http://mirror.turnkeylinux.org/turnkeylinux/images/iso/turnkey-nextcloud-18.0-bookworm-amd64.iso\nsleep 2\nmsg_ok \"${CL}${BL}${URL}${CL}\"\nwget -q --show-progress $URL\necho -en \"\\e[1A\\e[0K\"\nFILE=$(basename $URL)\nmsg_ok \"Downloaded ${CL}${BL}${FILE}${CL}\"\n\nSTORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}')\ncase $STORAGE_TYPE in\nnfs | dir)\n  DISK_EXT=\".raw\"\n  DISK_REF=\"$VMID/\"\n  DISK_IMPORT=\"-format raw\"\n  THIN=\"\"\n  ;;\nbtrfs)\n  DISK_EXT=\".raw\"\n  DISK_REF=\"$VMID/\"\n  DISK_IMPORT=\"-format raw\"\n  FORMAT=\",efitype=4m\"\n  THIN=\"\"\n  ;;\nesac\nfor i in {0,1}; do\n  disk=\"DISK$i\"\n  eval DISK${i}=vm-${VMID}-disk-${i}${DISK_EXT:-}\n  eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk}\ndone\n\nmsg_info \"Creating a $NAME\"\nqm create $VMID -agent 1${MACHINE} -tablet 0 -localtime 1 -bios seabios${CPU_TYPE} -cores $CORE_COUNT -memory $RAM_SIZE \\\n  -name $HN -tags proxmox-helper-scripts -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU -onboot 1 -ostype l26 -scsihw virtio-scsi-pci\npvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null\nqm importdisk $VMID ${FILE} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null\nqm set $VMID \\\n  -efidisk0 ${DISK0_REF}${FORMAT} \\\n  -scsi0 ${DISK1_REF},${DISK_CACHE}${THIN}size=12G \\\n  -boot order=scsi0 \\\n  -description \"<div align='center'><a href='https://Helper-Scripts.com'><img src='https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/logo-81x112.png'/></a>\n\n  # $NAME\n\n  <a href='https://ko-fi.com/D1D7EP4GF'><img src='https://img.shields.io/badge/&#x2615;-Buy me a coffee-blue' /></a>\n  </div>\" >/dev/null\nmsg_ok \"Created a $NAME ${CL}${BL}(${HN})\"\nif [ \"$START_VM\" == \"yes\" ]; then\n  msg_info \"Starting $NAME\"\n  qm start $VMID\n  msg_ok \"Started $NAME\"\nfi\nmsg_ok \"Completed Successfully!\\n\"\n"
  },
  {
    "path": "vm/openwrt.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n#         Jon Spriggs (jontheniceguy)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n# Based on work from https://i12bretro.github.io/tutorials/0405.html\n\nfunction header_info {\n  clear\n  cat <<\"EOF\"\n   ____                 _       __     __\n  / __ \\____  ___  ____| |     / /____/ /_\n / / / / __ \\/ _ \\/ __ \\ | /| / / ___/ __/\n/ /_/ / /_/ /  __/ / / / |/ |/ / /  / /_\n\\____/ .___/\\___/_/ /_/|__/|__/_/   \\__/\n    /_/ W I R E L E S S   F R E E D O M\n\nEOF\n}\nheader_info\necho -e \"Loading...\"\nGEN_MAC=02:$(openssl rand -hex 5 | awk '{print toupper($0)}' | sed 's/\\(..\\)/\\1:/g; s/.$//')\nGEN_MAC_LAN=02:$(openssl rand -hex 5 | awk '{print toupper($0)}' | sed 's/\\(..\\)/\\1:/g; s/.$//')\nNEXTID=$(pvesh get /cluster/nextid)\nYW=$(echo \"\\033[33m\")\nBL=$(echo \"\\033[36m\")\nHA=$(echo \"\\033[1;34m\")\nRD=$(echo \"\\033[01;31m\")\nBGN=$(echo \"\\033[4;92m\")\nGN=$(echo \"\\033[1;92m\")\nDGN=$(echo \"\\033[32m\")\nCL=$(echo \"\\033[m\")\nBFR=\"\\\\r\\\\033[K\"\nHOLD=\"-\"\nCM=\"${GN}✓${CL}\"\nCROSS=\"${RD}✗${CL}\"\nset -Eeo pipefail\ntrap 'error_handler $LINENO \"$BASH_COMMAND\"' ERR\ntrap cleanup EXIT\nfunction error_handler() {\n  local exit_code=\"$?\"\n  local line_number=\"$1\"\n  local command=\"$2\"\n  local error_message=\"${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}\"\n  echo -e \"\\n$error_message\\n\"\n  cleanup_vmid\n}\n\nfunction cleanup_vmid() {\n  if qm status $VMID &>/dev/null; then\n    qm stop $VMID &>/dev/null\n    qm destroy $VMID &>/dev/null\n  fi\n}\n\nfunction cleanup() {\n  popd >/dev/null\n  rm -rf $TEMP_DIR\n}\n\nTEMP_DIR=$(mktemp -d)\npushd $TEMP_DIR >/dev/null\nfunction send_line_to_vm() {\n  echo -e \"${DGN}Sending line: ${YW}$1${CL}\"\n  for ((i = 0; i < ${#1}; i++)); do\n    character=${1:i:1}\n    case $character in\n    \" \") character=\"spc\" ;;\n    \"-\") character=\"minus\" ;;\n    \"=\") character=\"equal\" ;;\n    \",\") character=\"comma\" ;;\n    \".\") character=\"dot\" ;;\n    \"/\") character=\"slash\" ;;\n    \"'\") character=\"apostrophe\" ;;\n    \";\") character=\"semicolon\" ;;\n    '\\') character=\"backslash\" ;;\n    '`') character=\"grave_accent\" ;;\n    \"[\") character=\"bracket_left\" ;;\n    \"]\") character=\"bracket_right\" ;;\n    \"_\") character=\"shift-minus\" ;;\n    \"+\") character=\"shift-equal\" ;;\n    \"?\") character=\"shift-slash\" ;;\n    \"<\") character=\"shift-comma\" ;;\n    \">\") character=\"shift-dot\" ;;\n    '\"') character=\"shift-apostrophe\" ;;\n    \":\") character=\"shift-semicolon\" ;;\n    \"|\") character=\"shift-backslash\" ;;\n    \"~\") character=\"shift-grave_accent\" ;;\n    \"{\") character=\"shift-bracket_left\" ;;\n    \"}\") character=\"shift-bracket_right\" ;;\n    \"A\") character=\"shift-a\" ;;\n    \"B\") character=\"shift-b\" ;;\n    \"C\") character=\"shift-c\" ;;\n    \"D\") character=\"shift-d\" ;;\n    \"E\") character=\"shift-e\" ;;\n    \"F\") character=\"shift-f\" ;;\n    \"G\") character=\"shift-g\" ;;\n    \"H\") character=\"shift-h\" ;;\n    \"I\") character=\"shift-i\" ;;\n    \"J\") character=\"shift-j\" ;;\n    \"K\") character=\"shift-k\" ;;\n    \"L\") character=\"shift-l\" ;;\n    \"M\") character=\"shift-m\" ;;\n    \"N\") character=\"shift-n\" ;;\n    \"O\") character=\"shift-o\" ;;\n    \"P\") character=\"shift-p\" ;;\n    \"Q\") character=\"shift-q\" ;;\n    \"R\") character=\"shift-r\" ;;\n    \"S\") character=\"shift-s\" ;;\n    \"T\") character=\"shift-t\" ;;\n    \"U\") character=\"shift-u\" ;;\n    \"V\") character=\"shift-v\" ;;\n    \"W\") character=\"shift-w\" ;;\n    \"X\") character=\"shift=x\" ;;\n    \"Y\") character=\"shift-y\" ;;\n    \"Z\") character=\"shift-z\" ;;\n    \"!\") character=\"shift-1\" ;;\n    \"@\") character=\"shift-2\" ;;\n    \"#\") character=\"shift-3\" ;;\n    '$') character=\"shift-4\" ;;\n    \"%\") character=\"shift-5\" ;;\n    \"^\") character=\"shift-6\" ;;\n    \"&\") character=\"shift-7\" ;;\n    \"*\") character=\"shift-8\" ;;\n    \"(\") character=\"shift-9\" ;;\n    \")\") character=\"shift-0\" ;;\n    esac\n    qm sendkey $VMID \"$character\"\n  done\n  qm sendkey $VMID ret\n}\n\nTEMP_DIR=$(mktemp -d)\npushd $TEMP_DIR >/dev/null\n\nif (whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"OpenWrt VM\" --yesno \"This will create a New OpenWrt VM. Proceed?\" 10 58); then\n  :\nelse\n  header_info && echo -e \"⚠ User exited script \\n\" && exit\nfi\n\nfunction msg_info() {\n  local msg=\"$1\"\n  echo -ne \" ${HOLD} ${YW}${msg}...\"\n}\n\nfunction msg_ok() {\n  local msg=\"$1\"\n  echo -e \"${BFR} ${CM} ${GN}${msg}${CL}\"\n}\n\nfunction msg_error() {\n  local msg=\"$1\"\n  echo -e \"${BFR} ${CROSS} ${RD}${msg}${CL}\"\n}\n\nfunction pve_check() {\n  if ! pveversion | grep -Eq \"pve-manager/8.[1-3]\"; then\n    msg_error \"This version of Proxmox Virtual Environment is not supported\"\n    echo -e \"Requires Proxmox Virtual Environment Version 8.1 or later.\"\n    echo -e \"Exiting...\"\n    sleep 2\n    exit\nfi\n}\n\nfunction arch_check() {\n  if [ \"$(dpkg --print-architecture)\" != \"amd64\" ]; then\n    echo -e \"\\n ${CROSS} This script will not work with PiMox! \\n\"\n    echo -e \"Exiting...\"\n    sleep 2\n    exit\n  fi\n}\n\nfunction ssh_check() {\n  if command -v pveversion >/dev/null 2>&1; then\n    if [ -n \"${SSH_CLIENT:+x}\" ]; then\n      if whiptail --backtitle \"Proxmox VE Helper Scripts\" --defaultno --title \"SSH DETECTED\" --yesno \"It's suggested to use the Proxmox shell instead of SSH, since SSH can create issues while gathering variables. Would you like to proceed with using SSH?\" 10 62; then\n        echo \"you've been warned\"\n      else\n        clear\n        exit\n      fi\n    fi\n  fi\n}\n\nfunction exit-script() {\n  clear\n  echo -e \"⚠  User exited script \\n\"\n  exit\n}\n\nfunction default_settings() {\n  VMID=$NEXTID\n  HN=openwrt\n  CORE_COUNT=\"1\"\n  RAM_SIZE=\"256\"\n  BRG=\"vmbr0\"\n  VLAN=\"\"\n  MAC=$GEN_MAC\n  LAN_MAC=$GEN_MAC_LAN\n  LAN_BRG=\"vmbr0\"\n  LAN_IP_ADDR=\"192.168.1.1\"\n  LAN_NETMASK=\"255.255.255.0\"\n  LAN_VLAN=\",tag=999\"\n  MTU=\"\"\n  START_VM=\"yes\"\n  echo -e \"${DGN}Using Virtual Machine ID: ${BGN}${VMID}${CL}\"\n  echo -e \"${DGN}Using Hostname: ${BGN}${HN}${CL}\"\n  echo -e \"${DGN}Allocated Cores: ${BGN}${CORE_COUNT}${CL}\"\n  echo -e \"${DGN}Allocated RAM: ${BGN}${RAM_SIZE}${CL}\"\n  echo -e \"${DGN}Using WAN Bridge: ${BGN}${BRG}${CL}\"\n  echo -e \"${DGN}Using WAN VLAN: ${BGN}Default${CL}\"\n  echo -e \"${DGN}Using WAN MAC Address: ${BGN}${MAC}${CL}\"\n  echo -e \"${DGN}Using LAN MAC Address: ${BGN}${LAN_MAC}${CL}\"\n  echo -e \"${DGN}Using LAN Bridge: ${BGN}${LAN_BRG}${CL}\"\n  echo -e \"${DGN}Using LAN VLAN: ${BGN}999${CL}\"\n  echo -e \"${DGN}Using LAN IP Address: ${BGN}${LAN_IP_ADDR}${CL}\"\n  echo -e \"${DGN}Using LAN NETMASK: ${BGN}${LAN_NETMASK}${CL}\"\n  echo -e \"${DGN}Using Interface MTU Size: ${BGN}Default${CL}\"\n  echo -e \"${DGN}Start VM when completed: ${BGN}yes${CL}\"\n  echo -e \"${BL}Creating a OpenWRT VM using the above default settings${CL}\"\n}\n\nfunction advanced_settings() {\n  while true; do\n    if VMID=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set Virtual Machine ID\" 8 58 $NEXTID --title \"VIRTUAL MACHINE ID\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n      if [ -z \"$VMID\" ]; then\n        VMID=\"$NEXTID\"\n      fi\n      if pct status \"$VMID\" &>/dev/null || qm status \"$VMID\" &>/dev/null; then\n        echo -e \"${CROSS}${RD} ID $VMID is already in use${CL}\"\n        sleep 2\n        continue\n      fi\n      echo -e \"${DGN}Virtual Machine ID: ${BGN}$VMID${CL}\"\n      break\n    else\n      exit-script\n    fi\n  done\n\n  if VM_NAME=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set Hostname\" 8 58 openwrt --title \"HOSTNAME\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $VM_NAME ]; then\n      HN=\"openwrt\"\n    else\n      HN=$(echo ${VM_NAME,,} | tr -d ' ')\n    fi\n    echo -e \"${DGN}Using Hostname: ${BGN}$HN${CL}\"\n  else\n    exit-script\n  fi\n\n  if CORE_COUNT=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Allocate CPU Cores\" 8 58 1 --title \"CORE COUNT\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $CORE_COUNT ]; then\n      CORE_COUNT=\"1\"\n    fi\n    echo -e \"${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}\"\n  else\n    exit-script\n  fi\n\n  if RAM_SIZE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Allocate RAM in MiB\" 8 58 256 --title \"RAM\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $RAM_SIZE ]; then\n      RAM_SIZE=\"256\"\n    fi\n    echo -e \"${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}\"\n  else\n    exit-script\n  fi\n\n  if BRG=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set a WAN Bridge\" 8 58 vmbr0 --title \"WAN BRIDGE\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $BRG ]; then\n      BRG=\"vmbr0\"\n    fi\n    echo -e \"${DGN}Using WAN Bridge: ${BGN}$BRG${CL}\"\n  else\n    exit-script\n  fi\n\n  if LAN_BRG=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set a LAN Bridge\" 8 58 vmbr0 --title \"LAN BRIDGE\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $LAN_BRG ]; then\n      LAN_BRG=\"vmbr0\"\n    fi\n    echo -e \"${DGN}Using LAN Bridge: ${BGN}$LAN_BRG${CL}\"\n  else\n    exit-script\n  fi\n\n  if LAN_IP_ADDR=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set a router IP\" 8 58 $LAN_IP_ADDR --title \"LAN IP ADDRESS\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $LAN_IP_ADDR ]; then\n      LAN_IP_ADDR=\"192.168.1.1\"\n    fi\n    echo -e \"${DGN}Using LAN IP ADDRESS: ${BGN}$LAN_IP_ADDR${CL}\"\n  else\n    exit-script\n  fi\n\n  if LAN_NETMASK=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set a router netmmask\" 8 58 $LAN_NETMASK --title \"LAN NETMASK\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $LAN_NETMASK ]; then\n      LAN_NETMASK=\"255.255.255.0\"\n    fi\n    echo -e \"${DGN}Using LAN NETMASK: ${BGN}$LAN_NETMASK${CL}\"\n  else\n    exit-script\n  fi\n\n  if MAC1=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set a WAN MAC Address\" 8 58 $GEN_MAC --title \"WAN MAC ADDRESS\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $MAC1 ]; then\n      MAC=\"$GEN_MAC\"\n    else\n      MAC=\"$MAC1\"\n    fi\n    echo -e \"${DGN}Using WAN MAC Address: ${BGN}$MAC${CL}\"\n  else\n    exit-script\n  fi\n\n  if MAC2=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set a LAN MAC Address\" 8 58 $GEN_MAC_LAN --title \"LAN MAC ADDRESS\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $MAC2 ]; then\n      LAN_MAC=\"$GEN_MAC_LAN\"\n    else\n      LAN_MAC=\"$MAC2\"\n    fi\n    echo -e \"${DGN}Using LAN MAC Address: ${BGN}$LAN_MAC${CL}\"\n  else\n    exit-script\n  fi\n\n  if VLAN1=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set a WAN Vlan (leave blank for default)\" 8 58 --title \"WAN VLAN\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $VLAN1 ]; then\n      VLAN1=\"Default\"\n      VLAN=\"\"\n    else\n      VLAN=\",tag=$VLAN1\"\n    fi\n    echo -e \"${DGN}Using WAN Vlan: ${BGN}$VLAN1${CL}\"\n  else\n    exit-script\n  fi\n\n  if VLAN2=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set a LAN Vlan\" 8 58 999 --title \"LAN VLAN\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $VLAN2 ]; then\n      VLAN2=\"999\"\n      LAN_VLAN=\",tag=$VLAN2\"\n    else\n      LAN_VLAN=\",tag=$VLAN2\"\n    fi\n    echo -e \"${DGN}Using LAN Vlan: ${BGN}$VLAN2${CL}\"\n  else\n    exit-script\n  fi\n\n  if MTU1=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set Interface MTU Size (leave blank for default)\" 8 58 --title \"MTU SIZE\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $MTU1 ]; then\n      MTU1=\"Default\"\n      MTU=\"\"\n    else\n      MTU=\",mtu=$MTU1\"\n    fi\n    echo -e \"${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}\"\n  else\n    exit-script\n  fi\n\n  if (whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"START VIRTUAL MACHINE\" --yesno \"Start VM when completed?\" 10 58); then\n    START_VM=\"yes\"\n  else\n    START_VM=\"no\"\n  fi\n  echo -e \"${DGN}Start VM when completed: ${BGN}$START_VM${CL}\"\n\n  if (whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"ADVANCED SETTINGS COMPLETE\" --yesno \"Ready to create OpenWrt VM?\" --no-button Do-Over 10 58); then\n    echo -e \"${RD}Creating a OpenWrt VM using the above advanced settings${CL}\"\n  else\n    header_info\n    echo -e \"${RD}Using Advanced Settings${CL}\"\n    advanced_settings\n  fi\n}\n\nfunction start_script() {\n  if (whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"SETTINGS\" --yesno \"Use Default Settings?\" --no-button Advanced 10 58); then\n    header_info\n    echo -e \"${BL}Using Default Settings${CL}\"\n    default_settings\n  else\n    header_info\n    echo -e \"${RD}Using Advanced Settings${CL}\"\n    advanced_settings\n  fi\n}\n\narch_check\npve_check\nssh_check\nstart_script\n\nmsg_info \"Validating Storage\"\nwhile read -r line; do\n  TAG=$(echo $line | awk '{print $1}')\n  TYPE=$(echo $line | awk '{printf \"%-10s\", $2}')\n  FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( \"%9sB\", $6)}')\n  ITEM=\"  Type: $TYPE Free: $FREE \"\n  OFFSET=2\n  if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then\n    MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET))\n  fi\n  STORAGE_MENU+=(\"$TAG\" \"$ITEM\" \"OFF\")\ndone < <(pvesm status -content images | awk 'NR>1')\nVALID=$(pvesm status -content images | awk 'NR>1')\nif [ -z \"$VALID\" ]; then\n  echo -e \"\\n${RD}⚠ Unable to detect a valid storage location.${CL}\"\n  echo -e \"Exiting...\"\n  exit\nelif [ $((${#STORAGE_MENU[@]} / 3)) -eq 1 ]; then\n  STORAGE=${STORAGE_MENU[0]}\nelse\n  while [ -z \"${STORAGE:+x}\" ]; do\n    STORAGE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"Storage Pools\" --radiolist \\\n      \"Which storage pool you would like to use for the OpenWrt VM?\\n\\n\" \\\n      16 $(($MSG_MAX_LENGTH + 23)) 6 \\\n      \"${STORAGE_MENU[@]}\" 3>&1 1>&2 2>&3) || exit\n  done\nfi\nmsg_ok \"Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location.\"\nmsg_ok \"Virtual Machine ID is ${CL}${BL}$VMID${CL}.\"\nmsg_info \"Getting URL for OpenWrt Disk Image\"\n\nresponse=$(curl -s https://openwrt.org)\nstableversion=$(echo \"$response\" | sed -n 's/.*Current stable release - OpenWrt \\([0-9.]\\+\\).*/\\1/p')\nURL=\"https://downloads.openwrt.org/releases/$stableversion/targets/x86/64/openwrt-$stableversion-x86-64-generic-ext4-combined.img.gz\"\n\nsleep 2\nmsg_ok \"${CL}${BL}${URL}${CL}\"\nwget -q --show-progress $URL\necho -en \"\\e[1A\\e[0K\"\nFILE=$(basename $URL)\nmsg_ok \"Downloaded ${CL}${BL}$FILE${CL}\"\ngunzip -f $FILE >/dev/null 2>/dev/null || true\nNEWFILE=\"${FILE%.*}\"\nFILE=\"$NEWFILE\"\nmv $FILE ${FILE%.*}\nqemu-img resize -f raw ${FILE%.*} 512M >/dev/null 2>/dev/null\nmsg_ok \"Extracted & Resized OpenWrt Disk Image ${CL}${BL}$FILE${CL}\"\nSTORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}')\ncase $STORAGE_TYPE in\nnfs | dir)\n  DISK_EXT=\".qcow2\"\n  DISK_REF=\"$VMID/\"\n  DISK_IMPORT=\"-format qcow2\"\n  ;;\nbtrfs)\n  DISK_EXT=\".raw\"\n  DISK_REF=\"$VMID/\"\n  DISK_IMPORT=\"-format raw\"\n  ;;\nesac\nfor i in {0,1}; do\n  disk=\"DISK$i\"\n  eval DISK${i}=vm-${VMID}-disk-${i}${DISK_EXT:-}\n  eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk}\ndone\n\nmsg_info \"Creating OpenWrt VM\"\nqm create $VMID -cores $CORE_COUNT -memory $RAM_SIZE -name $HN \\\n  -onboot 1 -ostype l26 -scsihw virtio-scsi-pci --tablet 0\npvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null\nqm importdisk $VMID ${FILE%.*} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null\nqm set $VMID \\\n  -efidisk0 ${DISK0_REF},efitype=4m,size=4M \\\n  -scsi0 ${DISK1_REF},size=512M \\\n  -boot order=scsi0 \\\n  -tags proxmox-helper-scripts \\\n  -description \"<div align='center'><a href='https://Helper-Scripts.com'><img src='https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/logo-81x112.png'/></a>\n\n  # OpenWRT\n\n  <a href='https://ko-fi.com/D1D7EP4GF'><img src='https://img.shields.io/badge/&#x2615;-Buy me a coffee-blue' /></a>\n  </div>\" >/dev/null\nmsg_ok \"Created OpenWrt VM ${CL}${BL}(${HN})\"\nmsg_info \"OpenWrt is being started in order to configure the network interfaces.\"\nqm start $VMID\nsleep 15\nmsg_ok \"Network interfaces are being configured as OpenWrt initiates.\"\nsend_line_to_vm \"\"\nsend_line_to_vm \"uci delete network.@device[0]\"\nsend_line_to_vm \"uci set network.wan=interface\"\nsend_line_to_vm \"uci set network.wan.device=eth1\"\nsend_line_to_vm \"uci set network.wan.proto=dhcp\"\nsend_line_to_vm \"uci delete network.lan\"\nsend_line_to_vm \"uci set network.lan=interface\"\nsend_line_to_vm \"uci set network.lan.device=eth0\"\nsend_line_to_vm \"uci set network.lan.proto=static\"\nsend_line_to_vm \"uci set network.lan.ipaddr=${LAN_IP_ADDR}\"\nsend_line_to_vm \"uci set network.lan.netmask=${LAN_NETMASK}\"\nsend_line_to_vm \"uci set firewall.@zone[1].input='ACCEPT'\"\nsend_line_to_vm \"uci set firewall.@zone[1].forward='ACCEPT'\"\nsend_line_to_vm \"uci commit\"\nsend_line_to_vm \"halt\"\nmsg_ok \"Network interfaces have been successfully configured.\"\nuntil qm status $VMID | grep -q \"stopped\"; do\n  sleep 2\ndone\nmsg_info \"Bridge interfaces are being added.\"\nqm set $VMID \\\n  -net0 virtio,bridge=${LAN_BRG},macaddr=${LAN_MAC}${LAN_VLAN}${MTU} \\\n  -net1 virtio,bridge=${BRG},macaddr=${MAC}${VLAN}${MTU} >/dev/null 2>/dev/null\nmsg_ok \"Bridge interfaces have been successfully added.\"\nif [ \"$START_VM\" == \"yes\" ]; then\n  msg_info \"Starting OpenWrt VM\"\n  qm start $VMID\n  msg_ok \"Started OpenWrt VM\"\nfi\nVLAN_FINISH=\"\"\nif [ \"$VLAN\" == \"\" ] && [ \"$VLAN2\" != \"999\" ]; then\n  VLAN_FINISH=\" Please remember to adjust the VLAN tags to suit your network.\"\nfi\nmsg_ok \"Completed Successfully!\\n${VLAN_FINISH}\"\n"
  },
  {
    "path": "vm/owncloud-vm.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\n  clear\n  cat <<\"EOF\"\n ______              __ __                           _______             __  _   ____  ___\n/_  __/_ _________  / //_/__ __ __  ___ _    _____  / ___/ /__  __ _____/ / | | / /  |/  /\n / / / // / __/ _ \\/ ,< / -_) // / / _ \\ |/|/ / _ \\/ /__/ / _ \\/ // / _  /  | |/ / /|_/ /\n/_/  \\_,_/_/ /_//_/_/|_|\\__/\\_, /  \\___/__,__/_//_/\\___/_/\\___/\\_,_/\\_,_/   |___/_/  /_/\n                           /___/\nEOF\n}\nheader_info\necho -e \"\\n Loading...\"\nGEN_MAC=02:$(openssl rand -hex 5 | awk '{print toupper($0)}' | sed 's/\\(..\\)/\\1:/g; s/.$//')\nNEXTID=$(pvesh get /cluster/nextid)\n\nYW=$(echo \"\\033[33m\")\nBL=$(echo \"\\033[36m\")\nHA=$(echo \"\\033[1;34m\")\nRD=$(echo \"\\033[01;31m\")\nBGN=$(echo \"\\033[4;92m\")\nGN=$(echo \"\\033[1;92m\")\nDGN=$(echo \"\\033[32m\")\nCL=$(echo \"\\033[m\")\nBFR=\"\\\\r\\\\033[K\"\nHOLD=\"-\"\nCM=\"${GN}✓${CL}\"\nCROSS=\"${RD}✗${CL}\"\nTHIN=\"discard=on,ssd=1,\"\nset -e\ntrap 'error_handler $LINENO \"$BASH_COMMAND\"' ERR\ntrap cleanup EXIT\nfunction error_handler() {\n  local exit_code=\"$?\"\n  local line_number=\"$1\"\n  local command=\"$2\"\n  local error_message=\"${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}\"\n  echo -e \"\\n$error_message\\n\"\n  cleanup_vmid\n}\n\nfunction cleanup_vmid() {\n  if qm status $VMID &>/dev/null; then\n    qm stop $VMID &>/dev/null\n    qm destroy $VMID &>/dev/null\n  fi\n}\n\nfunction cleanup() {\n  popd >/dev/null\n  rm -rf $TEMP_DIR\n}\n\nTEMP_DIR=$(mktemp -d)\npushd $TEMP_DIR >/dev/null\nif whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"TurnKey-ownCloud VM\" --yesno \"This will create a New TurnKey-ownCloud VM. Proceed?\" 10 58; then\n  :\nelse\n  header_info && echo -e \"⚠ User exited script \\n\" && exit\nfi\n\nfunction msg_info() {\n  local msg=\"$1\"\n  echo -ne \" ${HOLD} ${YW}${msg}...\"\n}\n\nfunction msg_ok() {\n  local msg=\"$1\"\n  echo -e \"${BFR} ${CM} ${GN}${msg}${CL}\"\n}\n\nfunction msg_error() {\n  local msg=\"$1\"\n  echo -e \"${BFR} ${CROSS} ${RD}${msg}${CL}\"\n}\n\nfunction check_root() {\n  if [[ \"$(id -u)\" -ne 0 || $(ps -o comm= -p $PPID) == \"sudo\" ]]; then\n    clear\n    msg_error \"Please run this script as root.\"\n    echo -e \"\\nExiting...\"\n    sleep 2\n    exit\n  fi\n}\n\nfunction pve_check() {\n  if ! pveversion | grep -Eq \"pve-manager/8.[1-3]\"; then\n    msg_error \"This version of Proxmox Virtual Environment is not supported\"\n    echo -e \"Requires Proxmox Virtual Environment Version 8.1 or later.\"\n    echo -e \"Exiting...\"\n    sleep 2\n    exit\nfi\n}\n\nfunction arch_check() {\n  if [ \"$(dpkg --print-architecture)\" != \"amd64\" ]; then\n    msg_error \"This script will not work with PiMox! \\n\"\n    echo -e \"Exiting...\"\n    sleep 2\n    exit\n  fi\n}\n\nfunction ssh_check() {\n  if command -v pveversion >/dev/null 2>&1; then\n    if [ -n \"${SSH_CLIENT:+x}\" ]; then\n      if whiptail --backtitle \"Proxmox VE Helper Scripts\" --defaultno --title \"SSH DETECTED\" --yesno \"It's suggested to use the Proxmox shell instead of SSH, since SSH can create issues while gathering variables. Would you like to proceed with using SSH?\" 10 62; then\n        echo \"you've been warned\"\n      else\n        clear\n        exit\n      fi\n    fi\n  fi\n}\n\nfunction exit-script() {\n  clear\n  echo -e \"⚠  User exited script \\n\"\n  exit\n}\n\nfunction default_settings() {\n  VMID=\"$NEXTID\"\n  FORMAT=\",efitype=4m\"\n  MACHINE=\"\"\n  DISK_CACHE=\"\"\n  HN=\"turnkey-owncloud-vm\"\n  CPU_TYPE=\"\"\n  CORE_COUNT=\"2\"\n  RAM_SIZE=\"2048\"\n  BRG=\"vmbr0\"\n  MAC=\"$GEN_MAC\"\n  VLAN=\"\"\n  MTU=\"\"\n  START_VM=\"no\"\n  echo -e \"${DGN}Using Virtual Machine ID: ${BGN}${VMID}${CL}\"\n  echo -e \"${DGN}Using Machine Type: ${BGN}i440fx${CL}\"\n  echo -e \"${DGN}Using Disk Cache: ${BGN}None${CL}\"\n  echo -e \"${DGN}Using Hostname: ${BGN}${HN}${CL}\"\n  echo -e \"${DGN}Using CPU Model: ${BGN}KVM64${CL}\"\n  echo -e \"${DGN}Allocated Cores: ${BGN}${CORE_COUNT}${CL}\"\n  echo -e \"${DGN}Allocated RAM: ${BGN}${RAM_SIZE}${CL}\"\n  echo -e \"${DGN}Using Bridge: ${BGN}${BRG}${CL}\"\n  echo -e \"${DGN}Using MAC Address: ${BGN}${MAC}${CL}\"\n  echo -e \"${DGN}Using VLAN: ${BGN}Default${CL}\"\n  echo -e \"${DGN}Using Interface MTU Size: ${BGN}Default${CL}\"\n  echo -e \"${DGN}Start VM when completed: ${BGN}no${CL}\"\n  echo -e \"${BL}Creating a TurnKey ownCloud VM using the above default settings${CL}\"\n}\n\nfunction advanced_settings() {\n  while true; do\n    if VMID=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set Virtual Machine ID\" 8 58 $NEXTID --title \"VIRTUAL MACHINE ID\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n      if [ -z \"$VMID\" ]; then\n        VMID=\"$NEXTID\"\n      fi\n      if pct status \"$VMID\" &>/dev/null || qm status \"$VMID\" &>/dev/null; then\n        echo -e \"${CROSS}${RD} ID $VMID is already in use${CL}\"\n        sleep 2\n        continue\n      fi\n      echo -e \"${DGN}Virtual Machine ID: ${BGN}$VMID${CL}\"\n      break\n    else\n      exit-script\n    fi\n  done\n\n  if MACH=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"MACHINE TYPE\" --radiolist --cancel-button Exit-Script \"Choose Type\" 10 58 2 \\\n    \"i440fx\" \"Machine i440fx\" ON \\\n    \"q35\" \"Machine q35\" OFF \\\n    3>&1 1>&2 2>&3); then\n    if [ $MACH = q35 ]; then\n      echo -e \"${DGN}Using Machine Type: ${BGN}$MACH${CL}\"\n      FORMAT=\"\"\n      MACHINE=\" -machine q35\"\n    else\n      echo -e \"${DGN}Using Machine Type: ${BGN}$MACH${CL}\"\n      FORMAT=\",efitype=4m\"\n      MACHINE=\"\"\n    fi\n  else\n    exit-script\n  fi\n\n  if DISK_CACHE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"DISK CACHE\" --radiolist \"Choose\" --cancel-button Exit-Script 10 58 2 \\\n    \"0\" \"None (Default)\" ON \\\n    \"1\" \"Write Through\" OFF \\\n    3>&1 1>&2 2>&3); then\n    if [ $DISK_CACHE = \"1\" ]; then\n      echo -e \"${DGN}Using Disk Cache: ${BGN}Write Through${CL}\"\n      DISK_CACHE=\"cache=writethrough,\"\n    else\n      echo -e \"${DGN}Using Disk Cache: ${BGN}None${CL}\"\n      DISK_CACHE=\"\"\n    fi\n  else\n    exit-script\n  fi\n\n  if VM_NAME=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set Hostname\" 8 58 turnkey-owncloud-vm --title \"HOSTNAME\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $VM_NAME ]; then\n      HN=\"turnkey-owncloud-vm\"\n      echo -e \"${DGN}Using Hostname: ${BGN}$HN${CL}\"\n    else\n      HN=$(echo ${VM_NAME,,} | tr -d ' ')\n      echo -e \"${DGN}Using Hostname: ${BGN}$HN${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  if CPU_TYPE1=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"CPU MODEL\" --radiolist \"Choose\" --cancel-button Exit-Script 10 58 2 \\\n    \"0\" \"KVM64 (Default)\" ON \\\n    \"1\" \"Host\" OFF \\\n    3>&1 1>&2 2>&3); then\n    if [ $CPU_TYPE1 = \"1\" ]; then\n      echo -e \"${DGN}Using CPU Model: ${BGN}Host${CL}\"\n      CPU_TYPE=\" -cpu host\"\n    else\n      echo -e \"${DGN}Using CPU Model: ${BGN}KVM64${CL}\"\n      CPU_TYPE=\"\"\n    fi\n  else\n    exit-script\n  fi\n\n  if CORE_COUNT=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Allocate CPU Cores\" 8 58 2 --title \"CORE COUNT\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $CORE_COUNT ]; then\n      CORE_COUNT=\"2\"\n      echo -e \"${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}\"\n    else\n      echo -e \"${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  if RAM_SIZE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Allocate RAM in MiB\" 8 58 2048 --title \"RAM\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $RAM_SIZE ]; then\n      RAM_SIZE=\"2048\"\n      echo -e \"${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}\"\n    else\n      echo -e \"${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  if BRG=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set a Bridge\" 8 58 vmbr0 --title \"BRIDGE\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $BRG ]; then\n      BRG=\"vmbr0\"\n      echo -e \"${DGN}Using Bridge: ${BGN}$BRG${CL}\"\n    else\n      echo -e \"${DGN}Using Bridge: ${BGN}$BRG${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  if MAC1=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set a MAC Address\" 8 58 $GEN_MAC --title \"MAC ADDRESS\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $MAC1 ]; then\n      MAC=\"$GEN_MAC\"\n      echo -e \"${DGN}Using MAC Address: ${BGN}$MAC${CL}\"\n    else\n      MAC=\"$MAC1\"\n      echo -e \"${DGN}Using MAC Address: ${BGN}$MAC1${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  if VLAN1=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set a Vlan(leave blank for default)\" 8 58 --title \"VLAN\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $VLAN1 ]; then\n      VLAN1=\"Default\"\n      VLAN=\"\"\n      echo -e \"${DGN}Using Vlan: ${BGN}$VLAN1${CL}\"\n    else\n      VLAN=\",tag=$VLAN1\"\n      echo -e \"${DGN}Using Vlan: ${BGN}$VLAN1${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  if MTU1=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set Interface MTU Size (leave blank for default)\" 8 58 --title \"MTU SIZE\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $MTU1 ]; then\n      MTU1=\"Default\"\n      MTU=\"\"\n      echo -e \"${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}\"\n    else\n      MTU=\",mtu=$MTU1\"\n      echo -e \"${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  if (whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"START VIRTUAL MACHINE\" --yesno \"Start VM when completed?\" 10 58); then\n    echo -e \"${DGN}Start VM when completed: ${BGN}yes${CL}\"\n    START_VM=\"yes\"\n  else\n    echo -e \"${DGN}Start VM when completed: ${BGN}no${CL}\"\n    START_VM=\"no\"\n  fi\n\n  if (whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"ADVANCED SETTINGS COMPLETE\" --yesno \"Ready to create a TurnKey ownCloud VM?\" --no-button Do-Over 10 58); then\n    echo -e \"${RD}Creating a TurnKey ownCloud VM using the above advanced settings${CL}\"\n  else\n    header_info\n    echo -e \"${RD}Using Advanced Settings${CL}\"\n    advanced_settings\n  fi\n}\n\nfunction start_script() {\n  if (whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"SETTINGS\" --yesno \"Use Default Settings?\" --no-button Advanced 10 58); then\n    header_info\n    echo -e \"${BL}Using Default Settings${CL}\"\n    default_settings\n  else\n    header_info\n    echo -e \"${RD}Using Advanced Settings${CL}\"\n    advanced_settings\n  fi\n}\n\ncheck_root\narch_check\npve_check\nssh_check\nstart_script\n\nmsg_info \"Validating Storage\"\nwhile read -r line; do\n  TAG=$(echo $line | awk '{print $1}')\n  TYPE=$(echo $line | awk '{printf \"%-10s\", $2}')\n  FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( \"%9sB\", $6)}')\n  ITEM=\"  Type: $TYPE Free: $FREE \"\n  OFFSET=2\n  if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then\n    MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET))\n  fi\n  STORAGE_MENU+=(\"$TAG\" \"$ITEM\" \"OFF\")\ndone < <(pvesm status -content images | awk 'NR>1')\nVALID=$(pvesm status -content images | awk 'NR>1')\nif [ -z \"$VALID\" ]; then\n  msg_error \"Unable to detect a valid storage location.\"\n  exit\nelif [ $((${#STORAGE_MENU[@]} / 3)) -eq 1 ]; then\n  STORAGE=${STORAGE_MENU[0]}\nelse\n  while [ -z \"${STORAGE:+x}\" ]; do\n    STORAGE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"Storage Pools\" --radiolist \\\n      \"Which storage pool you would like to use for ${HN}?\\nTo make a selection, use the Spacebar.\\n\" \\\n      16 $(($MSG_MAX_LENGTH + 23)) 6 \\\n      \"${STORAGE_MENU[@]}\" 3>&1 1>&2 2>&3) || exit\n  done\nfi\nmsg_ok \"Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location.\"\nmsg_ok \"Virtual Machine ID is ${CL}${BL}$VMID${CL}.\"\nmsg_info \"Retrieving the URL for the TurnKey ownCloud ISO Disk Image\"\nURL=http://mirror.turnkeylinux.org/turnkeylinux/images/iso/turnkey-owncloud-18.0-bookworm-amd64.iso\nsleep 2\nmsg_ok \"${CL}${BL}${URL}${CL}\"\nwget -q --show-progress $URL\necho -en \"\\e[1A\\e[0K\"\nFILE=$(basename $URL)\nmsg_ok \"Downloaded ${CL}${BL}${FILE}${CL}\"\n\nSTORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}')\ncase $STORAGE_TYPE in\nnfs | dir)\n  DISK_EXT=\".raw\"\n  DISK_REF=\"$VMID/\"\n  DISK_IMPORT=\"-format raw\"\n  THIN=\"\"\n  ;;\nbtrfs)\n  DISK_EXT=\".raw\"\n  DISK_REF=\"$VMID/\"\n  DISK_IMPORT=\"-format raw\"\n  FORMAT=\",efitype=4m\"\n  THIN=\"\"\n  ;;\nesac\nfor i in {0,1}; do\n  disk=\"DISK$i\"\n  eval DISK${i}=vm-${VMID}-disk-${i}${DISK_EXT:-}\n  eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk}\ndone\n\nmsg_info \"Creating a TurnKey ownCloud VM\"\nqm create $VMID -agent 1${MACHINE} -tablet 0 -localtime 1 -bios seabios${CPU_TYPE} -cores $CORE_COUNT -memory $RAM_SIZE \\\n  -name $HN -tags proxmox-helper-scripts -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU -onboot 1 -ostype l26 -scsihw virtio-scsi-pci\npvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null\nqm importdisk $VMID ${FILE} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null\nqm set $VMID \\\n  -efidisk0 ${DISK0_REF}${FORMAT} \\\n  -scsi0 ${DISK1_REF},${DISK_CACHE}${THIN}size=12G \\\n  -boot order=scsi0 \\\n  -description \"<div align='center'><a href='https://Helper-Scripts.com'><img src='https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/logo-81x112.png'/></a>\n\n  # TurnKey ownCloud VM\n\n  <a href='https://ko-fi.com/D1D7EP4GF'><img src='https://img.shields.io/badge/&#x2615;-Buy me a coffee-blue' /></a>\n  </div>\" >/dev/null\nmsg_ok \"Created a TurnKey ownCloud VM ${CL}${BL}(${HN})\"\nif [ \"$START_VM\" == \"yes\" ]; then\n  msg_info \"Starting TurnKey ownCloud VM\"\n  qm start $VMID\n  msg_ok \"Started TurnKey ownCloud VM\"\nfi\nmsg_ok \"Completed Successfully!\\n\"\n"
  },
  {
    "path": "vm/pimox-haos-vm.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\n  cat <<\"EOF\"\n                                      ____  _ __  ___                                        \n                                    / __ \\(_)  |/  /___  _  __                              \n                                   / /_/ / / /|_/ / __ \\| |/_/                              \n                                  / ____/ / /  / / /_/ />  <                                \n    __  __                       /_/_  /_/_/  /_/\\____/_/|_|              __     ____  _____\n   / / / /___  ____ ___  ___     /   |  __________(_)____/ /_____ _____  / /_   / __ \\/ ___/\n  / /_/ / __ \\/ __ `__ \\/ _ \\   / /| | / ___/ ___/ / ___/ __/ __ `/ __ \\/ __/  / / / /\\__ \\ \n / __  / /_/ / / / / / /  __/  / ___ |(__  |__  ) (__  ) /_/ /_/ / / / / /_   / /_/ /___/ / \n/_/ /_/\\____/_/ /_/ /_/\\___/  /_/  |_/____/____/_/____/\\__/\\__,_/_/ /_/\\__/   \\____//____/  \n                                                                                            \nEOF\n}\nclear\nheader_info\necho -e \"Loading...\"\nGEN_MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]')\nUSEDID=$(pvesh get /cluster/resources --type vm --output-format yaml | egrep -i 'vmid' | awk '{print substr($2, 1, length($2)-0) }')\nNEXTID=$(pvesh get /cluster/nextid)\nSTABLE=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/stable.json | grep \"ova\" | awk '{print substr($2, 2, length($2)-3) }')\nBETA=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/beta.json | grep \"ova\" | awk '{print substr($2, 2, length($2)-3) }')\nDEV=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/dev.json | grep \"ova\" | awk '{print substr($2, 2, length($2)-3) }')\nYW=$(echo \"\\033[33m\")\nBL=$(echo \"\\033[36m\")\nHA=$(echo \"\\033[1;34m\")\nRD=$(echo \"\\033[01;31m\")\nBGN=$(echo \"\\033[4;92m\")\nGN=$(echo \"\\033[1;92m\")\nDGN=$(echo \"\\033[32m\")\nCL=$(echo \"\\033[m\")\nBFR=\"\\\\r\\\\033[K\"\nHOLD=\"-\"\nCM=\"${GN}✓${CL}\"\nCROSS=\"${RD}✗${CL}\"\nset -o errexit\nset -o errtrace\nset -o nounset\nset -o pipefail\nshopt -s expand_aliases\nalias die='EXIT=$? LINE=$LINENO error_exit'\ntrap die ERR\ntrap cleanup EXIT\nfunction error_exit() {\n  trap - ERR\n  local reason=\"Unknown failure occurred.\"\n  local msg=\"${1:-$reason}\"\n  local flag=\"${RD}‼ ERROR ${CL}$EXIT@$LINE\"\n  echo -e \"$flag $msg\" 1>&2\n  [ ! -z ${VMID-} ] && cleanup_vmid\n  exit $EXIT\n}\nfunction cleanup_vmid() {\n  if $(qm status $VMID &>/dev/null); then\n    if [ \"$(qm status $VMID | awk '{print $2}')\" == \"running\" ]; then\n      qm stop $VMID\n    fi\n    qm destroy $VMID\n  fi\n}\nfunction cleanup() {\n  popd >/dev/null\n  rm -rf $TEMP_DIR\n}\nTEMP_DIR=$(mktemp -d)\npushd $TEMP_DIR >/dev/null\nif ! command -v whiptail &> /dev/null; then\n    echo \"Installing whiptail...\"\n    apt-get update &>/dev/null\n    apt-get install -y whiptail &>/dev/null\nfi\nif (whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"PiMox HAOS VM\" --yesno \"This will create a New PiMox HAOS VM. Proceed?\" 10 58); then\n  echo \"User selected Yes\"\nelse\n  clear\n  echo -e \"⚠ User exited script \\n\"\n  exit\nfi\nfunction ARCH_CHECK() {\n  ARCH=$(dpkg --print-architecture)\n  if [[ \"$ARCH\" == \"amd64\" ]]; then\n    echo -e \"\\n ❌  This script only works with PiMox! \\n\"\n    echo -e \"Exiting...\"\n    sleep 2\n    exit\n  fi\n}\nfunction msg_info() {\n  local msg=\"$1\"\n  echo -ne \" ${HOLD} ${YW}${msg}...\"\n}\nfunction msg_ok() {\n  local msg=\"$1\"\n  echo -e \"${BFR} ${CM} ${GN}${msg}${CL}\"\n}\nfunction msg_error() {\n  local msg=\"$1\"\n  echo -e \"${BFR} ${CROSS} ${RD}${msg}${CL}\"\n}\n\nfunction default_settings() {\n  echo -e \"${DGN}Using HAOS Version: ${BGN}${STABLE}${CL}\"\n  BRANCH=${STABLE}\n  echo -e \"${DGN}Using Virtual Machine ID: ${BGN}$NEXTID${CL}\"\n  VMID=$NEXTID\n  echo -e \"${DGN}Using Hostname: ${BGN}haos${STABLE}${CL}\"\n  HN=haos${STABLE}\n  echo -e \"${DGN}Allocated Cores: ${BGN}2${CL}\"\n  CORE_COUNT=\"2\"\n  echo -e \"${DGN}Allocated RAM: ${BGN}4096${CL}\"\n  RAM_SIZE=\"4096\"\n  echo -e \"${DGN}Using Bridge: ${BGN}vmbr0${CL}\"\n  BRG=\"vmbr0\"\n  echo -e \"${DGN}Using MAC Address: ${BGN}$GEN_MAC${CL}\"\n  MAC=$GEN_MAC\n  echo -e \"${DGN}Using VLAN: ${BGN}Default${CL}\"\n  VLAN=\"\"\n  echo -e \"${DGN}Using Interface MTU Size: ${BGN}Default${CL}\"\n  MTU=\"\"\n  echo -e \"${DGN}Start VM when completed: ${BGN}yes${CL}\"\n  START_VM=\"yes\"\n  echo -e \"${BL}Creating a HAOS VM using the above default settings${CL}\"\n}\nfunction advanced_settings() {\n  BRANCH=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"HAOS VERSION\" --radiolist \"Choose Version\" --cancel-button Exit-Script 10 58 3 \\\n    \"$STABLE\" \"Stable\" ON \\\n    \"$BETA\" \"Beta\" OFF \\\n    \"$DEV\" \"Dev\" OFF \\\n    3>&1 1>&2 2>&3)\n  exitstatus=$?\n  if [ $exitstatus = 0 ]; then echo -e \"${DGN}Using HAOS Version: ${BGN}$BRANCH${CL}\"; fi\n  VMID=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set Virtual Machine ID\" 8 58 $NEXTID --title \"VIRTUAL MACHINE ID\" --cancel-button Exit-Script 3>&1 1>&2 2>&3)\n  exitstatus=$?\n  if [ -z $VMID ]; then\n    VMID=\"$NEXTID\"\n    echo -e \"${DGN}Virtual Machine: ${BGN}$VMID${CL}\"\n  else\n    if echo \"$USEDID\" | egrep -q \"$VMID\"; then\n      echo -e \"\\n🚨  ${RD}ID $VMID is already in use${CL} \\n\"\n      echo -e \"Exiting Script \\n\"\n      sleep 2\n      exit\n    else\n      if [ $exitstatus = 0 ]; then echo -e \"${DGN}Virtual Machine ID: ${BGN}$VMID${CL}\"; fi\n    fi\n  fi\n  VM_NAME=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set Hostname\" 8 58 haos${BRANCH} --title \"HOSTNAME\" --cancel-button Exit-Script 3>&1 1>&2 2>&3)\n  exitstatus=$?\n  if [ -z $VM_NAME ]; then\n    HN=\"haos${BRANCH}\"\n    echo -e \"${DGN}Using Hostname: ${BGN}$HN${CL}\"\n  else\n    if [ $exitstatus = 0 ]; then\n      HN=$(echo ${VM_NAME,,} | tr -d ' ')\n      echo -e \"${DGN}Using Hostname: ${BGN}$HN${CL}\"\n    fi\n  fi\n  CORE_COUNT=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Allocate CPU Cores\" 8 58 2 --title \"CORE COUNT\" --cancel-button Exit-Script 3>&1 1>&2 2>&3)\n  exitstatus=$?\n  if [ -z $CORE_COUNT ]; then\n    CORE_COUNT=\"2\"\n    echo -e \"${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}\"\n  else\n    if [ $exitstatus = 0 ]; then echo -e \"${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}\"; fi\n  fi\n  RAM_SIZE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Allocate RAM in MiB\" 8 58 4096 --title \"RAM\" --cancel-button Exit-Script 3>&1 1>&2 2>&3)\n  exitstatus=$?\n  if [ -z $RAM_SIZE ]; then\n    RAM_SIZE=\"4096\"\n    echo -e \"${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}\"\n  else\n    if [ $exitstatus = 0 ]; then echo -e \"${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}\"; fi\n  fi\n  BRG=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set a Bridge\" 8 58 vmbr0 --title \"BRIDGE\" --cancel-button Exit-Script 3>&1 1>&2 2>&3)\n  exitstatus=$?\n  if [ -z $BRG ]; then\n    BRG=\"vmbr0\"\n    echo -e \"${DGN}Using Bridge: ${BGN}$BRG${CL}\"\n  else\n    if [ $exitstatus = 0 ]; then echo -e \"${DGN}Using Bridge: ${BGN}$BRG${CL}\"; fi\n  fi\n  MAC1=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set a MAC Address\" 8 58 $GEN_MAC --title \"MAC ADDRESS\" --cancel-button Exit-Script 3>&1 1>&2 2>&3)\n  exitstatus=$?\n  if [ -z $MAC1 ]; then\n    MAC=\"$GEN_MAC\"\n    echo -e \"${DGN}Using MAC Address: ${BGN}$MAC${CL}\"\n  else\n    if [ $exitstatus = 0 ]; then\n      MAC=\"$MAC1\"\n      echo -e \"${DGN}Using MAC Address: ${BGN}$MAC1${CL}\"\n    fi\n  fi\n  VLAN1=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set a Vlan(leave blank for default)\" 8 58 --title \"VLAN\" --cancel-button Exit-Script 3>&1 1>&2 2>&3)\n  exitstatus=$?\n  if [ $exitstatus = 0 ]; then\n    if [ -z $VLAN1 ]; then\n      VLAN1=\"Default\" VLAN=\"\"\n      echo -e \"${DGN}Using Vlan: ${BGN}$VLAN1${CL}\"\n    else\n      VLAN=\",tag=$VLAN1\"\n      echo -e \"${DGN}Using Vlan: ${BGN}$VLAN1${CL}\"\n    fi\n  fi\n  MTU1=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set Interface MTU Size (leave blank for default)\" 8 58 --title \"MTU SIZE\" --cancel-button Exit-Script 3>&1 1>&2 2>&3)\n  exitstatus=$?\n  if [ $exitstatus = 0 ]; then\n    if [ -z $MTU1 ]; then\n      MTU1=\"Default\" MTU=\"\"\n      echo -e \"${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}\"\n    else\n      MTU=\",mtu=$MTU1\"\n      echo -e \"${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}\"\n    fi\n  fi\n  if (whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"START VIRTUAL MACHINE\" --yesno \"Start VM when completed?\" 10 58); then\n    echo -e \"${DGN}Start VM when completed: ${BGN}yes${CL}\"\n    START_VM=\"yes\"\n  else\n    echo -e \"${DGN}Start VM when completed: ${BGN}no${CL}\"\n    START_VM=\"no\"\n  fi\n  if (whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"ADVANCED SETTINGS COMPLETE\" --yesno \"Ready to create HAOS ${BRANCH} VM?\" --no-button Do-Over 10 58); then\n    echo -e \"${RD}Creating a HAOS VM using the above advanced settings${CL}\"\n  else\n    clear\n    header_info\n    echo -e \"${RD}Using Advanced Settings${CL}\"\n    advanced_settings\n  fi\n}\nfunction START_SCRIPT() {\n  if (whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"SETTINGS\" --yesno \"Use Default Settings?\" --no-button Advanced 10 58); then\n    clear\n    header_info\n    echo -e \"${BL}Using Default Settings${CL}\"\n    default_settings\n  else\n    clear\n    header_info\n    echo -e \"${RD}Using Advanced Settings${CL}\"\n    advanced_settings\n  fi\n}\nARCH_CHECK\nSTART_SCRIPT\nwhile read -r line; do\n  TAG=$(echo $line | awk '{print $1}')\n  TYPE=$(echo $line | awk '{printf \"%-10s\", $2}')\n  FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( \"%9sB\", $6)}')\n  ITEM=\"  Type: $TYPE Free: $FREE \"\n  OFFSET=2\n  if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then\n    MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET))\n  fi\n  STORAGE_MENU+=(\"$TAG\" \"$ITEM\" \"OFF\")\ndone < <(pvesm status -content images | awk 'NR>1')\nif [ $((${#STORAGE_MENU[@]} / 3)) -eq 0 ]; then\n  echo -e \"'Disk image' needs to be selected for at least one storage location.\"\n  die \"Unable to detect valid storage location.\"\nelif [ $((${#STORAGE_MENU[@]} / 3)) -eq 1 ]; then\n  STORAGE=${STORAGE_MENU[0]}\nelse\n  while [ -z \"${STORAGE:+x}\" ]; do\n    STORAGE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"Storage Pools\" --radiolist \\\n      \"Which storage pool you would like to use for the HAOS VM?\\n\\n\" \\\n      16 $(($MSG_MAX_LENGTH + 23)) 6 \\\n      \"${STORAGE_MENU[@]}\" 3>&1 1>&2 2>&3) || exit\n  done\nfi\nmsg_ok \"Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location.\"\nmsg_ok \"Virtual Machine ID is ${CL}${BL}$VMID${CL}.\"\nmsg_info \"Getting URL for Home Assistant ${BRANCH} Disk Image\"\nURL=https://github.com/home-assistant/operating-system/releases/download/${BRANCH}/haos_generic-aarch64-${BRANCH}.qcow2.xz\nsleep 2\nmsg_ok \"${CL}${BL}${URL}${CL}\"\nwget -q --show-progress $URL\necho -en \"\\e[1A\\e[0K\"\nFILE=$(basename $URL)\nmsg_ok \"Downloaded ${CL}${BL}haos_generic-aarch64-${BRANCH}.qcow2.xz${CL}\"\nmsg_info \"Extracting Disk Image\"\nunxz $FILE\nSTORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}')\ncase $STORAGE_TYPE in\nnfs | dir)\n  DISK_EXT=\".qcow2\"\n  DISK_REF=\"$VMID/\"\n  DISK_IMPORT=\"-format qcow2\"\n  ;;\nesac\nfor i in {0,1}; do\n  disk=\"DISK$i\"\n  eval DISK${i}=vm-${VMID}-disk-${i}${DISK_EXT:-}\n  eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk}\ndone\nmsg_ok \"Extracted Disk Image\"\nmsg_info \"Creating HAOS VM\"\nqm create $VMID -bios ovmf -cores $CORE_COUNT -memory $RAM_SIZE -name $HN \\\n  -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU -onboot 1 -ostype l26 -scsihw virtio-scsi-pci\npvesm alloc $STORAGE $VMID $DISK0 64M 1>&/dev/null\nqm importdisk $VMID ${FILE%.*} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null\nqm set $VMID \\\n  -efidisk0 ${DISK0_REF},efitype=4m,size=64M \\\n  -scsi0 ${DISK1_REF},size=32G >/dev/null\nqm set $VMID \\\n  -boot order=scsi0 \\\n  -description \"<div align='center'><a href='https://Helper-Scripts.com'><img src='https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/logo-81x112.png'/></a>\n\n  # Home Assistant OS\n\n  <a href='https://ko-fi.com/D1D7EP4GF'><img src='https://img.shields.io/badge/&#x2615;-Buy me a coffee-blue' /></a>\n  </div>\" >/dev/null\nmsg_ok \"Created HAOS VM ${CL}${BL}(${HN})\"\nif [ \"$START_VM\" == \"yes\" ]; then\n  msg_info \"Starting Home Assistant OS VM\"\n  qm start $VMID\n  msg_ok \"Started Home Assistant OS VM\"\nfi\nmsg_ok \"Completed Successfully!\\n\"\n"
  },
  {
    "path": "vm/ubuntu2204-vm.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\n  clear\n  cat <<\"EOF\"\n   __  ____                __           ___  ___    ____  __ __     _    ____  ___\n  / / / / /_  __  ______  / /___  __   |__ \\|__ \\  / __ \\/ // /    | |  / /  |/  /\n / / / / __ \\/ / / / __ \\/ __/ / / /   __/ /__/ / / / / / // /_    | | / / /|_/ /\n/ /_/ / /_/ / /_/ / / / / /_/ /_/ /   / __// __/_/ /_/ /__  __/    | |/ / /  / /\n\\____/_.___/\\__,_/_/ /_/\\__/\\__,_/   /____/____(_)____/  /_/       |___/_/  /_/\n\nEOF\n}\nheader_info\necho -e \"\\n Loading...\"\nGEN_MAC=02:$(openssl rand -hex 5 | awk '{print toupper($0)}' | sed 's/\\(..\\)/\\1:/g; s/.$//')\nNEXTID=$(pvesh get /cluster/nextid)\n\nYW=$(echo \"\\033[33m\")\nBL=$(echo \"\\033[36m\")\nHA=$(echo \"\\033[1;34m\")\nRD=$(echo \"\\033[01;31m\")\nBGN=$(echo \"\\033[4;92m\")\nGN=$(echo \"\\033[1;92m\")\nDGN=$(echo \"\\033[32m\")\nCL=$(echo \"\\033[m\")\nBFR=\"\\\\r\\\\033[K\"\nHOLD=\"-\"\nCM=\"${GN}✓${CL}\"\nCROSS=\"${RD}✗${CL}\"\nTHIN=\"discard=on,ssd=1,\"\nset -e\ntrap 'error_handler $LINENO \"$BASH_COMMAND\"' ERR\ntrap cleanup EXIT\nfunction error_handler() {\n  local exit_code=\"$?\"\n  local line_number=\"$1\"\n  local command=\"$2\"\n  local error_message=\"${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}\"\n  echo -e \"\\n$error_message\\n\"\n  cleanup_vmid\n}\n\nfunction cleanup_vmid() {\n  if qm status $VMID &>/dev/null; then\n    qm stop $VMID &>/dev/null\n    qm destroy $VMID &>/dev/null\n  fi\n}\n\nfunction cleanup() {\n  popd >/dev/null\n  rm -rf $TEMP_DIR\n}\n\nTEMP_DIR=$(mktemp -d)\npushd $TEMP_DIR >/dev/null\nif whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"Ubuntu 22.04 VM\" --yesno \"This will create a New Ubuntu 22.04 VM. Proceed?\" 10 58; then\n  :\nelse\n  header_info && echo -e \"⚠ User exited script \\n\" && exit\nfi\n\nfunction msg_info() {\n  local msg=\"$1\"\n  echo -ne \" ${HOLD} ${YW}${msg}...\"\n}\n\nfunction msg_ok() {\n  local msg=\"$1\"\n  echo -e \"${BFR} ${CM} ${GN}${msg}${CL}\"\n}\n\nfunction msg_error() {\n  local msg=\"$1\"\n  echo -e \"${BFR} ${CROSS} ${RD}${msg}${CL}\"\n}\n\nfunction check_root() {\n  if [[ \"$(id -u)\" -ne 0 || $(ps -o comm= -p $PPID) == \"sudo\" ]]; then\n    clear\n    msg_error \"Please run this script as root.\"\n    echo -e \"\\nExiting...\"\n    sleep 2\n    exit\n  fi\n}\n\nfunction pve_check() {\n  if ! pveversion | grep -Eq \"pve-manager/8.[1-3]\"; then\n    msg_error \"This version of Proxmox Virtual Environment is not supported\"\n    echo -e \"Requires Proxmox Virtual Environment Version 8.1 or later.\"\n    echo -e \"Exiting...\"\n    sleep 2\n    exit\nfi\n}\n\nfunction arch_check() {\n  if [ \"$(dpkg --print-architecture)\" != \"amd64\" ]; then\n    msg_error \"This script will not work with PiMox! \\n\"\n    echo -e \"Exiting...\"\n    sleep 2\n    exit\n  fi\n}\n\nfunction ssh_check() {\n  if command -v pveversion >/dev/null 2>&1; then\n    if [ -n \"${SSH_CLIENT:+x}\" ]; then\n      if whiptail --backtitle \"Proxmox VE Helper Scripts\" --defaultno --title \"SSH DETECTED\" --yesno \"It's suggested to use the Proxmox shell instead of SSH, since SSH can create issues while gathering variables. Would you like to proceed with using SSH?\" 10 62; then\n        echo \"you've been warned\"\n      else\n        clear\n        exit\n      fi\n    fi\n  fi\n}\n\nfunction exit-script() {\n  clear\n  echo -e \"⚠  User exited script \\n\"\n  exit\n}\n\nfunction default_settings() {\n  VMID=\"$NEXTID\"\n  FORMAT=\",efitype=4m\"\n  MACHINE=\"\"\n  DISK_CACHE=\"\"\n  HN=\"ubuntu\"\n  CPU_TYPE=\"\"\n  CORE_COUNT=\"2\"\n  RAM_SIZE=\"2048\"\n  BRG=\"vmbr0\"\n  MAC=\"$GEN_MAC\"\n  VLAN=\"\"\n  MTU=\"\"\n  START_VM=\"no\"\n  echo -e \"${DGN}Using Virtual Machine ID: ${BGN}${VMID}${CL}\"\n  echo -e \"${DGN}Using Machine Type: ${BGN}i440fx${CL}\"\n  echo -e \"${DGN}Using Disk Cache: ${BGN}None${CL}\"\n  echo -e \"${DGN}Using Hostname: ${BGN}${HN}${CL}\"\n  echo -e \"${DGN}Using CPU Model: ${BGN}KVM64${CL}\"\n  echo -e \"${DGN}Allocated Cores: ${BGN}${CORE_COUNT}${CL}\"\n  echo -e \"${DGN}Allocated RAM: ${BGN}${RAM_SIZE}${CL}\"\n  echo -e \"${DGN}Using Bridge: ${BGN}${BRG}${CL}\"\n  echo -e \"${DGN}Using MAC Address: ${BGN}${MAC}${CL}\"\n  echo -e \"${DGN}Using VLAN: ${BGN}Default${CL}\"\n  echo -e \"${DGN}Using Interface MTU Size: ${BGN}Default${CL}\"\n  echo -e \"${DGN}Start VM when completed: ${BGN}no${CL}\"\n  echo -e \"${BL}Creating an Ubuntu 22.04 VM using the above default settings${CL}\"\n}\n\nfunction advanced_settings() {\n  while true; do\n    if VMID=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set Virtual Machine ID\" 8 58 $NEXTID --title \"VIRTUAL MACHINE ID\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n      if [ -z \"$VMID\" ]; then\n        VMID=\"$NEXTID\"\n      fi\n      if pct status \"$VMID\" &>/dev/null || qm status \"$VMID\" &>/dev/null; then\n        echo -e \"${CROSS}${RD} ID $VMID is already in use${CL}\"\n        sleep 2\n        continue\n      fi\n      echo -e \"${DGN}Virtual Machine ID: ${BGN}$VMID${CL}\"\n      break\n    else\n      exit-script\n    fi\n  done\n\n  if MACH=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"MACHINE TYPE\" --radiolist --cancel-button Exit-Script \"Choose Type\" 10 58 2 \\\n    \"i440fx\" \"Machine i440fx\" ON \\\n    \"q35\" \"Machine q35\" OFF \\\n    3>&1 1>&2 2>&3); then\n    if [ $MACH = q35 ]; then\n      echo -e \"${DGN}Using Machine Type: ${BGN}$MACH${CL}\"\n      FORMAT=\"\"\n      MACHINE=\" -machine q35\"\n    else\n      echo -e \"${DGN}Using Machine Type: ${BGN}$MACH${CL}\"\n      FORMAT=\",efitype=4m\"\n      MACHINE=\"\"\n    fi\n  else\n    exit-script\n  fi\n\n  if DISK_CACHE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"DISK CACHE\" --radiolist \"Choose\" --cancel-button Exit-Script 10 58 2 \\\n    \"0\" \"None (Default)\" ON \\\n    \"1\" \"Write Through\" OFF \\\n    3>&1 1>&2 2>&3); then\n    if [ $DISK_CACHE = \"1\" ]; then\n      echo -e \"${DGN}Using Disk Cache: ${BGN}Write Through${CL}\"\n      DISK_CACHE=\"cache=writethrough,\"\n    else\n      echo -e \"${DGN}Using Disk Cache: ${BGN}None${CL}\"\n      DISK_CACHE=\"\"\n    fi\n  else\n    exit-script\n  fi\n\n  if VM_NAME=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set Hostname\" 8 58 ubuntu --title \"HOSTNAME\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $VM_NAME ]; then\n      HN=\"ubuntu\"\n      echo -e \"${DGN}Using Hostname: ${BGN}$HN${CL}\"\n    else\n      HN=$(echo ${VM_NAME,,} | tr -d ' ')\n      echo -e \"${DGN}Using Hostname: ${BGN}$HN${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  if CPU_TYPE1=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"CPU MODEL\" --radiolist \"Choose\" --cancel-button Exit-Script 10 58 2 \\\n    \"0\" \"KVM64 (Default)\" ON \\\n    \"1\" \"Host\" OFF \\\n    3>&1 1>&2 2>&3); then\n    if [ $CPU_TYPE1 = \"1\" ]; then\n      echo -e \"${DGN}Using CPU Model: ${BGN}Host${CL}\"\n      CPU_TYPE=\" -cpu host\"\n    else\n      echo -e \"${DGN}Using CPU Model: ${BGN}KVM64${CL}\"\n      CPU_TYPE=\"\"\n    fi\n  else\n    exit-script\n  fi\n\n  if CORE_COUNT=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Allocate CPU Cores\" 8 58 2 --title \"CORE COUNT\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $CORE_COUNT ]; then\n      CORE_COUNT=\"2\"\n      echo -e \"${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}\"\n    else\n      echo -e \"${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  if RAM_SIZE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Allocate RAM in MiB\" 8 58 2048 --title \"RAM\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $RAM_SIZE ]; then\n      RAM_SIZE=\"2048\"\n      echo -e \"${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}\"\n    else\n      echo -e \"${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  if BRG=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set a Bridge\" 8 58 vmbr0 --title \"BRIDGE\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $BRG ]; then\n      BRG=\"vmbr0\"\n      echo -e \"${DGN}Using Bridge: ${BGN}$BRG${CL}\"\n    else\n      echo -e \"${DGN}Using Bridge: ${BGN}$BRG${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  if MAC1=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set a MAC Address\" 8 58 $GEN_MAC --title \"MAC ADDRESS\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $MAC1 ]; then\n      MAC=\"$GEN_MAC\"\n      echo -e \"${DGN}Using MAC Address: ${BGN}$MAC${CL}\"\n    else\n      MAC=\"$MAC1\"\n      echo -e \"${DGN}Using MAC Address: ${BGN}$MAC1${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  if VLAN1=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set a Vlan(leave blank for default)\" 8 58 --title \"VLAN\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $VLAN1 ]; then\n      VLAN1=\"Default\"\n      VLAN=\"\"\n      echo -e \"${DGN}Using Vlan: ${BGN}$VLAN1${CL}\"\n    else\n      VLAN=\",tag=$VLAN1\"\n      echo -e \"${DGN}Using Vlan: ${BGN}$VLAN1${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  if MTU1=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set Interface MTU Size (leave blank for default)\" 8 58 --title \"MTU SIZE\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $MTU1 ]; then\n      MTU1=\"Default\"\n      MTU=\"\"\n      echo -e \"${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}\"\n    else\n      MTU=\",mtu=$MTU1\"\n      echo -e \"${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  if (whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"START VIRTUAL MACHINE\" --yesno \"Start VM when completed?\" 10 58); then\n    echo -e \"${DGN}Start VM when completed: ${BGN}yes${CL}\"\n    START_VM=\"yes\"\n  else\n    echo -e \"${DGN}Start VM when completed: ${BGN}no${CL}\"\n    START_VM=\"no\"\n  fi\n\n  if (whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"ADVANCED SETTINGS COMPLETE\" --yesno \"Ready to create an Ubuntu 22.04 VM?\" --no-button Do-Over 10 58); then\n    echo -e \"${RD}Creating an Ubuntu 22.04 VM using the above advanced settings${CL}\"\n  else\n    header_info\n    echo -e \"${RD}Using Advanced Settings${CL}\"\n    advanced_settings\n  fi\n}\n\nfunction start_script() {\n  if (whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"SETTINGS\" --yesno \"Use Default Settings?\" --no-button Advanced 10 58); then\n    header_info\n    echo -e \"${BL}Using Default Settings${CL}\"\n    default_settings\n  else\n    header_info\n    echo -e \"${RD}Using Advanced Settings${CL}\"\n    advanced_settings\n  fi\n}\n\ncheck_root\narch_check\npve_check\nssh_check\nstart_script\n\nmsg_info \"Validating Storage\"\nwhile read -r line; do\n  TAG=$(echo $line | awk '{print $1}')\n  TYPE=$(echo $line | awk '{printf \"%-10s\", $2}')\n  FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( \"%9sB\", $6)}')\n  ITEM=\"  Type: $TYPE Free: $FREE \"\n  OFFSET=2\n  if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then\n    MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET))\n  fi\n  STORAGE_MENU+=(\"$TAG\" \"$ITEM\" \"OFF\")\ndone < <(pvesm status -content images | awk 'NR>1')\nVALID=$(pvesm status -content images | awk 'NR>1')\nif [ -z \"$VALID\" ]; then\n  msg_error \"Unable to detect a valid storage location.\"\n  exit\nelif [ $((${#STORAGE_MENU[@]} / 3)) -eq 1 ]; then\n  STORAGE=${STORAGE_MENU[0]}\nelse\n  while [ -z \"${STORAGE:+x}\" ]; do\n    STORAGE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"Storage Pools\" --radiolist \\\n      \"Which storage pool you would like to use for ${HN}?\\nTo make a selection, use the Spacebar.\\n\" \\\n      16 $(($MSG_MAX_LENGTH + 23)) 6 \\\n      \"${STORAGE_MENU[@]}\" 3>&1 1>&2 2>&3) || exit\n  done\nfi\nmsg_ok \"Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location.\"\nmsg_ok \"Virtual Machine ID is ${CL}${BL}$VMID${CL}.\"\nmsg_info \"Retrieving the URL for the Ubuntu 22.04 Disk Image\"\nURL=https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img\nsleep 2\nmsg_ok \"${CL}${BL}${URL}${CL}\"\nwget -q --show-progress $URL\necho -en \"\\e[1A\\e[0K\"\nFILE=$(basename $URL)\nmsg_ok \"Downloaded ${CL}${BL}${FILE}${CL}\"\n\nSTORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}')\ncase $STORAGE_TYPE in\nnfs | dir)\n  DISK_EXT=\".qcow2\"\n  DISK_REF=\"$VMID/\"\n  DISK_IMPORT=\"-format qcow2\"\n  THIN=\"\"\n  ;;\nbtrfs)\n  DISK_EXT=\".raw\"\n  DISK_REF=\"$VMID/\"\n  DISK_IMPORT=\"-format raw\"\n  FORMAT=\",efitype=4m\"\n  THIN=\"\"\n  ;;\nesac\nfor i in {0,1}; do\n  disk=\"DISK$i\"\n  eval DISK${i}=vm-${VMID}-disk-${i}${DISK_EXT:-}\n  eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk}\ndone\n\nmsg_info \"Creating a Ubuntu 22.04 VM\"\nqm create $VMID -agent 1${MACHINE} -tablet 0 -localtime 1 -bios ovmf${CPU_TYPE} -cores $CORE_COUNT -memory $RAM_SIZE \\\n  -name $HN -tags proxmox-helper-scripts -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU -onboot 1 -ostype l26 -scsihw virtio-scsi-pci\npvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null\nqm importdisk $VMID ${FILE} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null\nqm set $VMID \\\n  -efidisk0 ${DISK0_REF}${FORMAT} \\\n  -scsi0 ${DISK1_REF},${DISK_CACHE}${THIN}size=2G \\\n  -ide2 ${STORAGE}:cloudinit \\\n  -boot order=scsi0 \\\n  -serial0 socket \\\n  -description \"<div align='center'><a href='https://Helper-Scripts.com'><img src='https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/logo-81x112.png'/></a>\n\n  # Ubuntu 22.04 VM\n\n  <a href='https://ko-fi.com/D1D7EP4GF'><img src='https://img.shields.io/badge/&#x2615;-Buy me a coffee-blue' /></a>\n  </div>\" >/dev/null\nmsg_ok \"Created a Ubuntu 22.04 VM ${CL}${BL}(${HN})\"\nif [ \"$START_VM\" == \"yes\" ]; then\n  msg_info \"Starting Ubuntu 22.04 VM\"\n  qm start $VMID\n  msg_ok \"Started Ubuntu 22.04 VM\"\nfi\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"Setup Cloud-Init before starting \\n\nMore info at https://github.com/tteck/Proxmox/discussions/2072 \\n\"\n"
  },
  {
    "path": "vm/ubuntu2404-vm.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (c) 2021-2024 tteck\n# Author: tteck (tteckster)\n# License: MIT\n# https://github.com/tteck/Proxmox/raw/main/LICENSE\n\nfunction header_info {\n  clear\n  cat <<\"EOF\"\n   __  ____                __           ___  __ __   ____  __ __     _    ____  ___\n  / / / / /_  __  ______  / /___  __   |__ \\/ // /  / __ \\/ // /    | |  / /  |/  /\n / / / / __ \\/ / / / __ \\/ __/ / / /   __/ / // /_ / / / / // /_    | | / / /|_/ /\n/ /_/ / /_/ / /_/ / / / / /_/ /_/ /   / __/__  __// /_/ /__  __/    | |/ / /  / /\n\\____/_.___/\\__,_/_/ /_/\\__/\\__,_/   /____/ /_/ (_)____/  /_/       |___/_/  /_/\n\nEOF\n}\nheader_info\necho -e \"\\n Loading...\"\nGEN_MAC=02:$(openssl rand -hex 5 | awk '{print toupper($0)}' | sed 's/\\(..\\)/\\1:/g; s/.$//')\nNEXTID=$(pvesh get /cluster/nextid)\n\nYW=$(echo \"\\033[33m\")\nBL=$(echo \"\\033[36m\")\nHA=$(echo \"\\033[1;34m\")\nRD=$(echo \"\\033[01;31m\")\nBGN=$(echo \"\\033[4;92m\")\nGN=$(echo \"\\033[1;92m\")\nDGN=$(echo \"\\033[32m\")\nCL=$(echo \"\\033[m\")\nBFR=\"\\\\r\\\\033[K\"\nHOLD=\"-\"\nCM=\"${GN}✓${CL}\"\nCROSS=\"${RD}✗${CL}\"\nTHIN=\"discard=on,ssd=1,\"\nset -e\ntrap 'error_handler $LINENO \"$BASH_COMMAND\"' ERR\ntrap cleanup EXIT\nfunction error_handler() {\n  local exit_code=\"$?\"\n  local line_number=\"$1\"\n  local command=\"$2\"\n  local error_message=\"${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}\"\n  echo -e \"\\n$error_message\\n\"\n  cleanup_vmid\n}\n\nfunction cleanup_vmid() {\n  if qm status $VMID &>/dev/null; then\n    qm stop $VMID &>/dev/null\n    qm destroy $VMID &>/dev/null\n  fi\n}\n\nfunction cleanup() {\n  popd >/dev/null\n  rm -rf $TEMP_DIR\n}\n\nTEMP_DIR=$(mktemp -d)\npushd $TEMP_DIR >/dev/null\nif whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"Ubuntu 24.04 VM\" --yesno \"This will create a New Ubuntu 24.04 VM. Proceed?\" 10 58; then\n  :\nelse\n  header_info && echo -e \"⚠ User exited script \\n\" && exit\nfi\n\nfunction msg_info() {\n  local msg=\"$1\"\n  echo -ne \" ${HOLD} ${YW}${msg}...\"\n}\n\nfunction msg_ok() {\n  local msg=\"$1\"\n  echo -e \"${BFR} ${CM} ${GN}${msg}${CL}\"\n}\n\nfunction msg_error() {\n  local msg=\"$1\"\n  echo -e \"${BFR} ${CROSS} ${RD}${msg}${CL}\"\n}\n\nfunction check_root() {\n  if [[ \"$(id -u)\" -ne 0 || $(ps -o comm= -p $PPID) == \"sudo\" ]]; then\n    clear\n    msg_error \"Please run this script as root.\"\n    echo -e \"\\nExiting...\"\n    sleep 2\n    exit\n  fi\n}\n\nfunction pve_check() {\n  if ! pveversion | grep -Eq \"pve-manager/8.[1-3]\"; then\n    msg_error \"This version of Proxmox Virtual Environment is not supported\"\n    echo -e \"Requires Proxmox Virtual Environment Version 8.1 or later.\"\n    echo -e \"Exiting...\"\n    sleep 2\n    exit\nfi\n}\n\nfunction arch_check() {\n  if [ \"$(dpkg --print-architecture)\" != \"amd64\" ]; then\n    msg_error \"This script will not work with PiMox! \\n\"\n    echo -e \"Exiting...\"\n    sleep 2\n    exit\n  fi\n}\n\nfunction ssh_check() {\n  if command -v pveversion >/dev/null 2>&1; then\n    if [ -n \"${SSH_CLIENT:+x}\" ]; then\n      if whiptail --backtitle \"Proxmox VE Helper Scripts\" --defaultno --title \"SSH DETECTED\" --yesno \"It's suggested to use the Proxmox shell instead of SSH, since SSH can create issues while gathering variables. Would you like to proceed with using SSH?\" 10 62; then\n        echo \"you've been warned\"\n      else\n        clear\n        exit\n      fi\n    fi\n  fi\n}\n\nfunction exit-script() {\n  clear\n  echo -e \"⚠  User exited script \\n\"\n  exit\n}\n\nfunction default_settings() {\n  VMID=\"$NEXTID\"\n  FORMAT=\",efitype=4m\"\n  MACHINE=\"\"\n  DISK_CACHE=\"\"\n  HN=\"ubuntu\"\n  CPU_TYPE=\"\"\n  CORE_COUNT=\"2\"\n  RAM_SIZE=\"2048\"\n  BRG=\"vmbr0\"\n  MAC=\"$GEN_MAC\"\n  VLAN=\"\"\n  MTU=\"\"\n  echo -e \"${DGN}Using Virtual Machine ID: ${BGN}${VMID}${CL}\"\n  echo -e \"${DGN}Using Machine Type: ${BGN}i440fx${CL}\"\n  echo -e \"${DGN}Using Disk Cache: ${BGN}None${CL}\"\n  echo -e \"${DGN}Using Hostname: ${BGN}${HN}${CL}\"\n  echo -e \"${DGN}Using CPU Model: ${BGN}KVM64${CL}\"\n  echo -e \"${DGN}Allocated Cores: ${BGN}${CORE_COUNT}${CL}\"\n  echo -e \"${DGN}Allocated RAM: ${BGN}${RAM_SIZE}${CL}\"\n  echo -e \"${DGN}Using Bridge: ${BGN}${BRG}${CL}\"\n  echo -e \"${DGN}Using MAC Address: ${BGN}${MAC}${CL}\"\n  echo -e \"${DGN}Using VLAN: ${BGN}Default${CL}\"\n  echo -e \"${DGN}Using Interface MTU Size: ${BGN}Default${CL}\"\n  echo -e \"${BL}Creating an Ubuntu 24.04 VM using the above default settings${CL}\"\n}\n\nfunction advanced_settings() {\n  while true; do\n    if VMID=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set Virtual Machine ID\" 8 58 $NEXTID --title \"VIRTUAL MACHINE ID\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n      if [ -z \"$VMID\" ]; then\n        VMID=\"$NEXTID\"\n      fi\n      if pct status \"$VMID\" &>/dev/null || qm status \"$VMID\" &>/dev/null; then\n        echo -e \"${CROSS}${RD} ID $VMID is already in use${CL}\"\n        sleep 2\n        continue\n      fi\n      echo -e \"${DGN}Virtual Machine ID: ${BGN}$VMID${CL}\"\n      break\n    else\n      exit-script\n    fi\n  done\n\n  if MACH=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"MACHINE TYPE\" --radiolist --cancel-button Exit-Script \"Choose Type\" 10 58 2 \\\n    \"i440fx\" \"Machine i440fx\" ON \\\n    \"q35\" \"Machine q35\" OFF \\\n    3>&1 1>&2 2>&3); then\n    if [ $MACH = q35 ]; then\n      echo -e \"${DGN}Using Machine Type: ${BGN}$MACH${CL}\"\n      FORMAT=\"\"\n      MACHINE=\" -machine q35\"\n    else\n      echo -e \"${DGN}Using Machine Type: ${BGN}$MACH${CL}\"\n      FORMAT=\",efitype=4m\"\n      MACHINE=\"\"\n    fi\n  else\n    exit-script\n  fi\n\n  if DISK_CACHE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"DISK CACHE\" --radiolist \"Choose\" --cancel-button Exit-Script 10 58 2 \\\n    \"0\" \"None (Default)\" ON \\\n    \"1\" \"Write Through\" OFF \\\n    3>&1 1>&2 2>&3); then\n    if [ $DISK_CACHE = \"1\" ]; then\n      echo -e \"${DGN}Using Disk Cache: ${BGN}Write Through${CL}\"\n      DISK_CACHE=\"cache=writethrough,\"\n    else\n      echo -e \"${DGN}Using Disk Cache: ${BGN}None${CL}\"\n      DISK_CACHE=\"\"\n    fi\n  else\n    exit-script\n  fi\n\n  if VM_NAME=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set Hostname\" 8 58 ubuntu --title \"HOSTNAME\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $VM_NAME ]; then\n      HN=\"ubuntu\"\n      echo -e \"${DGN}Using Hostname: ${BGN}$HN${CL}\"\n    else\n      HN=$(echo ${VM_NAME,,} | tr -d ' ')\n      echo -e \"${DGN}Using Hostname: ${BGN}$HN${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  if CPU_TYPE1=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"CPU MODEL\" --radiolist \"Choose\" --cancel-button Exit-Script 10 58 2 \\\n    \"0\" \"KVM64 (Default)\" ON \\\n    \"1\" \"Host\" OFF \\\n    3>&1 1>&2 2>&3); then\n    if [ $CPU_TYPE1 = \"1\" ]; then\n      echo -e \"${DGN}Using CPU Model: ${BGN}Host${CL}\"\n      CPU_TYPE=\" -cpu host\"\n    else\n      echo -e \"${DGN}Using CPU Model: ${BGN}KVM64${CL}\"\n      CPU_TYPE=\"\"\n    fi\n  else\n    exit-script\n  fi\n\n  if CORE_COUNT=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Allocate CPU Cores\" 8 58 2 --title \"CORE COUNT\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $CORE_COUNT ]; then\n      CORE_COUNT=\"2\"\n      echo -e \"${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}\"\n    else\n      echo -e \"${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  if RAM_SIZE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Allocate RAM in MiB\" 8 58 2048 --title \"RAM\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $RAM_SIZE ]; then\n      RAM_SIZE=\"2048\"\n      echo -e \"${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}\"\n    else\n      echo -e \"${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  if BRG=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set a Bridge\" 8 58 vmbr0 --title \"BRIDGE\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $BRG ]; then\n      BRG=\"vmbr0\"\n      echo -e \"${DGN}Using Bridge: ${BGN}$BRG${CL}\"\n    else\n      echo -e \"${DGN}Using Bridge: ${BGN}$BRG${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  if MAC1=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set a MAC Address\" 8 58 $GEN_MAC --title \"MAC ADDRESS\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $MAC1 ]; then\n      MAC=\"$GEN_MAC\"\n      echo -e \"${DGN}Using MAC Address: ${BGN}$MAC${CL}\"\n    else\n      MAC=\"$MAC1\"\n      echo -e \"${DGN}Using MAC Address: ${BGN}$MAC1${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  if VLAN1=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set a Vlan(leave blank for default)\" 8 58 --title \"VLAN\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $VLAN1 ]; then\n      VLAN1=\"Default\"\n      VLAN=\"\"\n      echo -e \"${DGN}Using Vlan: ${BGN}$VLAN1${CL}\"\n    else\n      VLAN=\",tag=$VLAN1\"\n      echo -e \"${DGN}Using Vlan: ${BGN}$VLAN1${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  if MTU1=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --inputbox \"Set Interface MTU Size (leave blank for default)\" 8 58 --title \"MTU SIZE\" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then\n    if [ -z $MTU1 ]; then\n      MTU1=\"Default\"\n      MTU=\"\"\n      echo -e \"${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}\"\n    else\n      MTU=\",mtu=$MTU1\"\n      echo -e \"${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}\"\n    fi\n  else\n    exit-script\n  fi\n\n  if (whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"ADVANCED SETTINGS COMPLETE\" --yesno \"Ready to create an Ubuntu 24.04 VM?\" --no-button Do-Over 10 58); then\n    echo -e \"${RD}Creating an Ubuntu 24.04 VM using the above advanced settings${CL}\"\n  else\n    header_info\n    echo -e \"${RD}Using Advanced Settings${CL}\"\n    advanced_settings\n  fi\n}\n\nfunction start_script() {\n  if (whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"SETTINGS\" --yesno \"Use Default Settings?\" --no-button Advanced 10 58); then\n    header_info\n    echo -e \"${BL}Using Default Settings${CL}\"\n    default_settings\n  else\n    header_info\n    echo -e \"${RD}Using Advanced Settings${CL}\"\n    advanced_settings\n  fi\n}\n\ncheck_root\narch_check\npve_check\nssh_check\nstart_script\n\nmsg_info \"Validating Storage\"\nwhile read -r line; do\n  TAG=$(echo $line | awk '{print $1}')\n  TYPE=$(echo $line | awk '{printf \"%-10s\", $2}')\n  FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( \"%9sB\", $6)}')\n  ITEM=\"  Type: $TYPE Free: $FREE \"\n  OFFSET=2\n  if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then\n    MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET))\n  fi\n  STORAGE_MENU+=(\"$TAG\" \"$ITEM\" \"OFF\")\ndone < <(pvesm status -content images | awk 'NR>1')\nVALID=$(pvesm status -content images | awk 'NR>1')\nif [ -z \"$VALID\" ]; then\n  msg_error \"Unable to detect a valid storage location.\"\n  exit\nelif [ $((${#STORAGE_MENU[@]} / 3)) -eq 1 ]; then\n  STORAGE=${STORAGE_MENU[0]}\nelse\n  while [ -z \"${STORAGE:+x}\" ]; do\n    STORAGE=$(whiptail --backtitle \"Proxmox VE Helper Scripts\" --title \"Storage Pools\" --radiolist \\\n      \"Which storage pool you would like to use for ${HN}?\\nTo make a selection, use the Spacebar.\\n\" \\\n      16 $(($MSG_MAX_LENGTH + 23)) 6 \\\n      \"${STORAGE_MENU[@]}\" 3>&1 1>&2 2>&3) || exit\n  done\nfi\nmsg_ok \"Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location.\"\nmsg_ok \"Virtual Machine ID is ${CL}${BL}$VMID${CL}.\"\nmsg_info \"Retrieving the URL for the Ubuntu 24.04 Disk Image\"\nURL=https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img\nsleep 2\nmsg_ok \"${CL}${BL}${URL}${CL}\"\nwget -q --show-progress $URL\necho -en \"\\e[1A\\e[0K\"\nFILE=$(basename $URL)\nmsg_ok \"Downloaded ${CL}${BL}${FILE}${CL}\"\n\nSTORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}')\ncase $STORAGE_TYPE in\nnfs | dir)\n  DISK_EXT=\".qcow2\"\n  DISK_REF=\"$VMID/\"\n  DISK_IMPORT=\"-format qcow2\"\n  THIN=\"\"\n  ;;\nbtrfs)\n  DISK_EXT=\".raw\"\n  DISK_REF=\"$VMID/\"\n  DISK_IMPORT=\"-format raw\"\n  FORMAT=\",efitype=4m\"\n  THIN=\"\"\n  ;;\nesac\nfor i in {0,1}; do\n  disk=\"DISK$i\"\n  eval DISK${i}=vm-${VMID}-disk-${i}${DISK_EXT:-}\n  eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk}\ndone\n\nmsg_info \"Creating a Ubuntu 24.04 VM\"\nqm create $VMID -agent 1${MACHINE} -tablet 0 -localtime 1 -bios ovmf${CPU_TYPE} -cores $CORE_COUNT -memory $RAM_SIZE \\\n  -name $HN -tags proxmox-helper-scripts -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU -onboot 1 -ostype l26 -scsihw virtio-scsi-pci\npvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null\nqm importdisk $VMID ${FILE} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null\nqm set $VMID \\\n  -efidisk0 ${DISK0_REF}${FORMAT} \\\n  -scsi0 ${DISK1_REF},${DISK_CACHE}${THIN}size=2G \\\n  -ide2 ${STORAGE}:cloudinit \\\n  -boot order=scsi0 \\\n  -serial0 socket \\\n  -description \"<div align='center'><a href='https://Helper-Scripts.com'><img src='https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/logo-81x112.png'/></a>\n\n  # Ubuntu 24.04 VM\n\n  <a href='https://ko-fi.com/D1D7EP4GF'><img src='https://img.shields.io/badge/&#x2615;-Buy me a coffee-blue' /></a>\n  </div>\" >/dev/null\nmsg_ok \"Created a Ubuntu 24.04 VM ${CL}${BL}(${HN})\"\nmsg_ok \"Completed Successfully!\\n\"\necho -e \"Setup Cloud-Init before starting \\n\nMore info at https://github.com/tteck/Proxmox/discussions/2072 \\n\"\n"
  }
]