diff --git a/.github/check-script.yml b/.github/check-script.yml deleted file mode 100644 index 560bc396..00000000 --- a/.github/check-script.yml +++ /dev/null @@ -1,54 +0,0 @@ -name: Check Shell Scripts - -on: - pull_request: - paths: - - '**/*.sh' # Führt den Check nur für Shell-Skripte aus - -jobs: - check-scripts: - runs-on: ubuntu-latest - - steps: - - name: Checkout Code - uses: actions/checkout@v3 - - - name: Check `source` Line in Scripts - shell: bash - run: | - set -e - ERROR_COUNT=0 - FILES=$(find . -name "*.sh") - - for FILE in $FILES; do - # Check for exact match of the source line in line 2 - if [[ $(sed -n '2p' "$FILE") =~ ^source[[:space:]]+<(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func) ]]; then - echo "Check passed for: $FILE" - else - echo "Error in $FILE: Line 2 must be exactly 'source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)' if a source line is used." - ERROR_COUNT=$((ERROR_COUNT + 1)) - fi - - # Check for shebang line at the top - if [[ $(head -n 1 "$FILE") != "#!/usr/bin/env bash" ]]; then - echo "Error in $FILE: The first line must be '#!/usr/bin/env bash'." - ERROR_COUNT=$((ERROR_COUNT + 1)) - fi - - # Check for executable permissions - if [[ ! -x "$FILE" ]]; then - echo "Warning in $FILE: This script is not executable. Consider running 'chmod +x $FILE'." - fi - - # Check for empty lines at the beginning of the script - if [[ $(head -n 10 "$FILE" | grep -c '^$') -gt 0 ]]; then - echo "Warning in $FILE: There are empty lines at the beginning of the script. Consider removing them." - fi - done - - if [[ "$ERROR_COUNT" -gt 0 ]]; then - echo "$ERROR_COUNT script(s) failed validation." - exit 1 - else - echo "All scripts passed." - fi diff --git a/.github/workflows/check-lowercase.yml b/.github/workflows/check-lowercase.yml deleted file mode 100644 index b570204b..00000000 --- a/.github/workflows/check-lowercase.yml +++ /dev/null @@ -1,92 +0,0 @@ -name: Check Lowercase Filenames - -on: - pull_request: - paths: - - 'ct/*.sh' - - 'install/*.sh' - - 'json/*.json' - -jobs: - check_lowercase: - runs-on: ubuntu-latest - - steps: - # Step 1: Checkout the code - - name: Checkout code - uses: actions/checkout@v4 - with: - fetch-depth: 0 # Ensure the full history is fetched for accurate diffing - - # Step 2: Fetch the base branch - - name: Fetch base branch - run: git fetch origin ${{ github.base_ref }} - - # Step 3a: Validate filenames in ct directory - - name: "Validate filenames in ct directory" - run: | - changed_files=$(git diff --name-only origin/${{ github.base_ref }}...HEAD | grep -E '^ct/.*\.sh$') - - ERROR_COUNT=0 - - for FILE in $changed_files; do - BASENAME=$(basename "$FILE") - if [[ "$BASENAME" =~ ^[a-z0-9._-]+$ ]]; then - echo "$FILE: Check for lowercase in filename passed." - else - echo "Error in $FILE. Change filename to lowercase." - ERROR_COUNT=$((ERROR_COUNT + 1)) - fi - done - - if [ "$ERROR_COUNT" -ne 0 ]; then - exit 1 - else - echo "All filenames in ct directory passed the lowercase check." - fi - - # Step 3b: Validate filenames in install directory - - name: "Validate filenames in install directory" - run: | - changed_files=$(git diff --name-only origin/${{ github.base_ref }}...HEAD | grep -E '^install/.*\.sh$') - - ERROR_COUNT=0 - - for FILE in $changed_files; do - BASENAME=$(basename "$FILE") - if [[ "$BASENAME" =~ ^[a-z0-9._-]+$ ]]; then - echo "$FILE: Check for lowercase in filename passed." - else - echo "Error in $FILE. Change filename to lowercase." - ERROR_COUNT=$((ERROR_COUNT + 1)) - fi - done - - if [ "$ERROR_COUNT" -ne 0 ]; then - exit 1 - else - echo "All filenames in install directory passed the lowercase check." - fi - - # Step 3c: Validate filenames in json directory - - name: "Validate filenames in json directory." - run: | - changed_files=$(git diff --name-only origin/${{ github.base_ref }}...HEAD | grep -E '^json/.*\.json$') - - ERROR_COUNT=0 - - for FILE in $changed_files; do - BASENAME=$(basename "$FILE") - if [[ "$BASENAME" =~ ^[a-z0-9._-]+$ ]]; then - echo "$FILE: Check for lowercase in filename passed." - else - echo "Error in $FILE. Change filename to lowercase." - ERROR_COUNT=$((ERROR_COUNT + 1)) - fi - done - - if [ "$ERROR_COUNT" -ne 0 ]; then - exit 1 - else - echo "All filenames in json directory passed the lowercase check." - fi diff --git a/.github/workflows/check-metadata.yml b/.github/workflows/check-metadata.yml deleted file mode 100644 index 67159feb..00000000 --- a/.github/workflows/check-metadata.yml +++ /dev/null @@ -1,55 +0,0 @@ -name: Check Metadata -on: - pull_request: - paths: - - '/ct/*.sh' - - '/install/*.sh' -jobs: - check-metadata: - runs-on: ubuntu-latest - steps: - - name: Checkout Code - uses: actions/checkout@v4 - - name: Check Metadata Lines in Scripts - shell: bash - run: | - set -e - ERROR_COUNT=0 - FILES=$(find . -name "*.sh") - - for FILE in $FILES; do - if [[ "$(sed -n '3p' "$FILE")" == "# Copyright (c) 2021-2024 community-scripts ORG" ]]; then - echo "Check for Copyright metadata passed for line 3 in: $FILE" - else - echo "Error in $FILE: Copyright metadata missing or not on line 3" - ERROR_COUNT=$((ERROR_COUNT + 1)) - fi - - if sed -n '4p' "$FILE" | grep -qE "^# Author: .+"; then - echo "Check for Author metadata passed for line 4 in: $FILE" - else - echo "Error in $FILE: Author metadata missing or invalid on line 4" - ERROR_COUNT=$((ERROR_COUNT + 1)) - fi - - if [[ "$(sed -n '5p' "$FILE")" == "# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE" ]]; then - echo "Check for License metadata passed for line 5 in: $FILE" - else - echo "Error in $FILE: License metadata missing or not on line 5" - ERROR_COUNT=$((ERROR_COUNT + 1)) - fi - - if sed -n '6p' "$FILE" | grep -qE "^# Source: .+"; then - echo "Check for Source metadata passed for line 6 in: $FILE" - else - echo "Error in $FILE: Source metadata missing or invalid on line 6" - ERROR_COUNT=$((ERROR_COUNT + 1)) - fi - done - - if [[ "$ERROR_COUNT" -gt 0 ]]; then - echo "$ERROR_COUNT script(s) failed validation." - exit 1 - else - echo "All scripts passed." - fi diff --git a/.github/workflows/validate-filenames.yml b/.github/workflows/validate-filenames.yml new file mode 100644 index 00000000..704715f5 --- /dev/null +++ b/.github/workflows/validate-filenames.yml @@ -0,0 +1,143 @@ +name: Validate filenames + +on: + pull_request: + paths: + - "ct/*.sh" + - "install/*.sh" + - "json/*.json" + - ".github/workflows/validate-filenames.yml" + +jobs: + check-files: + name: Check changed files + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 # Ensure the full history is fetched for accurate diffing + + - name: Get changed files + id: changed-files + run: | + if ${{ github.event_name == 'pull_request' }}; then + echo "files=$(git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.sha }} | xargs)" >> $GITHUB_OUTPUT + else + echo "files=$(git diff --name-only ${{ github.event.before }} ${{ github.event.after }} | xargs)" >> $GITHUB_OUTPUT + fi + + - name: "Validate filenames in ct and install directory" + if: always() && steps.changed-files.outputs.files != '' + id: check-scripts + run: | + CHANGED_FILES=$(printf "%s\n" ${{ steps.changed-files.outputs.files }} | { grep -E '^(ct|install)/.*\.sh$' || true; }) + + NON_COMPLIANT_FILES="" + for FILE in $CHANGED_FILES; do + BASENAME=$(echo "$(basename "${FILE%.*}")") + if [[ ! "$BASENAME" =~ ^[a-z0-9-]+$ ]]; then + NON_COMPLIANT_FILES="$NON_COMPLIANT_FILES $FILE" + fi + done + + if [ -n "$NON_COMPLIANT_FILES" ]; then + echo "files=$NON_COMPLIANT_FILES" >> $GITHUB_OUTPUT + echo "Non-compliant filenames found, change to lowercase:" + for FILE in $NON_COMPLIANT_FILES; do + echo "$FILE" + done + exit 1 + fi + + - name: "Validate filenames in json directory." + if: always() && steps.changed-files.outputs.files != '' + id: check-json + run: | + CHANGED_FILES=$(printf "%s\n" ${{ steps.changed-files.outputs.files }} | { grep -E '^json/.*\.json$' || true; }) + + NON_COMPLIANT_FILES="" + for FILE in $CHANGED_FILES; do + BASENAME=$(echo "$(basename "${FILE%.*}")") + if [[ ! "$BASENAME" =~ ^[a-z0-9-]+$ ]]; then + NON_COMPLIANT_FILES="$NON_COMPLIANT_FILES $FILE" + fi + done + + if [ -n "$NON_COMPLIANT_FILES" ]; then + echo "files=$NON_COMPLIANT_FILES" >> $GITHUB_OUTPUT + echo "Non-compliant filenames found, change to lowercase:" + for FILE in $NON_COMPLIANT_FILES; do + echo "$FILE" + done + exit 1 + fi + + - name: Post results and comment + if: always() && steps.check-scripts.outputs.files != '' && steps.check-json.outputs.files != '' && github.event_name == 'pull_request' + uses: actions/github-script@v7 + with: + script: | + const result = "${{ job.status }}" === "success" ? "success" : "failure"; + const nonCompliantFiles = { + script: "${{ steps.check-scripts.outputs.files }}", + JSON: "${{ steps.check-json.outputs.files }}", + }; + + const issueNumber = context.payload.pull_request + ? context.payload.pull_request.number + : null; + const commentIdentifier = "validate-filenames"; + let newCommentBody = `\n### Filename validation\n\n`; + + if (result === "failure") { + newCommentBody += ":x: We found issues in the following changed files:\n\n"; + for (const [check, files] of Object.entries(nonCompliantFiles)) { + if (files) { + newCommentBody += `**${check.charAt(0).toUpperCase() + check.slice(1)} filename invalid:**\n${files + .trim() + .split(" ") + .map((file) => `- ${file}`) + .join("\n")}\n\n`; + } + } + newCommentBody += + "Please change the filenames to lowercase and use only alphanumeric characters and dashes.\n"; + } else { + newCommentBody += `:rocket: All files passed filename validation!\n`; + } + + newCommentBody += `\n\n`; + + if (issueNumber) { + const { data: comments } = await github.rest.issues.listComments({ + ...context.repo, + issue_number: issueNumber, + }); + + const existingComment = comments.find( + (comment) => comment.user.login === "github-actions[bot]", + ); + + if (existingComment) { + if (existingComment.body.includes(commentIdentifier)) { + const re = new RegExp(String.raw`[\s\S]*?`, ""); + newCommentBody = existingComment.body.replace(re, newCommentBody); + } else { + newCommentBody = existingComment.body + '\n\n---\n\n' + newCommentBody; + } + + await github.rest.issues.updateComment({ + ...context.repo, + comment_id: existingComment.id, + body: newCommentBody, + }); + } else { + await github.rest.issues.createComment({ + ...context.repo, + issue_number: issueNumber, + body: newCommentBody, + }); + } + } diff --git a/.github/workflows/validate-scripts.yml b/.github/workflows/validate-scripts.yml new file mode 100644 index 00000000..10d6182d --- /dev/null +++ b/.github/workflows/validate-scripts.yml @@ -0,0 +1,214 @@ +name: Validate scripts +on: + push: + branches: + - main + pull_request: + paths: + - "ct/*.sh" + - "install/*.sh" + - ".github/workflows/validate-scripts.yml" + +jobs: + check-scripts: + name: Check changed files + runs-on: ubuntu-latest + permissions: + pull-requests: write + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: ${{ github.event_name == 'pull_request' && 2 || 0 }} + + - name: Get changed files + id: changed-files + run: | + if ${{ github.event_name == 'pull_request' }}; then + echo "files=$(git diff --name-only -r HEAD^1 HEAD | grep -E '\.(sh|func)$' | xargs)" >> $GITHUB_OUTPUT + else + echo "files=$(git diff --name-only ${{ github.event.before }} ${{ github.event.after }} | grep -E '\.(sh|func)$' | xargs)" >> $GITHUB_OUTPUT + fi + + - name: Check build.func line + if: always() && steps.changed-files.outputs.files != '' + id: build-func + run: | + NON_COMPLIANT_FILES="" + for FILE in ${{ steps.changed-files.outputs.files }}; do + if [[ "$FILE" == ct/* ]] && [[ $(sed -n '2p' "$FILE") != "source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)" ]]; then + NON_COMPLIANT_FILES="$NON_COMPLIANT_FILES $FILE" + fi + done + + if [ -n "$NON_COMPLIANT_FILES" ]; then + echo "files=$NON_COMPLIANT_FILES" >> $GITHUB_OUTPUT + echo "Build.func line missing or incorrect in files:" + for FILE in $NON_COMPLIANT_FILES; do + echo "$FILE" + done + exit 1 + fi + + - name: Check executable permissions + if: always() && steps.changed-files.outputs.files != '' + id: check-executable + run: | + NON_COMPLIANT_FILES="" + for FILE in ${{ steps.changed-files.outputs.files }}; do + if [[ ! -x "$FILE" ]]; then + NON_COMPLIANT_FILES="$NON_COMPLIANT_FILES $FILE" + fi + done + + if [ -n "$NON_COMPLIANT_FILES" ]; then + echo "files=$NON_COMPLIANT_FILES" >> $GITHUB_OUTPUT + echo "Files not executable:" + for FILE in $NON_COMPLIANT_FILES; do + echo "$FILE" + done + exit 1 + fi + + - name: Check copyright + if: always() && steps.changed-files.outputs.files != '' + id: check-copyright + run: | + NON_COMPLIANT_FILES="" + for FILE in ${{ steps.changed-files.outputs.files }}; do + if ! sed -n '3p' "$FILE" | grep -qE "^# Copyright \(c\) [0-9]{4}(-[0-9]{4})? (tteck \| community-scripts ORG|community-scripts ORG|tteck)$"; then + NON_COMPLIANT_FILES="$NON_COMPLIANT_FILES $FILE" + fi + done + + if [ -n "$NON_COMPLIANT_FILES" ]; then + echo "files=$NON_COMPLIANT_FILES" >> $GITHUB_OUTPUT + echo "Copyright header missing or not on line 3 in files:" + for FILE in $NON_COMPLIANT_FILES; do + echo "$FILE" + done + exit 1 + fi + + - name: Check author + if: always() && steps.changed-files.outputs.files != '' + id: check-author + run: | + NON_COMPLIANT_FILES="" + for FILE in ${{ steps.changed-files.outputs.files }}; do + if ! sed -n '4p' "$FILE" | grep -qE "^# Author: .+"; then + NON_COMPLIANT_FILES="$NON_COMPLIANT_FILES $FILE" + fi + done + + if [ -n "$NON_COMPLIANT_FILES" ]; then + echo "files=$NON_COMPLIANT_FILES" >> $GITHUB_OUTPUT + echo "Author header missing or invalid on line 4 in files:" + for FILE in $NON_COMPLIANT_FILES; do + echo "$FILE" + done + exit 1 + fi + + - name: Check license + if: always() && steps.changed-files.outputs.files != '' + id: check-license + run: | + NON_COMPLIANT_FILES="" + for FILE in ${{ steps.changed-files.outputs.files }}; do + if [[ "$(sed -n '5p' "$FILE")" != "# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE" ]]; then + NON_COMPLIANT_FILES="$NON_COMPLIANT_FILES $FILE" + fi + done + + if [ -n "$NON_COMPLIANT_FILES" ]; then + echo "files=$NON_COMPLIANT_FILES" >> $GITHUB_OUTPUT + echo "License header missing or not on line 5 in files:" + for FILE in $NON_COMPLIANT_FILES; do + echo "$FILE" + done + exit 1 + fi + + - name: Check source + if: always() && steps.changed-files.outputs.files != '' + id: check-source + run: | + NON_COMPLIANT_FILES="" + for FILE in ${{ steps.changed-files.outputs.files }}; do + if ! sed -n '6p' "$FILE" | grep -qE "^# Source: .+"; then + NON_COMPLIANT_FILES="$NON_COMPLIANT_FILES $FILE" + fi + done + + if [ -n "$NON_COMPLIANT_FILES" ]; then + echo "files=$NON_COMPLIANT_FILES" >> $GITHUB_OUTPUT + echo "Source header missing or not on line 6 in files:" + for FILE in $NON_COMPLIANT_FILES; do + echo "$FILE" + done + exit 1 + fi + + - name: Post results and comment + if: always() && steps.changed-files.outputs.files != '' && github.event_name == 'pull_request' + uses: actions/github-script@v7 + with: + script: | + const result = '${{ job.status }}' === 'success' ? 'success' : 'failure'; + const nonCompliantFiles = { + 'Invalid build.func source': "${{ steps.build-func.outputs.files }}", + 'Not executable': "${{ steps.check-executable.outputs.files }}", + 'Copyright header line missing or invalid': "${{ steps.check-copyright.outputs.files }}", + 'Author header line missing or invalid': "${{ steps.check-author.outputs.files }}", + 'License header line missing or invalid': "${{ steps.check-license.outputs.files }}", + 'Source header line missing or invalid': "${{ steps.check-source.outputs.files }}" + }; + + const issueNumber = context.payload.pull_request ? context.payload.pull_request.number : null; + const commentIdentifier = 'validate-scripts'; + let newCommentBody = `\n### Script validation\n\n`; + + if (result === 'failure') { + newCommentBody += ':x: We found issues in the following changed files:\n\n'; + for (const [check, files] of Object.entries(nonCompliantFiles)) { + if (files) { + newCommentBody += `**${check}:**\n${files.trim().split(' ').map(file => `- ${file}`).join('\n')}\n\n`; + } + } + } else { + newCommentBody += `:rocket: All changed shell scripts passed validation!\n`; + } + + newCommentBody += `\n\n`; + + if (issueNumber) { + const { data: comments } = await github.rest.issues.listComments({ + ...context.repo, + issue_number: issueNumber + }); + + const existingComment = comments.find(comment => comment.user.login === 'github-actions[bot]'); + + if (existingComment) { + if (existingComment.body.includes(commentIdentifier)) { + const re = new RegExp(String.raw`[\s\S]*?`, ""); + newCommentBody = existingComment.body.replace(re, newCommentBody); + } else { + newCommentBody = existingComment.body + '\n\n---\n\n' + newCommentBody; + } + + await github.rest.issues.updateComment({ + ...context.repo, + comment_id: existingComment.id, + body: newCommentBody + }); + } else { + await github.rest.issues.createComment({ + ...context.repo, + issue_number: issueNumber, + body: newCommentBody + }); + } + } diff --git a/CHANGELOG.md b/CHANGELOG.md index 8010f6db..9c98aef0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,18 @@ All LXC instances created using this repository come pre-installed with Midnight > [!IMPORTANT] Do not break established syntax in this file, as it is automatically updated by a Github Workflow +## 2025-01-05 + +### Changed + +### 💥 Breaking Changes + +- [Breaking] Update Zigbee2mqtt to v.2.0.0 (Read PR Description) [@MickLesk](https://github.com/MickLesk) ([#1221](https://github.com/community-scripts/ProxmoxVE/pull/1221)) + +### ❔ Unlabelled + +- Add RAM and Disk units [@oOStroudyOo](https://github.com/oOStroudyOo) ([#1261](https://github.com/community-scripts/ProxmoxVE/pull/1261)) + ## 2025-01-04 ### Changed diff --git a/ct/5etools.sh b/ct/5etools.sh index faa18f9e..3385cbc6 100644 --- a/ct/5etools.sh +++ b/ct/5etools.sh @@ -58,14 +58,12 @@ function update_script() { $STD npm run build cd ~ echo "${RELEASE}" >"/opt/${APP}_version.txt" - msg_ok "Updated base 5etools" - chown -R www-data: "/opt/${APP}" chmod -R 755 "/opt/${APP}" - + msg_ok "Updated base 5etools" # Cleaning up msg_info "Cleaning Up" - rm "${RELEASE}.zip" + rm -rf /opt/${RELEASE}.zip $STD apt-get -y autoremove $STD apt-get -y autoclean msg_ok "Cleanup Completed" @@ -88,11 +86,11 @@ function update_script() { rm -rf "/opt/${APP}/img" mv "${APP}-img-${IMG_RELEASE:1}" "/opt/${APP}/img" echo "${IMG_RELEASE}" >"/opt/${APP}_IMG_version.txt" - msg_ok "Updating 5etools images" - chown -R www-data: "/opt/${APP}" chmod -R 755 "/opt/${APP}" + msg_ok "Updating 5etools images" + # Cleaning up msg_info "Cleaning Up" rm -rf /opt/${RELEASE}.zip diff --git a/ct/zigbee2mqtt.sh b/ct/zigbee2mqtt.sh index b916e5c4..50f0eced 100644 --- a/ct/zigbee2mqtt.sh +++ b/ct/zigbee2mqtt.sh @@ -33,91 +33,35 @@ function update_script() { msg_error "No ${APP} Installation Found!" exit fi - if [[ "$(node -v | cut -d 'v' -f 2)" == "18."* ]]; then - if ! command -v npm >/dev/null 2>&1; then - echo "Installing NPM..." - apt-get install -y npm >/dev/null 2>&1 - echo "Installed NPM..." - fi + RELEASE=$(curl -s https://api.github.com/repos/Koenkk/zigbee2mqtt/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') + if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then + msg_info "Stopping Service" + systemctl stop zigbee2mqtt + msg_ok "Stopped Service" + + msg_info "Creating Backup" + mkdir -p /opt/z2m_backup + tar -czf /opt/z2m_backup/${APP}_backup_$(date +%Y%m%d%H%M%S).tar.gz -C /opt zigbee2mqtt &>/dev/null + mv /opt/zigbee2mqtt/data /opt/z2m_backup + msg_ok "Backup Created" + + msg_info "Updating ${APP} to v${RELEASE}" + cd /opt + wget -q "https://github.com/Koenkk/zigbee2mqtt/archive/refs/tags/${RELEASE}.zip" + unzip -q ${RELEASE}.zip + mv zigbee2mqtt-${RELEASE} /opt/zigbee2mqtt + rm -rf /opt/zigbee2mqtt/data + mv /opt/z2m_backup/data /opt/zigbee2mqtt + cd /opt/zigbee2mqtt + pnpm install --frozen-lockfile &>/dev/null + pnpm build &>/dev/null + msg_info "Starting Service" + systemctl start zigbee2mqtt + msg_ok "Started Service" + echo "${RELEASE}" >/opt/${APP}_version.txt + else + msg_ok "No update required. ${APP} is already at v${RELEASE}." fi - cd /opt/zigbee2mqtt - - stop_zigbee2mqtt() { - if which systemctl 2>/dev/null >/dev/null; then - echo "Shutting down Zigbee2MQTT..." - sudo systemctl stop zigbee2mqtt - else - echo "Skipped stopping Zigbee2MQTT, no systemctl found" - fi - } - - start_zigbee2mqtt() { - if which systemctl 2>/dev/null >/dev/null; then - echo "Starting Zigbee2MQTT..." - sudo systemctl start zigbee2mqtt - else - echo "Skipped starting Zigbee2MQTT, no systemctl found" - fi - } - - set -e - - if [ -d data-backup ]; then - echo "ERROR: Backup directory exists. May be previous restoring was failed?" - echo "1. Save 'data-backup' and 'data' dirs to safe location to make possibility to restore config later." - echo "2. Manually delete 'data-backup' dir and try again." - exit 1 - fi - - stop_zigbee2mqtt - - echo "Generating a backup of the configuration..." - cp -R data data-backup || { - echo "Failed to create backup." - exit 1 - } - - echo "Checking if any changes were made to package-lock.json..." - git checkout package-lock.json || { - echo "Failed to check package-lock.json." - exit 1 - } - - echo "Initiating update..." - if ! git pull; then - echo "Update failed, temporarily storing changes and trying again." - git stash && git pull || ( - echo "Update failed even after storing changes. Aborting." - exit 1 - ) - fi - - echo "Acquiring necessary components..." - npm ci || { - echo "Failed to install necessary components." - exit 1 - } - - echo "Building..." - npm run build || { - echo "Failed to build new version." - exit 1 - } - - echo "Restoring configuration..." - cp -R data-backup/* data || { - echo "Failed to restore configuration." - exit 1 - } - - rm -rf data-backup || { - echo "Failed to remove backup directory." - exit 1 - } - - start_zigbee2mqtt - - echo "Done!" exit } @@ -128,4 +72,4 @@ description msg_ok "Completed Successfully!\n" echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" echo -e "${INFO}${YW} Access it using the following URL:${CL}" -echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:9442${CL}" \ No newline at end of file +echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:9442${CL}" diff --git a/install/5etools-install.sh b/install/5etools-install.sh index c1a3cd94..1e2da9c7 100644 --- a/install/5etools-install.sh +++ b/install/5etools-install.sh @@ -38,6 +38,7 @@ msg_ok "Installed Node.js" # Setup App msg_info "Set up 5etools Base" +cd /opt RELEASE=$(curl -s https://api.github.com/repos/5etools-mirror-3/5etools-src/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') wget -q "https://github.com/5etools-mirror-3/5etools-src/archive/refs/tags/${RELEASE}.zip" unzip -q "${RELEASE}.zip" @@ -45,18 +46,16 @@ mv "5etools-src-${RELEASE:1}" /opt/5etools cd /opt/5etools $STD npm install $STD npm run build -cd ~ echo "${RELEASE}" >"/opt/5etools_version.txt" -rm "${RELEASE}.zip" msg_ok "Set up 5etools Base" msg_info "Set up 5etools Image" +cd /opt IMG_RELEASE=$(curl -s https://api.github.com/repos/5etools-mirror-2/5etools-img/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') curl -sSL "https://github.com/5etools-mirror-2/5etools-img/archive/refs/tags/${IMG_RELEASE}.zip" > "${IMG_RELEASE}.zip" unzip -q "${IMG_RELEASE}.zip" mv "5etools-img-${IMG_RELEASE:1}" /opt/5etools/img echo "${IMG_RELEASE}" >"/opt/5etools_IMG_version.txt" -rm "${IMG_RELEASE}.zip" msg_ok "Set up 5etools Image" msg_info "Creating Service" @@ -74,6 +73,8 @@ chmod -R 755 "/opt/5etools" msg_ok "Created Service" msg_info "Cleaning up" +rm -rf /opt/${IMG_RELEASE}.zip +rm -rf /opt/${RELEASE}.zip $STD apt-get -y autoremove $STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/install/zigbee2mqtt-install.sh b/install/zigbee2mqtt-install.sh index 516fc3b0..faf08b57 100644 --- a/install/zigbee2mqtt-install.sh +++ b/install/zigbee2mqtt-install.sh @@ -14,21 +14,22 @@ network_check update_os msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -$STD apt-get install -y git -$STD apt-get install -y make -$STD apt-get install -y g++ -$STD apt-get install -y gcc -$STD apt-get install -y ca-certificates -$STD apt-get install -y gnupg +$STD apt-get install -y \ + curl \ + sudo \ + mc \ + git \ + make \ + g++ \ + gcc \ + ca-certificates \ + gnupg msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" mkdir -p /etc/apt/keyrings curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg -echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" >/etc/apt/sources.list.d/nodesource.list +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_22.x nodistro main" >/etc/apt/sources.list.d/nodesource.list msg_ok "Set up Node.js Repository" msg_info "Installing Node.js" @@ -36,37 +37,47 @@ $STD apt-get update $STD apt-get install -y nodejs msg_ok "Installed Node.js" -msg_info "Setting up Zigbee2MQTT Repository" -$STD git clone --depth 1 https://github.com/Koenkk/zigbee2mqtt.git /opt/zigbee2mqtt -msg_ok "Set up Zigbee2MQTT Repository" +msg_info "Installing pnpm" +$STD npm install -g pnpm +msg_ok "Installed pnpm" -msg_info "Installing Zigbee2MQTT" +msg_info "Setting up Zigbee2MQTT" +cd /opt +RELEASE=$(curl -s https://api.github.com/repos/Koenkk/zigbee2mqtt/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +wget -q "https://github.com/Koenkk/zigbee2mqtt/archive/refs/tags/${RELEASE}.zip" +unzip -q ${RELEASE}.zip +mv zigbee2mqtt-${RELEASE} /opt/zigbee2mqtt +cd /opt/zigbee2mqtt/data +mv configuration.example.yaml configuration.yaml cd /opt/zigbee2mqtt -$STD npm ci +$STD pnpm install --frozen-lockfile +$STD pnpm build msg_ok "Installed Zigbee2MQTT" msg_info "Creating Service" -service_path="/etc/systemd/system/zigbee2mqtt.service" -echo "[Unit] +cat </etc/systemd/system/zigbee2mqtt.service +[Unit] Description=zigbee2mqtt After=network.target [Service] Environment=NODE_ENV=production -ExecStart=/usr/bin/npm start +ExecStart=/usr/bin/pnpm start WorkingDirectory=/opt/zigbee2mqtt StandardOutput=inherit StandardError=inherit Restart=always User=root [Install] -WantedBy=multi-user.target" >$service_path -$STD systemctl enable zigbee2mqtt.service +WantedBy=multi-user.target +EOF +systemctl enable -q --now zigbee2mqtt.service msg_ok "Created Service" motd_ssh customize msg_info "Cleaning up" +rm -rf /opt/${RELEASE}.zip $STD apt-get -y autoremove $STD apt-get -y autoclean msg_ok "Cleaned" diff --git a/misc/build.func b/misc/build.func index e2e1b076..e8c50f4e 100644 --- a/misc/build.func +++ b/misc/build.func @@ -316,7 +316,7 @@ echo_default() { echo -e "${CONTAINERTYPE}${BOLD}${DGN}Container Type: ${BGN}$CT_TYPE_DESC${CL}" echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE}GB${CL}" echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}${CORE_COUNT}${CL}" - echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE}MB${CL}" + echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE}MiB${CL}" echo -e "${CONTAINERID}${BOLD}${DGN}Container ID: ${BGN}${CT_ID}${CL}" if [ "$VERB" == "yes" ]; then echo -e "${SEARCH}${BOLD}${DGN}Verbose Mode: ${BGN}Enabled${CL}" @@ -463,13 +463,13 @@ advanced_settings() { 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 if [ -z "$DISK_SIZE" ]; then DISK_SIZE="$var_disk" - echo -e "${DISKSIZE}${DGN}Disk Size: ${BGN}$DISK_SIZE${CL}" + echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE}GB${CL}" else if ! [[ $DISK_SIZE =~ $INTEGER ]]; then echo -e "{INFO}${HOLD}${RD} DISK SIZE MUST BE AN INTEGER NUMBER!${CL}" advanced_settings fi - echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}$DISK_SIZE${CL}" + echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE}GB${CL}" fi else exit_script @@ -489,9 +489,9 @@ advanced_settings() { 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 if [ -z "$RAM_SIZE" ]; then RAM_SIZE="$var_ram" - echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}$RAM_SIZE${CL}" + echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE}MiB${CL}" else - echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}$RAM_SIZE${CL}" + echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE}MiB${CL}" fi else exit_script @@ -820,6 +820,7 @@ build_container() { $PW " # This executes create_lxc.sh and creates the container and .conf file + bash -c "$(curl -sL ${CSCRIPTS_BASE_URL}/ct/create_lxc.sh)" || exit LXC_CONFIG=/etc/pve/lxc/${CTID}.conf